机器学习的噪声、奇异值、异常值
机器学习中,对数据进行处理时,遇到噪声、异常值的处理方法
什么是噪声 (nose)?
- 表达了当前任务上任何学习算法所能达到的期望泛化误差下界,刻画了问题本身的难度
什么是异常值?
- 训练数据包含异常值,这些异常值被定义为与其他数据相距甚远的观察值。因此,异常值检测估计器试图拟合训练数据最集中的区域,而忽略异常观察
- 异常值检测也称为无监督异常检测
什么是奇异值?
- 训练数据不包含异常值,只含有 positive(正常)的数据,通过算法学习其 pattern。之后用于检测未曾看到过新数据是否属于这个 pattern,如果属于,该新数据是 positive,否则 negative,即奇异值
- 新奇检测也称为半监督异常检测
噪声和离群点(异常点)有什么区别?
- 观测量 (Measurement) = 真实数据 (True Data) + 噪声 (Noise):而离群点 (Outlier) 属于观测量,既有可能是真实数据产生的,也有可能是噪声带来的,但是总的来说是和大部分观测量之间有明显不同的观测值
- 噪声与离群点有很多相同的地方。之间没有太过明确的定义,主要看应用的场景。如在信用卡诈骗中,我们通常会关注那些少量的异常数据,此时数据是具有探索意义的。而在一般的场景下,离群点和噪声都需要剔除
异常值检测算法?
- IsolationForest 算法
1
2
3
4
5>>> from sklearn.ensemble import IsolationForest
>>> X = [[-1.1], [0.3], [0.5], [100]]
>>> clf = IsolationForest(random_state=0).fit(X)
>>> clf.predict([[0.1], [0], [90]])
array([ 1, 1, -1]) - LocalOutlierFactor 算法
1
2
3
4
5
6
7
8>>> import numpy as np
>>> from sklearn.neighbors import LocalOutlierFactor
>>> X = [[-1.1], [0.2], [101.1], [0.3]]
>>> clf = LocalOutlierFactor(n_neighbors=2)
>>> clf.fit_predict(X)
array([ 1, 1, -1, 1])
>>> clf.negative_outlier_factor_
array([ -0.9821..., -1.0370..., -73.3697..., -0.9821...]) - OneClassSVM 算法
1
2
3
4
5
6
7>>> from sklearn.svm import OneClassSVM
>>> X = [[0], [0.44], [0.45], [0.46], [1]]
>>> clf = OneClassSVM(gamma='auto').fit(X)
>>> clf.predict(X)
array([-1, 1, 1, 1, -1])
>>> clf.score_samples(X)
array([1.7798..., 2.0547..., 2.0556..., 2.0561..., 1.7332...]) - SGDOneClassSVM 算法
1
2
3
4
5
6
7
8>>> import numpy as np
>>> from sklearn import linear_model
>>> X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
>>> clf = linear_model.SGDOneClassSVM(random_state=42)
>>> clf.fit(X)
SGDOneClassSVM(random_state=42)
>>> print(clf.predict([[4, 4]]))
[1] - EllipticEnvelope 算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17>>> import numpy as np
>>> from sklearn.covariance import EllipticEnvelope
>>> true_cov = np.array([[.8, .3],
... [.3, .4]])
>>> X = np.random.RandomState(0).multivariate_normal(mean=[0, 0],
... cov=true_cov,
... size=500)
>>> cov = EllipticEnvelope(random_state=0).fit(X)
>>> # predict returns 1 for an inlier and -1 for an outlier
>>> cov.predict([[0, 0],
... [3, 3]])
array([ 1, -1])
>>> cov.covariance_
array([[0.7411..., 0.2535...],
[0.2535..., 0.3053...]])
>>> cov.location_
array([0.0813... , 0.0427...])
在数据清理过程中,如何检测离群点(异常值)?
- 简单统计分析:根据箱线图、各分位点判断是否存在异常,例如 pandas 的 describe 函数可以快速发现异常值
- 3 原则:若数据存在正态分布,偏离均值的 3 之外。通常定义 范围内的点为离群点
- 基于绝对离差中位数(MAD):这是一种稳健对抗离群数据的距离值方法,采用计算各观测值与平均值的距离总和的方法。放大了离群值的影响
- 基于距离:通过定义对象之间的临近性度量,根据距离判断异常对象是否远离其他对象,缺点是计算复杂度较高,不适用于大数据集和存在不同密度区域的数据集
- 基于密度:离群点的局部密度显著低于大部分近邻点,适用于非均匀的数据集
- 基于聚类:利用聚类算法,丢弃远离其他簇的小簇
在数据清理过程中,如何处理离群点(异常值)?
- 删除: 根据异常点的数量及影响,删除该样本
- 替代: 使用平均值或中位数替代异常点
- 变换: 对数据做 log-scale 对数变换,消除异常值
- 树模型: 选择对异常值不敏感的树模型
在数据清理过程中,如何处理噪声?
- 分箱:对数据进行分箱操作,等频或等宽分箱,然后用每个箱的平均数,中位数或者边界值(不同数据分布,处理方法不同)代替箱中所有的数,起到平滑(均值、边界值、中值)数据的作用
- 建立该变量和预测变量的回归模型,根据回归系数和预测变量,反解出自变量的近似值