2013-06-01 8 views
9

provo a fare funzionare questa linea:errore con la funzione knn

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

ma ottengo sempre questo errore:

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 

Qualche idea per favore?

PS: mydades.training e mydades.test sono definiti come segue:

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

Potete fornire dati fittizi in modo che possiamo tentare di riprodurre da soli l'errore? Ciò sarebbe estremamente utile poiché, anche se hai fornito l'errore che hai ricevuto, il mio francese è OK (e se possiamo riprodurre l'errore, possiamo ottenere la dichiarazione di errore in inglese, che sarà più propensa a restituire i risultati di Google) . –

+0

Sarebbe d'aiuto se potessi anche fornire un piccolo set di dati fittizio per 'mydades' che sai che riproduce questo errore. –

risposta

17

Ho il sospetto che il problema risiede nell'avere campi dati non numerici in 'mydades'. La riga di errore:

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

mi fa sospettare che la chiamata knn all'implementazione del linguaggio C non riesca. Molte funzioni in R in realtà chiamano implementazioni C sottostanti più efficienti, invece di avere un algoritmo implementato in appena R. Se si digita solo "knn" nella console R, è possibile ispezionare l'implementazione R di "knn". Esiste la seguente riga:

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)) 

dove .C significa che stiamo chiamando una funzione C denominato 'VR_knn' con gli argomenti della funzione forniti. Dato che hai due errori

NAs introduced by coercion 

Penso che due delle chiamate as.double/as.integer falliscano e introducano valori NA. Se cominciamo a contare i parametri, il 6 ° argomento è:

as.double(train) 

che potrebbe non riuscire in casi come:

# 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 

si ottengono due degli errori di coercizione, che probabilmente sono date da 'come. double (train) 'and' as.double (test) '. Dal momento che non ci forniscono i dettagli esatti di come 'mydades' è, qui sono alcuni dei miei migliori congetture (e un dato di distribuzione normale multivariata artificiali):

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) 

non vorrei mantenere sia i dati numerici e di classe etichette in un'unica matrice, forse si potrebbero suddividere i dati come:

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

utilizzando chiamate

str(mydades); summary(mydades) 

può anche aiutare a/noi a localizzare le voci di dati problematici e co riorganizzarli a voci numeriche o omettere campi non numerici.

Il resto del codice di corsa (dopo la rottura dei dati), come previsto da voi:

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

Grande risposta da @ Teemu.

Poiché questa è una domanda ben letta, darò la stessa risposta dal punto di vista dell'analisi.

La funzione KNN classifica i punti dati calcolando la distanza euclidea tra i punti. Questo è un calcolo matematico che richiede numeri. Tutte le variabili in KNN devono quindi essere coercitabili ai valori numerici.

La preparazione dei dati per KNN spesso coinvolge tre compiti:
(1) correggere tutti NA o "" valori
(2) convertire tutti i fattori in una serie di booleani, uno per ogni livello nel fattore
(3) Normalizza i valori di ciascuna variabile nell'intervallo 0: 1 in modo che la gamma di variabili non abbia un impatto eccessivamente grande sulla misurazione della distanza.

0

Vorrei anche sottolineare che la funzione sembra fallire quando si usano gli interi. Avevo bisogno di convertire tutto in "num" prima di chiamare la funzione knn. Ciò include la funzione di destinazione, che la maggior parte dei metodi in R usa il tipo di fattore. Pertanto, as.numeric (my_frame $ target_feature) è richiesto.