knnImpute 使用带插入符包的分类变量
knnImpute using categorical variables with caret package
我有以下 data.table,其中每个唯一的 x
值都与一个唯一的 y
值相关联。然后我强制一个 x
值作为 NA
用于 k-最近邻练习:
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
参考 this question 的第一个答案,我从 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
使用 caret
包的 preProcess
函数中的 knnImpute
方法,我希望 dt3[1, 3]
下面的中心缩放输出等于第 7 行和第 12 行。但事实并非如此。事实上,它看起来几乎等于第 7 行和第 12 行的负值。
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
dt3$x
的第 3 行不应该等于第 7 行和第 11 行吗?如果是这样,我需要在脚本中更改什么?如果不是,为什么?
要了解正在发生的事情,您首先需要了解 caret
包的函数 preProcess
中的方法 knnImpute
的工作方式。 k-最近邻插补 有多种形式,不同的人在不同的软件包中以不同的方式实现它。
您可以使用加权平均数、中位数,甚至是 k 最近邻的简单平均数来替换缺失值。有几个距离度量来计算不同的距离以找到邻居。
现在针对您的问题,这里有一些随他们的回答而出现的问题。
1.How这里考虑了很多最近邻?
默认值为 5。您可以通过在 preProcess
函数中指定参数 k
来更改它。
2.Which 正在使用距离度量?
在上面的例子中使用了欧氏距离。
3.What是计算距离的space的维度,它是如何找到的?
在你的例子中,它是四维的 space。它是通过采用没有缺失值的列获得的。因此,在您的情况下,它是列号 2, 3, 4, 5
.
根据上述解释,如果您在删除存储在 preobj$data
中的具有 NA
的行后尝试在数据集中找到五个最近的邻居 ( nn
),您将获得以下索引( 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
4.Now最后如何替换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
你会发现 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
注意第三行。
要将 NA
的值简单地替换为最近邻居的相应值,您可以简单地使用 k=1
.
我有以下 data.table,其中每个唯一的 x
值都与一个唯一的 y
值相关联。然后我强制一个 x
值作为 NA
用于 k-最近邻练习:
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
参考 this question 的第一个答案,我从 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
使用 caret
包的 preProcess
函数中的 knnImpute
方法,我希望 dt3[1, 3]
下面的中心缩放输出等于第 7 行和第 12 行。但事实并非如此。事实上,它看起来几乎等于第 7 行和第 12 行的负值。
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
dt3$x
的第 3 行不应该等于第 7 行和第 11 行吗?如果是这样,我需要在脚本中更改什么?如果不是,为什么?
要了解正在发生的事情,您首先需要了解 caret
包的函数 preProcess
中的方法 knnImpute
的工作方式。 k-最近邻插补 有多种形式,不同的人在不同的软件包中以不同的方式实现它。
您可以使用加权平均数、中位数,甚至是 k 最近邻的简单平均数来替换缺失值。有几个距离度量来计算不同的距离以找到邻居。
现在针对您的问题,这里有一些随他们的回答而出现的问题。
1.How这里考虑了很多最近邻?
默认值为 5。您可以通过在 preProcess
函数中指定参数 k
来更改它。
2.Which 正在使用距离度量?
在上面的例子中使用了欧氏距离。
3.What是计算距离的space的维度,它是如何找到的?
在你的例子中,它是四维的 space。它是通过采用没有缺失值的列获得的。因此,在您的情况下,它是列号 2, 3, 4, 5
.
根据上述解释,如果您在删除存储在 preobj$data
中的具有 NA
的行后尝试在数据集中找到五个最近的邻居 ( nn
),您将获得以下索引( 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
4.Now最后如何替换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
你会发现 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
注意第三行。
要将 NA
的值简单地替换为最近邻居的相应值,您可以简单地使用 k=1
.