当我从头开始实现KNN填补方法来处理缺失数据时,我遇到了这个问题。我创建了一个虚拟数据集,并为包含缺失值的行找到了最邻近的邻居,以下是我的数据集
A B C D E0 NaN 2.0 4.0 10.0 100.01 NaN 3.0 9.0 12.0 NaN2 5.0 2.0 20.0 50.0 75.03 3.0 5.0 7.0 NaN 150.04 2.0 9.0 7.0 30.0 90.0
对于第0行,最邻近的邻居是1和2,为了替换(0, A)位置的NaN值,我们需要计算最邻近邻居在同一列中的值的距离平均值,但如果其中一个最邻近邻居的值也是NaN该怎么办?
示例:
假设第3行的最邻近邻居是2和4,所以在第3行中,列D有缺失值,为了替换这个缺失值,我们需要计算列D中最邻近邻居的值的距离平均值,如下所示
距离平均值 = [(1/D1) * 50.0 + (1/D2) * 30.0]/2
并用这个平均值替换(3, D)位置的NaN值(其中D1和D2是对应的NaN欧几里得距离)。但是在第0行的情况下,最邻近的邻居是1和2,为了替换(0, A)位置的NaN值,我们需要计算第1行和第2行在列A中的值的距离平均值,(2, A)的值是5.0很好,但是(1, A)是NaN,所以我们不能这样计算
距离平均值 = [(1/D3) * NaN + (1/D4) * 5.0]/2
那么我们如何替换(0, A)位置的NaN值?sklearn的KNNImputer是如何处理这种情况的?
回答:
sklearn的KNNImputer
默认使用nan_euclidean_distances
度量方法。根据其用户指南
如果一个样本有多个特征缺失,那么对于该样本的邻居可能会根据所填补的特定特征而有所不同。
该算法可能会使用不同的邻居集合来填补列D中的单个缺失值和列A中的两个缺失值。
这是一个简单的KNNImputer实现:
import numpy as npimport pandas as pdfrom sklearn.impute import KNNImputerA = [np.nan, np.nan, 5, 3, 2]B = [2, 3, 2, 5, 9]C = [4, 9, 20, 7, 7]D = [10, 12, 50, np.nan, 30]E = [100, np.nan, 75, 150, 90]columns=['A', 'B', 'C', 'D', 'E']data = pd.DataFrame(list(zip(A, B, C, D, E)), columns=columns)imputer = KNNImputer(n_neighbors=2)imputed_data = pd.DataFrame(imputer.fit_transform(data), columns=columns)
这是输出结果:
A B C D E0 3.5 2.0 4.0 10.0 100.01 2.5 3.0 9.0 12.0 125.02 5.0 2.0 20.0 50.0 75.03 3.0 5.0 7.0 11.0 150.04 2.0 9.0 7.0 30.0 90.0