了解sklearn的KNNImputer

Posted

技术标签:

【中文标题】了解sklearn的KNNImputer【英文标题】:Understanding sklearn's KNNImputer 【发布时间】:2020-08-28 07:50:56 【问题描述】:

我正在浏览它的文档,它说

每个样本的缺失值均使用来自 n_neighbors 在训练集中找到的最近邻居。两个样品 如果两个都没有丢失的特征是接近的,那么它们是接近的。

现在,玩弄一个玩具数据集,即

>>>X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]
>>>X

   [[ 1.,  2., nan],
    [ 3.,  4.,  3.],
    [nan,  6.,  5.],
    [ 8.,  8.,  7.]]

我们制作一个 KNNImputer 如下:

imputer = KNNImputer(n_neighbors=2)

问题是,它如何填充nans,同时在两列中有nans?例如,如果要在第一行的第三列中填充nan,由于其中一行在第一列中也有nan,它将如何选择最接近的特征?当我做imputer.fit_transform(X) 它给了我

array([[1. , 2. , 4. ],
       [3. , 4. , 3. ],
       [5.5, 6. , 5. ],
       [8. , 8. , 7. ]])

这意味着要填写第一行中的nan,最近的邻居是第二行和第三行。第一排和第三排的欧式距离是怎么计算的?

【问题讨论】:

【参考方案1】:

它如何使用也有NaNs 的行填充NaNs?

文档中似乎没有提到这一点。但是通过深入研究源代码,似乎对于每一列进行估算,所有距离较小的 donors 都会被考虑,即使它们有缺失值。处理方法是通过将权重矩阵中的缺失值设置为0,该矩阵根据使用的距离获得,参见_get_weights

相关代码在_calc_impute,在找到所有潜在捐助者的距离矩阵,然后上面提到的权重矩阵后,它被推算为:

# fill nans with zeros
if weight_matrix is not None:
    weight_matrix[np.isnan(weight_matrix)] = 0.0

如果所有潜在的捐赠者与接受者有至少一个非纳米距离

,他们都会被考虑
dist_pot_donors : ndarray of shape (n_receivers, n_potential_donors)
    Distance matrix between the receivers and potential donors from
    training set. There must be at least one non-nan distance between
    a receiver and a potential donor.

我们可以用一个玩具例子来检查一下;在下面的矩阵中,当在[nan, 7., 4., 5.] 中输入缺失值时,选择了最后一行(也包含两个NaNs)(注意我设置了n_neighbors=1)。这是因为与最后一行的距离是0,因为与NaN 值对应的距离 已设置为0。因此,只要与行 23 有最小差异,就选择最后一行,因为它被视为相等:

X = np.array([[np.nan,7,4,5],[2,8,4,5],[3,7,4,6],[1,np.nan,np.nan,5]])

print(X)
array([[nan,  7.,  4.,  5.],
       [ 2.,  8.,  4.,  5.],
       [ 3.,  7.,  4.,  6.],
       [ 1., nan, nan,  5.]])

from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=1)

imputer.fit_transform(X)
array([[1., 7., 4., 5.],
       [2., 8., 4., 5.],
       [3., 7., 4., 6.],
       [1., 7., 4., 5.]])

【讨论】:

您能解释一下“仅通过与第 2 行和第 3 行的最小差异,选择最后一行,因为它被视为相等”吗? 因此,如果您注意到,最后一行和第一行仅共享最后一列。由于 las 行中的其余值是 nan。它仍然是用于替换第一行的行。那是因为有0差异。 Nans被视为0差异。虽然第二行和第三行,die 有一些错误,但错误很小,但它们是不同的。所以选择误差最小的那个@arghhjayy 明白。现在,假设第 1 行第 1 列 nan 是第一步。对于第二步,我们要替换第 4 行第 2 列中的 nan。那么,对于第 2 步,第 1 行第 1 列的值是多少,是 nan 还是第一步中的估算值?跨度> NaN 是逐列填充的,您可以在 process_chunk 中看到。因此,由于第一行中的 nan 位于左侧,因此它已经被估算,因此如果我没有遗漏某些东西,则应考虑新值@arghhjayy

以上是关于了解sklearn的KNNImputer的主要内容,如果未能解决你的问题,请参考以下文章

了解sklearn的KNNImputer

SKLearn 多分类,无需预先了解 Python 中的分类

了解 sklearn grid_search

了解 sklearn 中 CountVectorizer 中的“ngram_range”参数

sklearn“RidgeClassifier”有啥作用?

sklearn 高斯朴素贝叶斯 - 为啥是“高斯”?