Python中使用KNN进行缺失值插补

21

我有一个数据集,长这样

1908    January 5.0 -1.4
1908    February    7.3 1.9
1908    March   6.2 0.3
1908    April   NaN   2.1
1908    May NaN   7.7
1908    June    17.7    8.7
1908    July    NaN   11.0
1908    August  17.5    9.7
1908    September   16.3    8.4
1908    October 14.6    8.0
1908    November    9.6 3.4
1908    December    5.8 NaN
1909    January 5.0 0.1
1909    February    5.5 -0.3
1909    March   5.6 -0.3
1909    April   12.2    3.3
1909    May 14.7    4.8
1909    June    15.0    7.5
1909    July    17.3    10.8
1909    August  18.8    10.7  

我希望使用KNN方法替换NaN,这与编程有关。我查阅了sklearn的Imputer类,但它仅支持均值、中位数和众数插补。这里有一个功能请求here,但我不认为目前已经实现。有没有想法如何使用KNN替换最后两列的NaN?
编辑:由于需要在另一个环境中运行代码,我不能安装其他软件包。我只能使用Sklearn、pandas、numpy和其他标准软件包。

Sklearn似乎非常接近发布此内容:https://github.com/scikit-learn/scikit-learn/pull/9212 - Cody Glickman
4个回答

23

fancyimpute包支持这种类型的填充,使用下面的API:

from fancyimpute import KNN    
# X is the complete data matrix
# X_incomplete has the same values as X except a subset have been replace with NaN

# Use 3 nearest rows which have a feature to fill in each row's missing features
X_filled_knn = KNN(k=3).complete(X_incomplete)

这个包支持以下缺失值填充方法:

•SimpleFill(简单填充): 将缺失值替换为每列的均值或中位数。

•KNN(最近邻填充): 计算两行都有观测数据的特征的平均平方差来加权样本的最近邻填充方法。

•SoftImpute(软阈值SVD分解填充): 通过迭代软阈值SVD分解完成矩阵填充。受基于Mazumder等人的《为学习大型不完整矩阵设计的谱正则化算法》着名的R软件包softImpute的启发,

•IterativeSVD(迭代低秩SVD分解填充): 通过迭代低秩SVD分解完成矩阵填充。应与Troyanskaya等人的《用于DNA微阵列的缺失值估计方法》中的SVDimpute类似。

•MICE(多重插补法): 链式方程多重插补法的重新实现。

•MatrixFactorization(矩阵分解填充): 直接将不完整的矩阵因子分解为低秩矩阵U和V,其中U中的元素具有L1稀疏性惩罚,V中的元素具有L2惩罚。采用梯度下降法求解。

•NuclearNormMinimization(核范数最小化): 通过使用cvxpy进行凸优化的精确矩阵完成的简单实现。对于大型矩阵太慢。

•BiScaler(双重标准化): 迭代估计行/列均值和标准差以获得双重标准化矩阵。不能保证收敛,但在实践中效果很好。取自《通过快速交替最小二乘法实现矩阵完成和低秩SVD》。


抱歉,我的错。这段代码需要在一个没有fancyImpute的环境中使用。它支持标准包,如numpy、pandas和sklearn。我会编辑问题。 - Clock Slave
6
那么,您可以查看fancyImpute的代码,并为您的情况自行实现。 - Vivek Kumar

6

fancyimpute的KNN插补不再支持其他答案建议的complete函数,现在需要使用fit_transform

# X is the complete data matrix
# X_incomplete has the same values as X except a subset have been replace with NaN
# Use 3 nearest rows which have a feature to fill in each row's missing features

X_filled_knn = KNN(k=3).fit_transform(X_incomplete)    

参考资料 https://github.com/iskandr/fancyimpute


6

scikit-learn v0.22支持本地KNN插补

import numpy as np
from sklearn.impute import KNNImputer

X = [[1, 2, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 7]]
imputer = KNNImputer(n_neighbors=2)
print(imputer.fit_transform(X))

2

这个pull request到sklearn添加了KNN支持。你可以从这里获取代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接