2016-12-07 64 views
2

我有以下data.table,其中每個唯一的x值與唯一的y值相關聯。於是我強迫一個x價值NA第k近鄰鍛鍊的目的:knnImpute使用分類變量與插入符號包

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?如果是這樣,我需要在腳本中更改哪些內容?如果不是,爲什麼?

回答

3

要了解發生了什麼事情,首先需要了解caret包的工作原理preProcess中的方法knnImpute的工作方式。各種風格的k-最近的鄰居插補是可用的,不同的人在不同的軟件包中以不同的方式實現它。

您可以使用加權平均數,中位數或甚至簡單平均值來替換缺失值。有幾個距離度量來計算找到鄰居的不同距離。

現在具體到你的問題這裏是一些問題,他們的答案出現了。

1.這裏最近的鄰居有多少?

默認爲。您可以通過在preProcess函數中指定參數k來更改它。

2.正在使用哪個距離度量?

在上述情況下使用歐幾里得距離。

3.計算距離的距離和發現距離的尺寸是多少?

在你的情況下,它是四維空間。它是通過獲取沒有缺失值的列獲得的。因此在你的情況下,它的列號是2, 3, 4, 5

基於上述的解釋,如果你嘗試刪除存儲在preobj$dataNA行後,發現在數據集中的五個最近的鄰居(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

+0

很好的解釋。對於我的具體情況,我在'preProcess'函數中做了'k = 2',它給了我期望看到的東西。然後,我重新創建了我的'dt'表,並在'preProcess'函數中重複了11次重複並使用'k = 10',並且現在仍然可以得到相同的答案。 – bshelt141