机器学习的噪声、奇异值、异常值

机器学习中,对数据进行处理时,遇到噪声、异常值的处理方法

什么是噪声 (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):这是一种稳健对抗离群数据的距离值方法,采用计算各观测值与平均值的距离总和的方法。放大了离群值的影响
  • 基于距离:通过定义对象之间的临近性度量,根据距离判断异常对象是否远离其他对象,缺点是计算复杂度较高,不适用于大数据集和存在不同密度区域的数据集
  • 基于密度:离群点的局部密度显著低于大部分近邻点,适用于非均匀的数据集
  • 基于聚类:利用聚类算法,丢弃远离其他簇的小簇

在数据清理过程中,如何处理离群点(异常值)?

  • 机器学习的噪声、奇异值、异常值-20230408153959
  • 删除: 根据异常点的数量及影响,删除该样本
  • 替代: 使用平均值或中位数替代异常点
  • 变换: 对数据做 log-scale 对数变换,消除异常值
  • 树模型: 选择对异常值不敏感的树模型

在数据清理过程中,如何处理噪声?

  • 分箱:对数据进行分箱操作,等频或等宽分箱,然后用每个箱的平均数,中位数或者边界值(不同数据分布,处理方法不同)代替箱中所有的数,起到平滑(均值、边界值、中值)数据的作用
  • 建立该变量和预测变量的回归模型,根据回归系数和预测变量,反解出自变量的近似值