2016-08-13 3 views
1

Weiß jemand, warum der unten KNN R Code verschiedene Vorhersagen für verschiedene Samen gibt? Dies ist seltsam wie K < -5, und somit ist die Mehrheit gut definiert. Außerdem sind die Floating-Zahlen groß - so entsteht keine Genauigkeit des Datenproblems (wie in dieser post).Q: KNN in R - seltsames Verhalten

library(class) 

set.seed(642002713) 
m = 20 
n = 1000 
from = -(2^30) 
to = -(from) 
train = matrix(runif(m*n, from, to), nrow=m, ncol=n) 
trainLabels = sample.int(2, size = m, replace=T)-1 
test = matrix(runif(n, from, to), nrow=1) 

K <- 5 

seed <- 544336746 
set.seed(seed) 
pred_1 <- knn(train=train, test=test, cl = trainLabels, k=K) 
message("predicted: ", pred_1, ", seed: ", seed) 
#predicted: 0, seed: 544336746 

seed <- 621513172 
set.seed(seed) 
pred_2 <- knn(train=train, test=test, cl = trainLabels, k=K) 
message("predicted: ", pred_2, ", seed: ", seed) 
#predicted: 1, seed: 621513172 

Eine manuelle Überprüfung:

euc.dist <- function(x1, x2) sqrt(sum((x1 - x2)^2)) 
result = vector(mode="numeric", length=nrow(train)) 
for(i in 1:nrow(train)) { 
    result[i] <- euc.dist(train[i,], test) 
} 
a <- data.frame(result, trainLabels) 
names(a) = c("RSSE", "labels") 
b <- a[with(a, order(sums, decreasing =T)), ] 
headK <- head(b, K) 
message("Manual predicted K: ", paste(K," class:", names(which.max(table(headK[,2]))))) 
#Manual predicted K: 5 class: 1 

würde die Vorhersage 1, mit dem Top K (= 5) RSSE:

RSSE    labels 
28479706980  1 
28472893026  0 
28063242772  1 
27966740954  1 
27927401005  1 

so wird mehrheitlich gut definiert + kein Problem kleiner Float-Unterschied in RSSE.

+0

Ziemlich interessant: Gehen Sie, um einige Ideen zu testen - Daten sind nicht skaliert und zentriert. Bleibt es bestehen, wenn Sie sie vorverarbeiten? Versuchen Sie kNN aus 'Caret' Paket. wenn es weitergeht ... Ich werde es testen, wenn ich nach Hause komme –

+0

Es gibt nichts stochastischen im R-Code für 'knn()', so dass der Unterschied in der C-Routine 'VR_knn()' in 'class.c sein muss 'das wird dadurch aufgerufen. –

Antwort

0

Wenn ich die Daten skaliere und zentriere - einschließlich Testset!, dann bekomme ich beide Prognosen 0.

Meine Vorverarbeitung:

sc<-function(x){(x-mean(x))/sd(x)} 
train<-apply(train,1,sc) 
train<-t(train) 
test<-apply(test,1,sc) 
test<-t(test) 

und erhalten:

> seed <- 544336746 
> pred_1 <- knn(train=train, test=test, cl = trainLabels, k=K) 
> message("predicted: ", pred_1, ", seed: ", seed) 
predicted: 0, seed: 544336746 

> seed <- 621513172 
> pred_2 <- knn(train=train, test=test, cl = trainLabels, k=K) 
> message("predicted: ", pred_2, ", seed: ", seed) 
predicted: 0, seed: 621513172 

manuelle Überprüfung, die ich auf diese Form

a <- data.frame(result, trainLabels) 
names(a) = c("RSSE", "labels") 
b <- a[with(a, order(a$RSSE)), ] 
headK <- head(b, K) 
message("Manual predicted K: ", paste(K," class:", names(which.max(table(headK[,2]))))) 
Manual predicted K: 5 class: 0 

und Ergebnisse bearbeitet :

 RSSE labels 
3 43.48199  0 
17 43.61283  1 
7 43.63948  1 
8 43.69730  0 
19 43.78931  0  
6 43.88009  0 
+0

Danke. (1) Wenn ich den Code "manuelle Prüfung" auf den skalierten und zentrierten Daten, die Sie erstellt haben, ausgeführt habe, bekam ich eine vorhergesagte "Klasse: 1" - während Sie "Klasse 0" bekamen - seltsam; (2) Sind Sie sicher, dass vor der Verwendung von KNN skaliert und zentriert werden muss? – erans

+0

Ich denke, du musst: <-apply trainieren (Zug, ** 2 **, sc) und entfernen: Zug <-t (Zug). Dann erhalten Sie die vorhergesagte Klasse 1, die der manuellen Prüfung entspricht. – erans

+0

Nun mit der Skalierung ist es mehrdeutig, wie sie darüber [hier] sprechen (http://stats.stackexchange.com/questions/121886/when-should-i-apply-feature-scaling-for-my-data). Aber zum Beispiel mein Lehrer Prof. Gorban sagte immer skalieren .... auch Ihre Daten könnten anders sein, weil 'set.seed' würde nicht für die zweite zufällige Verlosung für die Testdaten gelten, so dass wir verschiedene Testdaten haben ..if Ich setze den Startwert auf 5, bevor ich einen Test aus 'runf' zeichne, dann bekomme ich wieder Klasse 0 ... Ich dachte, du wärst hauptsächlich nach Konsistenz von kNN ... –