机器学习的缺失值的处理

机器学习中,对数据进行处理时,遇到缺失值的处理方法

为什么要进行缺失值插补?

  • 许多现实世界的数据集包含缺失值,通常编码为空白、NaN 或其他占位符
  • 样的数据集与 scikit-learn 估计器不兼容,后者假定数组中的所有值都是数字的,并且都具有并保持意义

在数据清理过程中,如何处理缺失值?

  • 删除: 若变量的缺失率较高(大于 80%),覆盖率较低,且重要性较低,可以直接将变量删除
  • 定值填充: 工程中常见用 - 9999 进行替代
  • 统计量填充: 若缺失率较低(小于 95%)且重要性较低,则根据数据分布的情况进行填充。对于数据符合均匀分布,用该变量的均值填补缺失,对于数据存在倾斜分布的情况,采用中位数进行填补。
  • 插值法填充: 包括单变量特征插补,最近邻插补,多重差补法,热平台插补,拉格朗日插值,牛顿插值等
  • 模型填充: 使用回归、贝叶斯、随机森林、决策树等模型对缺失数据进行预测。
  • 哑变量填充: 若变量是离散型,且不同值较少,可转换成哑变量,例如性别 SEX 变量,存在 male,fameal,NA 三个不同的值,可将该列转换成 IS_SEX_MALE, IS_SEX_FEMALE, IS_SEX_NA。
  • ** 一般处理流程:** 先用 pandas.isnull.sum () 检测出变量的缺失比例,考虑删除或者填充, 若需要填充的变量是连续型,一般采用均值法和随机差值进行填充;若变量是离散型,通常采用中位数或哑变量进行填充

sklearn 如何进行单变量特征插补?

  • SimpleImputer 供的常数值或使用缺失值所在的每一列的统计数据(平均值、中位数或最频繁)来估算缺失值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     >>> import numpy as np
    >>> from sklearn.impute import SimpleImputer
    >>> imp = SimpleImputer(missing_values=np.nan, strategy='mean')
    >>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
    SimpleImputer()
    >>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
    >>> print(imp.transform(X))
    [[4. 2. ]
    [6. 3.666...]
    [7. 6. ]]

sklearn 如何进行多元特征插补?

  • 一个更复杂的方法是使用 IterativeImputer 类,它将每个有缺失值的特征作为其他特征的函数来建模,并使用该估计值进行归因。它以迭代轮回的方式进行:在每一步,一个特征列被指定为输出 y,其他特征列被视为输入 X,一个回归器被拟合到已知 y 的(X,y)上。最后一轮归因的结果被返回
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     >>> import numpy as np
    >>> from sklearn.experimental import enable_iterative_imputer
    >>> from sklearn.impute import IterativeImputer
    >>> imp = IterativeImputer(max_iter=10, random_state=0)
    >>> imp.fit([[1, 2], [3, 6], [4, 8], [np.nan, 3], [7, np.nan]])
    IterativeImputer(random_state=0)
    >>> X_test = [[np.nan, 2], [6, np.nan], [np.nan, 6]]
    >>> # the model learns that the second feature is double the first
    >>> print(np.round(imp.transform(X_test)))
    [[ 1. 2.]
    [ 6. 12.]
    [ 3. 6.]]

sklearn 如何进行最近邻插补?

  • 默认情况下,支持缺失值的欧几里德距离度量,用于查找最近的邻居。每个缺失的特征都使用来自最近邻居的值进行估算,这些邻居具有该特征的值。邻居的特征被均匀地平均或按到每个邻居的距离加权。如果一个样本缺少一个以上的特征,那么该样本的邻居可能会根据被估算的特定特征而有所不同。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     >>> import numpy as np
    >>> from sklearn.impute import KNNImputer
    >>> nan = np.nan
    >>> X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]
    >>> imputer = KNNImputer(n_neighbors=2, weights="uniform")
    >>> imputer.fit_transform(X)
    array([[1. , 2. , 4. ],
    [3. , 4. , 3. ],
    [5.5, 6. , 5. ],
    [8. , 8. , 7. ]])