数据预处理 第4篇:数据预处理(sklearn 插补缺失值)

由于各种原因,现实世界中的许多数据集都包含缺失值,通常把缺失值编码为空白,NaN或其他占位符。但是,此类数据集与scikit-learn估计器不兼容,这是因为scikit-learn的估计器假定数组中的所有值都是数字,并且都存在有价值的含义。如果必须使用不完整数据集,那么处理缺失数据的基本策略是丢弃包含缺失值的整个行和/或列,但是,这是以丢失有价值的数据为代价的(即使数据不完整),更好的策略是估算缺失值,从数据的已知部分推断出缺失值,这就是插补(imputation)。

单变量插补法(univariate imputation),仅使用第i个特征维度中的非缺失值来插补第i个特征维度中的值。相比之下,多变量插补算法(multivariate imputation)会使用整个可用特征维度集来估算缺失值。

一,单变量插补

在sklearn包中,使用SimpleImputer估算器来实现单变量插补,单变量插补的处理策略(由strategy参数制定)有四个:mean,median,most_frequent和constant(搭配fill_value参数使用)。其中,mean和median分别表示使用均值和中位数来插补缺失值;对于定性数据,可以使用most_frequent(众数)来插补缺失值。

>>> 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.        ]]

二,多变量插补

在scikit-learn包中,多变量插补使用IterativeImputer估算器来实现,该估算器把含有缺失值的每个特征建模为其他特征的函数,并使用该估算值进行插补。

多变量插补法以迭代循环的方式进行:

  • 在每个步骤中,将特征列指定为输出y,将其他特征列视为输入X。
  • 把回归器拟合到已知的y的(X,y)上。
  • 然后,使用回归器预测y的缺失值。
  • 针对每个特征以迭代方式完成此操作,然后在max_iter插补回合中重复此操作。
  • 返回最后一轮估算的结果。

注意:多变量插补估算器目前仍处于试验阶段:默认参数或行为可能会更改。 解决以下问题将有助于稳定IterativeImputer:

  • 收敛标准(#14338):IterativeImputer不会收敛,事实上,收敛准则似乎不会随着迭代而下降。
  • 默认估计量(#13286):使用正则化最小二乘模型进行迭代插补与使用NMF进行插补大致相同。 取而代之的是,至少在sample_posterior = False的情况下,否则,我们应该使用RandomForestRegressor作为IterativeImputer中的默认回归器。
  • 随机状态的使用 (#15611):通过random_state指定RandomState对象,来保证结果可重复,有些跟scikit-learn相兼容的模块可能不兼容RandomState对象。

要使用多变量插补,需要显式导入enable_iterative_imputer。

>>> 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.]]

注意,IterativeImputer 返回单个插补而不是多个插补,但是,当设置sample_posterior = True时,通过把IterativeImputer重复应用于具有不同随机种子的同一数据集,也可以将其用于多个插补。

三,最邻近插补

KNNImputer 类提供了使用k最近邻方法来填充缺失值的插补。默认情况下,使用nan_euclidean_distances作为从存在缺失值的特征中计算欧氏距离的度量标准,用欧氏距离来查找最近的邻居。从存在缺失值的特征中选取最邻近的n_neighbors个邻居,使用这n_neighbors个邻居的值估算特征缺失的值。邻居的特征被均匀地平均,或通过到每个邻居的距离加权。如果一个样本有多个特征缺失,那么该样本的邻居可能会有所不同,具体取决于要插补的特定特征。当可用邻居的数量小于n_neighbors,并且与训练集之间没有定义的距离时,在插补过程中将使用该特征的训练集的平均值。如果存在至少一个具有定义距离的邻居,则在插补期间将使用其余邻居的加权或未加权平均值。如果训练中始终缺少某个特征,则在变换过程中将其删除。

以下代码段演示了如何使用具有缺失值的样本的两个最近邻居的平均特征值替换编码为np.nan的缺失值:

>>> 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.]]

 

参考文档:

6.4. Imputation of missing values

posted @ 2020-12-29 10:26  悦光阴  阅读(2373)  评论(0编辑  收藏  举报