2013-06-01 22 views
9

próbuję uruchomić tę linię:Błąd z funkcją KNN

knn(mydades.training[,-7],mydades.test[,-7],mydades.training[,7],k=5) 

ale zawsze ten błąd:

Error in knn(mydades.training[, -7], mydades.test[, -7], mydades.training[, : 
    NA/NaN/Inf in foreign function call (arg 6) 
In addition: Warning messages: 
1: In knn(mydades.training[, -7], mydades.test[, -7], mydades.training[, : 
    NAs introduced by coercion 
2: In knn(mydades.training[, -7], mydades.test[, -7], mydades.training[, : 
    NAs introduced by coercion 

pomysł, proszę?

PS: mydades.training i mydades.test są zdefiniowane następująco:

N <- nrow(mydades) 
permut <- sample(c(1:N),N,replace=FALSE) 
ord <- order(permut) 
mydades.shuffled <- mydades[ord,] 
prop.train <- 1/3 
NOMBRE <- round(prop.train*N) 
mydades.training <- mydades.shuffled[1:NOMBRE,] 
mydades.test <- mydades.shuffled[(NOMBRE+1):N,] 
+0

Czy możesz podać dane fikcyjne, abyśmy mogli sami spróbować odtworzyć błąd? Byłoby to niezwykle pomocne, ponieważ pomimo podania błędu, mój francuski jest po prostu OK (i jeśli uda nam się odtworzyć błąd, możemy uzyskać angielskie oświadczenie o błędzie, które będzie bardziej prawdopodobne, że zwróci wyniki z Google). . –

+0

Byłoby pomocne, gdybyś mógł również dostarczyć mały, fałszywy zestaw danych dla 'mydades', o którym wiesz, że odtwarza ten błąd. –

Odpowiedz

17

Podejrzewam, że problem tkwi w konieczności non-numeryczne pola danych w 'mydades. Linia błędu:

NA/NaN/Inf in foreign function call (arg 6) 

sprawia, że ​​podejrzewam, że wywołanie funkcji knn w implementacji języka C kończy się niepowodzeniem. Wiele funkcji w R faktycznie nazywa podstawowe, bardziej wydajne implementacje C, zamiast posiadania algorytmu zaimplementowanego tylko w R. Jeśli wpiszesz tylko "knn" w konsoli R, możesz sprawdzić implementację R 'knn'. Istnieje następujący wiersz:

Z <- .C(VR_knn, as.integer(k), as.integer(l), as.integer(ntr), 
     as.integer(nte), as.integer(p), as.double(train), as.integer(unclass(clf)), 
     as.double(test), res = integer(nte), pr = double(nte), 
     integer(nc + 1), as.integer(nc), as.integer(FALSE), as.integer(use.all)) 

gdzie .C oznacza, że ​​mamy wywołanie funkcji C o nazwie „VR_knn” z dostarczonych argumentów funkcji. Ponieważ masz dwa z tych błędów: Uważam, że dwa wywołania as.double/as.integer kończą się niepowodzeniem i wprowadzają wartości NA. Jeśli zaczniemy odliczanie parametry, 6. argumentem jest:

as.double(train) 

że może się nie udać w przypadkach takich jak:

# as.double can not translate text fields to doubles, they are coerced to NA-values: 
> as.double("sometext") 
[1] NA 
Warning message: 
NAs introduced by coercion 
# while the following text is cast to double without an error: 
> as.double("1.23") 
[1] 1.23 

dostać dwa błędy przymusu, które są prawdopodobnie podanych przez „jako. double (train) "i" as.double (test) ". Ponieważ nie udało nam dokładne szczegóły dotyczące „mydades” jest, oto niektóre z moich najlepszych prób (i sztucznym wielowymiarowych normalnych danych dystrybucyjnych):

library(MASS) 
mydades <- mvrnorm(100, mu=c(1:6), Sigma=matrix(1:36, ncol=6)) 
mydades <- cbind(mydades, sample(LETTERS[1:5], 100, replace=TRUE)) 

# This breaks knn 
mydades[3,4] <- Inf 
# This breaks knn 
mydades[4,3] <- -Inf 
# These, however, do not introduce the coercion for NA-values error message 

# This breaks knn and gives the same error; just some raw text 
mydades[1,2] <- mydades[50,1] <- "foo" 
mydades[100,3] <- "bar" 

# ... or perhaps wrongly formatted exponential numbers? 
mydades[1,1] <- "2.34EXP-05" 

# ... or wrong decimal symbol? 
mydades[3,3] <- "1,23" 
# should be 1.23, as R uses '.' as decimal symbol and not ',' 

# ... or most likely a whole column is non-numeric, since the error is given twice (as.double problem both in training AND test set) 
mydades[,1] <- sample(letters[1:5],100,replace=TRUE) 

Nie przechowywać zarówno dane liczbowe i klasa etykiety w pojedynczej macierzy, może mógłbyś podzielić dane jak:

mydadesnumeric <- mydades[,1:6] # 6 first columns 
mydadesclasses <- mydades[,7] 

Korzystanie połączeń

str(mydades); summary(mydades) 

może również pomóc nam w zlokalizowaniu/problematyczne zapisy danych i cO popraw je na wpisy numeryczne lub pomiń pola nienumeryczne.

Reszta kodu run (po zerwaniu danych), określonych przez użytkownika:

N <- nrow(mydades) 
permut <- sample(c(1:N),N,replace=FALSE) 
ord <- order(permut) 
mydades.shuffled <- mydades[ord,] 
prop.train <- 1/3 
NOMBRE <- round(prop.train*N) 
mydades.training <- mydades.shuffled[1:NOMBRE,] 
mydades.test <- mydades.shuffled[(NOMBRE+1):N,] 

# 7th column seems to be the class labels 
knn(train=mydades.training[,-7],test=mydades.test[,-7],mydades.training[,7],k=5) 
10

Świetna odpowiedź przez @ Teemu.

Ponieważ jest to dobrze przeczytane pytanie, udzielę tej samej odpowiedzi z perspektywy analitycznej.

Funkcja KNN klasyfikuje punkty danych, obliczając odległość euklidesową między punktami. To matematyczne obliczenie wymagające liczb. Wszystkie zmienne w KNN muszą więc być zdolne do wymiany danych liczbowych.

Preparat Dane KNN często obejmuje trzy zadania:
(1) ustala wszystkie NA lub „” wartości
(2) Konwersja wszystkich czynników zestawu logicznych, jednej na każdy poziom czynnika
(3) Normalizuj wartości każdej zmiennej do zakresu 0: 1, aby żaden zakres zmiennej nie miał nadmiernie dużego wpływu na pomiar odległości.

0

Chciałbym również zwrócić uwagę, że funkcja wydaje się nie udać, gdy używa się liczb całkowitych. Musiałem przekształcić wszystko na "num" przed wywołaniem funkcji knn. Obejmuje to funkcję docelową, którą większość metod w R używa typu czynnika. Zatem wymagany jest znak.numeryczny (my_frame $ target_feature).