由于各种原因,现实世界的许多数据集包含缺失值,通常将其编码为空白,NaN或其他占位符。但是,此类数据集与Scikit-Learn估计器不兼容,后者假定数组中的所有值都是具有含义的数字
使用不完整数据集的基本策略是舍弃包含缺失值的整行或整列。但是,这是以丢失可能有价值的数据为代价的(即使数据不完整)。更好的策略是估算缺失值,即从数据的已知部分推断出缺失值
缺失值的处理是数据预处理中非常重要的一步,因为很多机器学习算法都假设数据是完整的,算法的执行过程中没有考虑缺失值的影响。所以,为了提高数据质量、改进数据分析结果、提高数据挖掘和机器学习的效果,缺失值处理必不可少
对于包含缺失值的数据,有两种处理思路:
Scikit-Learn缺失值填充中文文档:https://scikit-learn.org.cn/view/124.html
下面主要介绍一些常用的缺失值填充处理方式
1)单变量填充
Scikit-Learn中的SimpleImputer
类提供了填充缺失值的基本策略。可以使用提供的常量或使用缺失值所在列的统计量(平均值、中位数或众数)来估算填充缺失值。此类还支持不同的缺失值编码
from sklearn.impute import SimpleImputer
# 均值(mean)、中位数(median)、众数(most_frequent)和常量(constant)填充
# 下面以均值填充为例
data = np.array([[1, 2, 3], [4, np.NaN, 6], [7, 8, np.NaN]])
print(data)
'''
[[ 1. 2. 3.]
[ 4. nan 6.]
[ 7. 8. nan]]
'''
# SimpleImputer(missing_values,strategy,fill_value)
# missing_values:指定缺失值 strategy:填充策略 fill_value:当填充策略为常量(constant)时使用
imputer = SimpleImputer(missing_values=np.NaN, strategy="mean")
data = imputer.fit_transform(data)
print(data)
'''
[[1. 2. 3. ]
[4. 5. 6. ]
[7. 8. 4.5]]
'''
填充的5和4.5分别是第二列和第三列的平均值
2)多变量填充
一种更复杂的方法是使用IterativeImputer
类,该类将每个包含缺失值的特征建模为其他特征的函数,并将该估计值用于插补。它以迭代的方式进行:在每个步骤中,将一个特征列指定为输出y,而将其他特征列视为输入X。回归器通过fit(X,y)
得到y。然后,使用该回归器预测y的缺失值。针对每个特征以迭代方式完成此操作,然后在max_iter
个插补回合中重复此操作,返回最后一轮估算的结果
种方式在填充时会考虑多个特征之间的关系,例如,对于特征A列中的缺失值,会同时考虑特征A和其他特征的关系,将其他特征作为自变量,特征A作为因变量,然后建模,来预测特征A中缺失值对应的预测值,通过控制迭代次数,将最后一次迭代的预测值作为填充值
需要注意的是,要使用它,我们需要显式的导入enable_iterative_imputer
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
data = np.array([[1, 2, 3], [4, np.NaN, 6], [7, 8, np.NaN]])
print(data)
'''
[[ 1. 2. 3.]
[ 4. nan 6.]
[ 7. 8. nan]]
'''
imp = IterativeImputer(max_iter=10, random_state=0)
data1 = imp.fit_transform(data)
print(data1)
'''
[[1. 2. 3. ]
[4. 5.00203075 6. ]
[7. 8. 8.99796726]]
'''
# 这种方式非常灵活,在拟合的时候可以选择多种模型,默认为BayesianRidge()循环插补估计器
# 下面以决策树回归模型为例
from sklearn.tree import DecisionTreeRegressor
imp = IterativeImputer(DecisionTreeRegressor(), max_iter=10, random_state=0)
data2 = imp.fit_transform(data)
print(data2)
'''
[[1. 2. 3.]
[4. 8. 6.]
[7. 8. 6.]]
'''
3)K近邻(KNN)填充
Scikit-Learn中的KNNImputer
类提供插补使用K-最近邻方法进行缺失值填充。默认情况下,支持缺失值nan_euclidean_distances
的欧几里得距离度量标准用于查找最近的邻居。使用n_neighbors
最近邻中具有该特征值的值来估算每个特征的缺失值。邻居的特征被平均或通过距离加权到每个邻居
K近邻填充利用K近邻算法,找到与缺失值最近的K个数据点,用它们的值的平均数或中位数来填充缺失值
API及参数介绍见中文官方文档:https://scikit-learn.org.cn/view/770.html
from sklearn.impute import KNNImputer
data = np.array([[1, 2, 3], [4, np.NaN, 6], [7, 8, np.NaN], [10, 11, 12]])
print(data)
'''
[[ 1. 2. 3.]
[ 4. nan 6.]
[ 7. 8. nan]
[10. 11. 12.]]
'''
# uniform:统一的权重。每个邻域内的所有点的权重是相等的
imputer = KNNImputer(n_neighbors=2, weights="uniform")
data = imputer.fit_transform(data)
print(data)
'''
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]
[10. 11. 12.]]
'''
填充的5和9分别是第二列和第三列缺失值最近的2个数据点的平均值
缺失值处理的主要作用包括:
在选择处理缺失值的方法时,需要考虑数据的性质、缺失值的比例、数据的分布以及具体的分析任务等因素。同时,不同的方法可能适用于不同的场景,需要结合具体情况进行选择
参考文章:
https://www.cnblogs.com/wang_yb/p/17921351.html
https://cloud.tencent.com/developer/article/1786924