2012-08-28 21 views
14

Vorrei iniziare dicendo che non ho esperienza con R, KNN o scienza dei dati in generale. Recentemente ho trovato Kaggle e ho giocato con la competizione/tutorial Digit Recognition.Come visualizzare i vicini più vicini in R?

In questo tutorial che forniscono alcuni esempi di codice per iniziare con una presentazione di base:

# makes the KNN submission 

library(FNN) 

train <- read.csv("c:/Development/data/digits/train.csv", header=TRUE) 
test <- read.csv("c:/Development/data/digits/test.csv", header=TRUE) 

labels <- train[,1] 
train <- train[,-1] 

results <- (0:9)[knn(train, test, labels, k = 10, algorithm="cover_tree")] 

write(results, file="knn_benchmark.csv", ncolumns=1) 

Le mie domande sono:

  1. Come posso visualizzare i vicini più vicini che sono stati selezionati per una riga di prova particolare ?
  2. Come posso modificare quale di questi dieci è selezionato per il mio results?

Queste domande potrebbero essere troppo ampie. In tal caso, accolgo con favore eventuali collegamenti che potrebbero indicarmi la strada giusta.

È molto possibile che ho detto qualcosa che non ha senso qui. Se questo è il caso, per favore correggimi.

risposta

23

1) È possibile ottenere i vicini più prossimi di una data riga in questo modo:

k <- knn(train, test, labels, k = 10, algorithm="cover_tree") 
indices <- attr(k, "nn.index") 

Poi, se si desidera che gli indici dei 10 vicini più prossimi a remare 20 nel training set:

print(indices[20, ]) 

(Otterrai i 10 vicini più vicini perché hai selezionato k=10). Ad esempio, se si esegue con solo le prime 1000 righe del training set e test (per rendere computazionalmente semplice):

train <- read.csv("train.csv", header=TRUE)[1:1000, ] 
test <- read.csv("test.csv", header=TRUE)[1:1000, ] 

labels <- train[,1] 
train <- train[,-1] 

k <- knn(train, test, labels, k = 10, algorithm="cover_tree") 
indices = attr(k, "nn.index") 

print(indices[20, ]) 
# output: 
# [1] 829 539 784 487 293 882 367 268 201 277 

Questi sono gli indici all'interno training set 1000 che sono più vicini alla fila 20 del set di prova.

2) Dipende da cosa intendi per "modifica". Per cominciare, è possibile ottenere gli indici di ciascuna delle 10 etichette più vicini a ogni riga in questo modo:

closest.labels = apply(indices, 2, function(col) labels[col]) 

È quindi possibile vedere le etichette dei 10 punti più vicini al punto di formazione 20 in questo modo:

closest.labels[20, ] 
# [1] 0 0 0 0 0 0 0 0 0 0 

Questo indica che tutti e 10 i punti più vicini della riga 20 sono tutti nel gruppo con l'etichetta 0. knn semplicemente sceglie l'etichetta con il voto di maggioranza (con pareggi interrotti casualmente), ma è possibile scegliere una sorta di schema di ponderazione se preferisci.

ETA: Se siete interessati a ponderare gli elementi più vicini più pesantemente nel vostro schema di votazione, si noti che è anche possibile ottenere le distanze a ciascuno dei vicini k come questo:

dists = attr(k, "nn.dist") 
dists[20, ] 
# output: 
# [1] 1238.777 1243.581 1323.538 1398.060 1503.371 1529.660 1538.128 1609.730 
# [9] 1630.910 1667.014 
+0

risposta meravigliosa, grazie tu! Ho avuto alcune domande. Ogni volta che provo a stampare 'indices' restituisce null, dovrei fare qualcosa di diverso dal tuo esempio? Potete consigliare delle risorse per ulteriori ricerche su come creare uno schema di ponderazione personalizzato? O esempi di qualcuno che ne crea uno che io possa guardare? –

+0

Questo è molto strano.Cosa ottieni se esegui 'print (k)'? Per quanto riguarda gli altri schemi di ponderazione, avresti tanta fortuna quanto vorrei cercare la frase "KNN ponderata" su Google. Ma sto scrivendo un po 'di più sulla ponderazione della mia risposta. –

+0

Ok, quindi per chiarire sto effettivamente usando 'results' invece di' k'. Presumo che questo non faccia la differenza, ma ho pensato che dovrei buttarlo lì. Quando faccio 'print (results)' Stampa i 1000 elementi che sono eventualmente scritti nel mio file csv. –