knnImpute 使用带有 caret 包的分类变量

bsh*_*141 2 r knn r-caret

我有以下 data.table,其中每个唯一x值都与一个唯一y值相关联。然后我强制一个x值作为NAk 最近邻练习的目的:

dt <- data.table(x = rep(c(1:4), 3), 
                 y = rep(c("Brandon", "Erica", "Karyna", "Alex"), 3))
dt[3, 1] <- NA

print(dt)
 #    x       y
 #1:  1 Brandon
 #2:  2   Erica
 #3: NA  Karyna
 #4:  4    Alex
 #5:  1 Brandon
 #6:  2   Erica
 #7:  3  Karyna
 #8:  4    Alex
 #9:  1 Brandon
#10:  2   Erica
#11:  3  Karyna
#12:  4    Alex
Run Code Online (Sandbox Code Playgroud)

参考这个问题的第一个答案,我创建了一个二进制矩阵,dt$y如下所示:

dt.a <- model.matrix(~ y -1 , data = dt)
dt2 <- cbind(dt[, -2, with = FALSE], dt.a)

print(dt2)
 #    x yAlex yBrandon yErica yKaryna
 #1:  1     0        1      0       0
 #2:  2     0        0      1       0
 #3: NA     0        0      0       1
 #4:  4     1        0      0       0
 #5:  1     0        1      0       0
 #6:  2     0        0      1       0
 #7:  3     0        0      0       1
 #8:  4     1        0      0       0
 #9:  1     0        1      0       0
#10:  2     0        0      1       0
#11:  3     0        0      0       1
#12:  4     1        0      0       0
Run Code Online (Sandbox Code Playgroud)

使用包函数中的knnImpute方法,我希望下面的中心和缩放输出等于第 7 行和第 12 行。但事实并非如此。事实上,它看起来几乎等于第 7 行和第 12 行的负值。preProcesscaretdt3[1, 3]

preobj <- preProcess(dt2, method = "knnImpute")
dt3 <- predict(preobj, dt2)

print(dt3)
 #             x      yAlex   yBrandon     yErica    yKaryna
 #1: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
 #2: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
 #3: -0.04494666 -0.5527708 -0.5527708 -0.5527708  1.6583124
 #4:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
 #5: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
 #6: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
 #7:  0.44946657 -0.5527708 -0.5527708 -0.5527708  1.6583124
 #8:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
 #9: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
#10: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
#11:  0.44946657 -0.5527708 -0.5527708 -0.5527708  1.6583124
#12:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
Run Code Online (Sandbox Code Playgroud)

dt3$x第 3 行不应该等于第 7 行和第 11 行吗?如果是这样,我需要在我的脚本中更改什么?如果不是,为什么?

9He*_*ads 5

要了解正在发生的事情,您首先需要了解 包knnImpute函数preProcess中 的方法的caret工作方式。可以使用各种类型的k 近邻插补,并且不同的人在不同的软件包中以不同的方式实现它。

您可以使用 k 最近邻的加权平均值、中位数甚至简单平均值来替换缺失值。有几个距离度量可以计算用于查找邻居的不同距离。

现在针对您的问题,这里有一些随着他们的回答而出现的问题。

1.这里考虑了多少个最近的邻居?

默认值为5。您可以通过kpreProcess函数中指定参数来更改它。

2.正在使用哪个距离度量?

在上述情况下,使用欧几里得距离。

3.计算距离的空间的维度是多少?如何找到?

在你的情况下,它是四维空间。它是通过取没有缺失值的列获得的。因此,在您的情况下,它是 column number 2, 3, 4, 5

根据上面的解释,如果您nn在删除NA存储在 中的行后尝试在数据集中找到五个最近的邻居 ( ) preobj$data,您将获得以下索引 ( nn.idx) 和相应的距离 ( nn.dists),如下所示。

> nn
$nn.idx
     [,1] [,2] [,3] [,4] [,5]
[1,]   10    6    5    9    2

$nn.dists
     [,1] [,2]     [,3]     [,4]     [,5]
[1,]    0    0 3.126944 3.126944 3.126944
Run Code Online (Sandbox Code Playgroud)

4.现在终于如何替换NA值了?

要替换该NA值,只需取与最近索引对应的缺失列中的值的平均值。

> preobj$data
             x      yAlex   yBrandon     yErica    yKaryna
 1: -1.1985775 -0.5527708  1.6583124 -0.5527708 -0.5527708
 2: -0.3745555 -0.5527708 -0.5527708  1.6583124 -0.5527708
 3:  1.2734886  1.6583124 -0.5527708 -0.5527708 -0.5527708
 4: -1.1985775 -0.5527708  1.6583124 -0.5527708 -0.5527708
 5: -0.3745555 -0.5527708 -0.5527708  1.6583124 -0.5527708
 6:  0.4494666 -0.5527708 -0.5527708 -0.5527708  1.6583124
 7:  1.2734886  1.6583124 -0.5527708 -0.5527708 -0.5527708
 8: -1.1985775 -0.5527708  1.6583124 -0.5527708 -0.5527708
 9: -0.3745555 -0.5527708 -0.5527708  1.6583124 -0.5527708
10:  0.4494666 -0.5527708 -0.5527708 -0.5527708  1.6583124
11:  1.2734886  1.6583124 -0.5527708 -0.5527708 -0.5527708

> mean(preobj$data$x[nn$nn.idx])
[1] -0.04494666
Run Code Online (Sandbox Code Playgroud)

你会发现NA在输出中确实被这个值替换了。

> dt3
              x      yAlex   yBrandon     yErica    yKaryna
 1: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
 2: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
 3: -0.04494666 -0.5527708 -0.5527708 -0.5527708  1.6583124
 4:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
 5: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
 6: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
 7:  0.44946657 -0.5527708 -0.5527708 -0.5527708  1.6583124
 8:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
 9: -1.19857753 -0.5527708  1.6583124 -0.5527708 -0.5527708
10: -0.37455548 -0.5527708 -0.5527708  1.6583124 -0.5527708
11:  0.44946657 -0.5527708 -0.5527708 -0.5527708  1.6583124
12:  1.27348863  1.6583124 -0.5527708 -0.5527708 -0.5527708
Run Code Online (Sandbox Code Playgroud)

注意第三行。

要将 的值替换为NA最近邻居的相应值,您可以简单地使用k=1