了解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)
问题是,它如何填充nan
s,同时在两列中有nan
s?例如,如果要在第一行的第三列中填充nan
,由于其中一行在第一列中也有nan
,它将如何选择最接近的特征?当我做imputer.fit_transform(X)
它给了我
array([[1. , 2. , 4. ],
[3. , 4. , 3. ],
[5.5, 6. , 5. ],
[8. , 8. , 7. ]])
这意味着要填写第一行中的nan
,最近的邻居是第二行和第三行。第一排和第三排的欧式距离是怎么计算的?
【问题讨论】:
【参考方案1】:它如何使用也有
NaNs
的行填充NaN
s?
文档中似乎没有提到这一点。但是通过深入研究源代码,似乎对于每一列进行估算,所有距离较小的 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.]
中输入缺失值时,选择了最后一行(也包含两个NaN
s)(注意我设置了n_neighbors=1
)。这是因为与最后一行的距离是0
,因为与NaN
值对应的距离 已设置为0
。因此,只要与行 2
和 3
有最小差异,就选择最后一行,因为它被视为相等:
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 多分类,无需预先了解 Python 中的分类