分类或回归数据集中存在异常值可能导致模型拟合不佳和预测建模性能下降。
鉴于输入变量数量众多,对于大多数机器学习数据集,使用简单的统计方法来识别和删除异常值具有挑战性。相反,可以在建模管道中使用自动异常值检测方法并进行比较,就像可以应用于数据集的其他数据准备转换一样。
在本教程中,您将学习如何使用自动异常值检测和删除来提高机器学习预测建模性能。
完成本教程后,您将了解:
- 自动异常值检测模型为具有大量输入变量且关系复杂且未知的情况提供了统计技术的替代方案。
- 如何仅将自动异常值检测和删除正确应用于训练数据集以避免数据泄露。
- 如何评估和比较从训练数据集中删除异常值的预测建模管道。
通过我的新书《机器学习数据准备》启动您的项目,其中包括分步教程和所有示例的Python 源代码文件。
让我们开始吧。

Python 中的基于模型的异常值检测和删除
图片作者:Zoltán Vörös,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 异常值检测与删除
- 数据集和性能基线
- 房价回归数据集
- 基线模型性能
- 自动异常值检测
- 孤立森林
- 最小协方差行列式
- 局部异常因子
- 单类支持向量机
异常值检测与删除
异常值是数据集中以某种方式不符合的数据点。
也许最常见或最熟悉的异常值类型是那些远离其他数据点或数据点质量中心的观察值。
当我们有一个或两个变量并且我们可以将数据可视化为直方图或散点图时,这很容易理解,但当我们有许多输入变量定义高维输入特征空间时,这变得非常具有挑战性。
在这种情况下,用于识别异常值的简单统计方法可能会失效,例如使用标准差或四分位距的方法。
在训练机器学习算法进行预测建模时,识别和删除数据中的异常值可能很重要。
异常值可能会扭曲统计测量值和数据分布,从而提供对底层数据和关系的误导性表示。在建模之前从训练数据中删除异常值可以使数据更好地拟合,进而产生更准确的预测。
值得庆幸的是,有各种基于模型的自动方法可以识别输入数据中的异常值。重要的是,每种方法对异常值的定义略有不同,提供了准备训练数据集的替代方法,可以像建模管道中的任何其他数据准备步骤一样进行评估和比较。
在我们深入研究自动异常值检测方法之前,我们首先选择一个标准的机器学习数据集,作为我们研究的基础。
想开始学习数据准备吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
数据集和性能基线
在本节中,我们将首先选择一个标准的机器学习数据集,并在此数据集上建立一个性能基线。
这将为下一节探索异常值识别和删除的数据准备方法提供背景。
房价回归数据集
我们将使用房价回归数据集。
该数据集有 13 个输入变量,描述了房屋和郊区的属性,需要预测郊区房屋的中位价值(以千美元计)。
你可以在此处了解更多关于此数据集的信息:
无需下载数据集,因为我们将在实际示例中自动下载。
打开数据集并查看原始数据。以下列出了数据的前几行。
我们可以看到这是一个回归预测建模问题,具有数值输入变量,每个变量都有不同的比例。
1 2 3 4 5 6 |
0.00632,18.00,2.310,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98,24.00 0.02731,0.00,7.070,0,0.4690,6.4210,78.90,4.9671,2,242.0,17.80,396.90,9.14,21.60 0.02729,0.00,7.070,0,0.4690,7.1850,61.10,4.9671,2,242.0,17.80,392.83,4.03,34.70 0.03237,0.00,2.180,0,0.4580,6.9980,45.80,6.0622,3,222.0,18.70,394.63,2.94,33.40 0.06905,0.00,2.180,0,0.4580,7.1470,54.20,6.0622,3,222.0,18.70,396.90,5.33,36.20 ... |
该数据集有许多数值输入变量,它们之间存在未知且复杂的关系。我们不知道该数据集中是否存在异常值,尽管我们可能会猜测可能存在一些异常值。
下面的示例加载数据集并将其拆分为输入和输出列,然后将其拆分为训练和测试数据集,然后总结数据数组的形状。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 加载并汇总数据集 from pandas import read_csv from sklearn.model_selection import train_test_split # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 总结数据集的形状 print(X.shape, y.shape) # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 总结训练集和测试集的形状 print(X_train.shape, X_test.shape, y_train.shape, y_test.shape) |
运行示例,我们可以看到数据集已正确加载,并且有 506 行数据,包含 13 个输入变量和一个目标变量。
数据集被分成训练集和测试集,其中 339 行用于模型训练,167 行用于模型评估。
1 2 |
(506, 13) (506,) (339, 13) (167, 13) (339,) (167,) |
接下来,让我们评估此数据集上的模型并建立性能基线。
基线模型性能
这是一个回归预测建模问题,这意味着我们将预测一个数值。所有输入变量也都是数值型的。
在这种情况下,我们将拟合一个线性回归算法,并通过在测试数据集上训练模型并对测试数据进行预测,然后使用平均绝对误差 (MAE) 评估预测来评估模型性能。
下面列出了评估数据集上线性回归模型的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 评估原始数据集上的模型 from pandas import read_csv from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.metrics import mean_absolute_error # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 拟合模型 模型 = LinearRegression() model.fit(X_train, y_train) # 评估模型 yhat = model.predict(X_test) # 评估预测 mae = mean_absolute_error(y_test, yhat) print('MAE: %.3f' % mae) |
运行示例会拟合和评估模型,然后报告 MAE。
注意:考虑到算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到模型实现了大约 3.417 的 MAE。这提供了一个性能基线,我们可以将不同的异常值识别和删除过程与此进行比较。
1 |
MAE: 3.417 |
接下来,我们可以尝试从训练数据集中删除异常值。
自动异常值检测
scikit-learn 库提供了许多用于识别数据中异常值的内置自动方法。
在本节中,我们将回顾四种方法并比较它们在房价数据集上的性能。
每种方法都将被定义,然后在训练数据集上拟合。然后,拟合模型将预测训练数据集中哪些示例是异常值,哪些不是(即所谓正常值)。然后,异常值将从训练数据集中删除,然后模型将在剩余示例上拟合,并在整个测试数据集上进行评估。
在整个训练数据集上拟合异常值检测方法是无效的,因为这会导致数据泄露。也就是说,模型将能够访问测试集中未用于训练模型的数据(或有关数据的信息)。这可能会导致模型性能的乐观估计。
我们可以尝试在预测之前检测“新数据”中的异常值,例如测试集,但如果检测到异常值,我们该怎么办?
一种方法可能是返回“None”,表示模型无法对这些异常值情况进行预测。这可能是一个有趣的扩展,可以探索并可能适合您的项目。
孤立森林
孤立森林(简称 iForest)是一种基于树的异常检测算法。
它基于以一种隔离数量少且特征空间不同的异常值的方式对正常数据进行建模。
……我们提出的方法利用了两个异常值的定量特性:i)它们是少数,由较少的实例组成;ii)它们的属性值与正常实例的属性值非常不同。
—— 孤立森林,2008 年。
scikit-learn 库通过 IsolationForest 类提供孤立森林的实现。
也许模型中最重要的超参数是“contamination”参数,它用于帮助估计数据集中的异常值数量。该值介于 0.0 和 0.5 之间,默认设置为 0.1。
1 2 3 4 |
... # 识别训练数据集中的异常值 iso = IsolationForest(contamination=0.1) yhat = iso.fit_predict(X_train) |
一旦识别出异常值,我们就可以从训练数据集中删除它们。
1 2 3 4 |
... # 选择所有非异常值的行 mask = yhat != -1 X_train, y_train = X_train[mask, :], y_train[mask] |
综合来看,下面列出了使用孤立森林识别和删除异常值后,在房屋数据集上评估线性模型的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# 使用孤立森林删除异常值后评估模型性能 from pandas import read_csv from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.ensemble import IsolationForest from sklearn.metrics import mean_absolute_error # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 总结训练数据集的形状 print(X_train.shape, y_train.shape) # 识别训练数据集中的异常值 iso = IsolationForest(contamination=0.1) yhat = iso.fit_predict(X_train) # 选择所有非异常值的行 mask = yhat != -1 X_train, y_train = X_train[mask, :], y_train[mask] # 总结更新后的训练数据集的形状 print(X_train.shape, y_train.shape) # 拟合模型 模型 = LinearRegression() model.fit(X_train, y_train) # 评估模型 yhat = model.predict(X_test) # 评估预测 mae = mean_absolute_error(y_test, yhat) print('MAE: %.3f' % mae) |
运行示例会拟合和评估模型,然后报告 MAE。
注意:考虑到算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到模型识别并删除了 34 个异常值,MAE 约为 3.189,比基线(3.417)有所改进。
1 2 3 |
(339, 13) (339,) (305, 13) (305,) MAE: 3.189 |
最小协方差行列式
如果输入变量服从高斯分布,则可以使用简单的统计方法来检测异常值。
例如,如果数据集有两个输入变量且都服从高斯分布,则特征空间形成多维高斯分布,并且可以使用该分布的知识来识别远离该分布的值。
这种方法可以通过定义一个覆盖正常数据的超球面(椭球)来推广,落在该形状之外的数据被认为是异常值。这种多元数据技术的有效实现被称为最小协方差行列式(简称 MCD)。
最小协方差行列式(MCD)方法是一种对多元位置和散布的稳健估计器,它有一个快速算法可用。 [...] 它也可用作异常值检测的方便高效工具。
—— 最小协方差行列式及其扩展,2017 年。
scikit-learn 库通过 EllipticEnvelope 类提供对该方法的访问。
它提供了“contamination”参数,该参数定义了实践中预期观察到的异常值比率。在这种情况下,我们将其设置为 0.01,这是通过一些试错找到的。
1 2 3 4 |
... # 识别训练数据集中的异常值 ee = EllipticEnvelope(contamination=0.01) yhat = ee.fit_predict(X_train) |
一旦识别出异常值,就可以像前面的示例一样从训练数据集中删除它们。
综合来看,下面列出了使用椭圆包络(最小协方差行列式)方法从房屋数据集中识别和删除异常值的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# 使用椭圆包络删除异常值后评估模型性能 from pandas import read_csv from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.covariance import EllipticEnvelope from sklearn.metrics import mean_absolute_error # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 总结训练数据集的形状 print(X_train.shape, y_train.shape) # 识别训练数据集中的异常值 ee = EllipticEnvelope(contamination=0.01) yhat = ee.fit_predict(X_train) # 选择所有非异常值的行 mask = yhat != -1 X_train, y_train = X_train[mask, :], y_train[mask] # 总结更新后的训练数据集的形状 print(X_train.shape, y_train.shape) # 拟合模型 模型 = LinearRegression() model.fit(X_train, y_train) # 评估模型 yhat = model.predict(X_test) # 评估预测 mae = mean_absolute_error(y_test, yhat) print('MAE: %.3f' % mae) |
运行示例会拟合和评估模型,然后报告 MAE。
注意:考虑到算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到椭圆包络方法识别并仅删除了 4 个异常值,导致 MAE 从基线的 3.417 下降到 3.388。
1 2 3 |
(339, 13) (339,) (335, 13) (335,) MAE: 3.388 |
局部异常因子
识别异常值的一个简单方法是找到那些在特征空间中与其他示例相距甚远的示例。
这对于低维度的特征空间(少数特征)可能效果很好,但随着特征数量的增加,其可靠性会降低,这被称为维度诅咒。
局部异常因子(简称 LOF)是一种试图利用近邻思想进行异常值检测的技术。每个示例都被分配一个评分,表明它根据其局部邻域的大小有多孤立或有多大可能是异常值。得分最高的示例更可能是异常值。
我们为数据集中的每个对象引入一个局部异常值 (LOF),以表明其异常程度。
—— LOF: 识别基于密度的局部异常值,2000 年。
scikit-learn 库在 LocalOutlierFactor 类中提供了这种方法的实现。
该模型提供了“contamination”参数,即数据集中异常值的预期百分比,默认为 0.1。
1 2 3 4 |
... # 识别训练数据集中的异常值 lof = LocalOutlierFactor() yhat = lof.fit_predict(X_train) |
综合来看,下面列出了使用局部异常因子方法从房屋数据集中识别和删除异常值的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# 使用局部异常因子删除异常值后评估模型性能 from pandas import read_csv from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.neighbors import LocalOutlierFactor from sklearn.metrics import mean_absolute_error # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 总结训练数据集的形状 print(X_train.shape, y_train.shape) # 识别训练数据集中的异常值 lof = LocalOutlierFactor() yhat = lof.fit_predict(X_train) # 选择所有非异常值的行 mask = yhat != -1 X_train, y_train = X_train[mask, :], y_train[mask] # 总结更新后的训练数据集的形状 print(X_train.shape, y_train.shape) # 拟合模型 模型 = LinearRegression() model.fit(X_train, y_train) # 评估模型 yhat = model.predict(X_test) # 评估预测 mae = mean_absolute_error(y_test, yhat) print('MAE: %.3f' % mae) |
运行示例会拟合和评估模型,然后报告 MAE。
注意:考虑到算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到局部异常因子方法识别并删除了 34 个异常值,与孤立森林的数量相同,导致 MAE 从基线的 3.417 下降到 3.356。虽然有所改善,但不如孤立森林,这表明识别和删除的异常值集合不同。
1 2 3 |
(339, 13) (339,) (305, 13) (305,) MAE: 3.356 |
单类支持向量机
支持向量机(简称 SVM)算法最初是为二元分类开发的,可用于单类分类。
在对一个类进行建模时,算法会捕获多数类的密度,并将密度函数极端的示例分类为异常值。这种 SVM 的修改称为单类 SVM。
……一种计算二元函数的算法,该函数旨在捕获输入空间中概率密度存在的区域(其支持),即,大多数数据将存在于函数非零区域的函数。
—— 估计高维分布的支持,2001 年。
尽管 SVM 是一种分类算法,单类 SVM 也是一种分类算法,但它可用于发现回归和分类数据集中的输入数据异常值。
scikit-learn 库在 OneClassSVM 类中提供了单类 SVM 的实现。
该类提供了“nu”参数,用于指定数据集中异常值的近似比率,默认为 0.1。在这种情况下,我们将其设置为 0.01,这是通过一些试错找到的。
1 2 3 4 |
... # 识别训练数据集中的异常值 ee = OneClassSVM(nu=0.01) yhat = ee.fit_predict(X_train) |
综合来看,下面列出了使用单类支持向量机方法从房屋数据集中识别和删除异常值的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# 使用单类 SVM 删除异常值后评估模型性能 from pandas import read_csv from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.svm import OneClassSVM from sklearn.metrics import mean_absolute_error # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' df = read_csv(url, header=None) # 检索数组 data = df.values # 分割输入和输出元素 X, y = data[:, :-1], data[:, -1] # 拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1) # 总结训练数据集的形状 print(X_train.shape, y_train.shape) # 识别训练数据集中的异常值 ee = OneClassSVM(nu=0.01) yhat = ee.fit_predict(X_train) # 选择所有非异常值的行 mask = yhat != -1 X_train, y_train = X_train[mask, :], y_train[mask] # 总结更新后的训练数据集的形状 print(X_train.shape, y_train.shape) # 拟合模型 模型 = LinearRegression() model.fit(X_train, y_train) # 评估模型 yhat = model.predict(X_test) # 评估预测 mae = mean_absolute_error(y_test, yhat) print('MAE: %.3f' % mae) |
运行示例会拟合和评估模型,然后报告 MAE。
注意:考虑到算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到只识别并删除了三个异常值,模型实现了大约 3.431 的 MAE,这并不比基线模型的 3.417 好。也许通过更多的调优可以实现更好的性能。
1 2 3 |
(339, 13) (339,) (336, 13) (336,) MAE: 3.431 |
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
相关教程
论文
- 孤立森林, 2008.
- 最小协方差行列式及其扩展, 2017.
- LOF:识别基于密度的局部异常值, 2000.
- 估计高维分布的支持, 2001.
API
- 新颖性与异常值检测,scikit-learn 用户指南.
- sklearn.covariance.EllipticEnvelope API.
- sklearn.svm.OneClassSVM API.
- sklearn.neighbors.LocalOutlierFactor API.
- sklearn.ensemble.IsolationForest API.
总结
在本教程中,您学习了如何使用自动异常值检测和删除来提高机器学习预测建模性能。
具体来说,你学到了:
- 自动异常值检测模型为具有大量输入变量且关系复杂且未知的情况提供了统计技术的替代方案。
- 如何仅将自动异常值检测和删除正确应用于训练数据集以避免数据泄露。
- 如何评估和比较从训练数据集中删除异常值的预测建模管道。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
嗨 Jason,感谢您的又一篇精彩文章!
我的问题是关于基于树的算法(RF、XGBoost)中的异常值。在这种情况下,删除异常值真的会改变模型在实际生活中的结果吗?研究结果会随着时间而变化,这就是我提出这个问题的原因。
我认为树对异常值相当稳健。请针对您的数据集进行测试。
好文!
感谢您的分享!
不客气。
列表中还有两个:自动编码器和 PCA
用于异常值检测?怎么会?
实际上,自动编码器可以在异常检测问题中提供最佳性能,其次是 PCA。
这取决于具体的数据集。
绝对正确!我也尝试过,它在自动编码器方面表现得非常好。
自动编码器和 PCA 都是降维技术。有趣的是,在降维过程中会识别出异常值。
你好,先生,
这是一篇很棒的文章。只有一个疑问
当数据具有非常大的维度(例如 >1000)时,MCD 技术表现不佳。在这种情况下,使用数据的主成分来训练模型是一个不错的选择。您在链接中提到的论文说
“对于大型 p,我们仍然可以对散布进行粗略估计,如下所示。首先计算数据的前 q < p 个稳健主成分。为此,我们可以使用基于 MCD 的 ROBPCA 方法53,这要求成分 q 的数量设置得相当低。”
现在 ROBPCA 在 python 中不可用。您能告诉我这种情况下该怎么做吗?
谢谢你
好建议,谢谢。
也许找一个实现该方法的不同平台?
也许自己实现?
也许完全使用不同的方法?
嗨,Jason,
一如既往的精彩教育文章。
自动异常值检测如何集成到交叉验证循环中?它是否必须是管道的一部分,其步骤将是:异常值检测 > 异常值删除(转换器)> 建模?
在这种情况下,是否应该创建一个特定的“异常值移除器”转换器?
谢谢
您必须手动运行 CV 循环,并在拟合/评估模型或管道之前将方法应用于数据。
令人失望的是 sklearn 不支持管道中添加/删除行的方法。不平衡学习可以做到这一点……
感谢您的精彩文章。
哪种算法最适合时间序列数据中的异常值检测?
我暂时不清楚,我希望将来能写一篇关于这个主题的文章。
问候,
感谢这篇精彩的文章。你有没有写过关于时间序列异常检测的文章?我正在学习,很想听听你的看法 🙂
还没有,在待办事项中。
对这个有什么想法?https://github.com/arundo/adtk
我不熟悉它。
如果有人在 X_train[mask, :] 遇到 TypeError,只需将其更改为 X_train[mask]。顺便说一句,又一篇很棒的文章。
听到这个消息我很难过。
或许这些提示会有帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
嗨,Jason。
感谢这篇文章。
不过有几个问题
1. 我们如何验证本文中提到的异常值检测算法的输出,即标记的记录是否真的是异常值?通过箱线图?
2. 另外,为什么我们不将目标变量作为异常值算法的输入?我漏掉了这一点……
谢谢。
好问题,您可以通过评估已知异常值数据集上的预测来验证模型,或者检查已识别的异常值并使用主题专家来确定它们是否是真正的异常值。
这些算法是单类算法,不需要目标变量。
太棒了,谢谢!
不客气。
您有没有使用 Q-learning 进行异常值检测的示例?我发现 Q-learning 几乎用于许多动作(机器人上下左右移动,因此有 4 个动作)的情况,但在异常值检测的情况下,它只有 2 个动作(正常行为和异常值),这让我担心 Q-learning 能否用于异常值检测(异常检测)。如果您能提供一个示例或提出任何建议,我将不胜感激。
抱歉,目前我没有任何示例或 RL。
感谢您的建议。
嗨,很棒的教程。
只有一个问题。您如何查看所有被删除的行?
“被删除的行”是什么意思?
嗨,Jason,
我读过关于孤立森林等超参数调整的文章。当所有模型/删除检测到的异常值并没有真正增加价值或没有改善我的基线模型的分数时:你认为投入时间进行这些异常检测模型的超参数调整有意义吗?
此外:在我看来,这些异常值似乎对我来说是合法的……
再次感谢,
马龙
如果它不能提高性能,那么就不需要。
我想他的意思是那些被识别为异常值(被删除的行)的行!
感谢您的精彩文章。我有一个问题,为什么我们不将异常值检测算法应用于整个数据集,而只应用于训练数据集?如果测试数据集中有异常数据,这不会影响模型的准确性吗?
我们不知道这个例子只将自动方法应用于训练数据集。
先生您好!感谢您提供的精彩内容,我只想指出一点。在孤立森林的 Scikit Learn 文档中,我读到 contamination 的默认值不再是 0.1,而是更改为 auto。您可以更正该部分 🙂
不客气。
感谢您的建议。
一点小提示!在最小协方差行列式方法中,您提到当特征是高斯或类似高斯分布时可以使用此方法,但在您使用的数据集中,特征并没有这样的形状。它们中的大多数都是偏斜的。我认为我们应该首先应用转换(对数、box-cox 等),然后将此方法应用于几乎没有或没有偏斜的特征。我实际上正在为此编写一个 Kaggle kernel,并且很想听听您完成后的想法!
通常,我建议评估使用和不使用数据预处理的方法,并采用性能最佳的方法。
先生,精彩的教程!
问题——我们是否总是应该删除包含异常值的行?在某些情况下,异常值插补会更好吗?
谢谢。
这是您必须在预测项目中做出的决定。
Jason 你的努力值得赞赏。您能告诉我是否可以将异常值检测方法应用于用于情感分类的文本数据?如果可以,那该如何应用
不确定文本中的“异常值”是什么意思,也许是稀有词——在这种情况下,将词汇量减少到最常用词即可。
关于孤立森林的一个问题
我没有理解第 22 行代码:mask = yhat != -1
您能详细解释一下吗。
- 数据科学新手
掩码等于一个布尔值,取决于 yhat 中的值是否为 -1。
嗨,Jason!
首先,祝贺并感谢这项有趣的工作!
只有一个问题:是否可以获得 LOF 的准确性?更具体地说,sklearn LOF 库是否可以做到这一点?
谢谢!
是的,上面的教程中有一个 LOF 示例,您可以用来入门。
感谢分享
不客气!
嗨,Jason,
您能否澄清一下,在时间序列数值数据中,哪种缩放(例如 MinMax)更适合用于异常检测的二元分类?考虑到大多数特征是接近的(彼此之间差异很小),数字和一些小的异常变化会在系统中产生异常。
非常感谢您的关注和参与。
我建议测试不同的方法,并使用能让您的模型在您的数据集上表现最佳的缩放方法。
嗨,Jason!
您认为我应该在数据转换之前还是之后删除异常值?或者我应该在降维和特征选择之前还是之后删除异常值?我知道如果数据是非参数的,则应该在转换之后删除异常值,但是如果我使用非参数异常值检测算法,这重要吗?
可能在之前,但这取决于数据和转换。测试一下,看看什么最适合你!
嗨,Jason,
关于如何摆脱数据异常值的精彩且有用的教程。
我分享了我对核心代码进行两次额外且连续的实现实验
1º) 我将每种异常值方法应用于整个数据集 (X_train + X_test),而不仅仅是 X_train。
我使用 IsolationForest() 获得了更好的 MAE 结果,约为 2.9 而不是 3.19。
2º) 遵循此实现,我通过 Sklearn API ColumnTransformer() 应用列转换。
特别是,我对所有 X 输入实施了“MinMaxScaler()”,对 Y(波士顿房价)输出实施了“StandardScaler”。
我使用 LOF 方法获得了出色的 MAE,等于 0.3(在仅消除 23 行异常值后,甚至比其他方法(如 IsolationForest())更少)。
非常感谢……您真的提升了我们的 ML/DL 技能!感谢您的精彩教程!
我非常感谢您。
此致,
JG
干得好!
亲爱的,我看到您只从训练数据集 (X_train) 中删除行而没有标签 (y_train)。您打算如何从目标变量中删除相同的元素?
抱歉,我不太理解您的问题,也许您可以重新措辞或详细说明。
异常值删除是根据输入特征从数据集中删除行。
我想他问的是如何从目标中删除训练中的相同行。只需查看他代码中的“mask”即可,那一行标记了异常值的位置(技术术语是索引)。
谢谢。
嗨,Jason,
很棒的文章,我学到了很多!我有一个问题。有必要将这些类型的异常值方法放入 scikit 管道中吗?
可能没有必要,但您也可以考虑一下。特别是如果您认为它有帮助,或者您有任何理由这样做(例如,在生产系统中,您不希望在输入错误时破坏模型)。
下午好,
所有这些内容都很棒!谢谢你!
想知道您在构建异常值检测模型时对特征选择有什么建议吗?
谢谢
嗨 Manuel……您可能会发现以下资源很有趣
https://ieeexplore.ieee.org/document/7837865
https://ojs.aaai.org/index.php/AAAI/article/view/5755/5611
你好 Jason,
精彩的文章,
我只是不明白这些方法如何检测异常值?
嗨 Sajad……您可能会发现以下内容很有趣
https://machinelearning.org.cn/how-to-use-statistics-to-identify-outliers-in-data/
https://machinelearning.org.cn/anomaly-detection-with-isolation-forest-and-kernel-density-estimation/
嗨,Jason,
感谢这篇精彩的文章。
我有一个关于孤立森林的问题,使用这个算法我们可以根据特征检测异常值,然后删除这些记录,但我想知道如何用中位数/均值替换这些记录而不是删除它们。
谢谢
嗨 Merve……您可能会发现以下内容很有趣
https://stackoverflow.com/questions/45386955/python-replacing-outliers-values-with-median-values
你好,
请问
何时使用基尼指数、KS 统计量和 p 值?https://machinelearning.org.cn/tour-of-evaluation-metrics-for-imbalanced-classification/
非常感谢
先生,我非常感谢您的努力和知识分享。
我有一个小而简单的问题。通常是自动异常值检测技术好用,还是手动技术 (IQR) 更好用?
嗨 Ma……非常欢迎!感谢您的反馈和支持!
通常很难预测哪种方法“最好”。我们建议您调查两种选择并比较性能。
让我们知道您的发现!