2012-08-28 18 views
14

Zacznę od stwierdzenia, że ​​nie mam żadnego doświadczenia z R, KNN lub nauką o danych w ogóle. Ostatnio znalazłem Kaggle i bawiłem się konkursem/tutorialem Digit Recognition.Jak wyświetlić najbliższych sąsiadów w R?

W tym tutorialu one dostarczyć przykładowy kod, aby uzyskać początek z podstawowych wniosków:

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

Moje pytania to:

  1. Jak mogę wyświetlić najbliższych sąsiadów, które zostały wybrane do a konkretny wiersz testowy?
  2. Jak mogę zmienić, która z tych dziesięciu jest wybrana dla mojego results?

Te pytania mogą być zbyt ogólne. Jeśli tak, chciałbym powitać wszystkie linki, które mogłyby wskazać mi właściwą drogę.

Jest możliwe, że powiedziałem coś, co nie ma sensu. W takim przypadku popraw mnie.

Odpowiedz

23

1) Można dostać najbliższych sąsiadów danym rzędzie tak:

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

Następnie, jeśli chcesz indeksy 10 najbliższych sąsiadów do wiersza 20 w zbiorze treningowym:

print(indices[20, ]) 

(Otrzymasz 10 najbliższych sąsiadów, ponieważ wybrałeś k=10). Na przykład, jeśli uruchomić tylko 1000 pierwszych rzędach treningowego i testowego zestawu (aby obliczeniowo łatwiej):

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 

Są to wskaźniki w zbiorze treningowym 1000, które są najbliżej do 20. rzędu zestawu testowego.

2) To zależy od tego, co masz na myśli przez "modyfikuj". Na początek, można uzyskać indeksy każdego z 10 najbliższymi etykiet do każdego wiersza tak:

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

Można wtedy zobaczyć etykiety z 10 najbliższymi punktami na 20. miejscu treningowym tak:

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

Oznacza to, że wszystkie 10 punktów znajdujących się najbliżej wiersza 20 znajduje się w grupie oznaczonej jako 0. knn po prostu wybiera etykietę większością głosów (losowo zerwane krawędzie), ale można wybrać jakiś schemat ważenia, jeśli ty preferujesz.

ETA: Jeśli jesteś zainteresowany ważenie bliższych elementy w większym stopniu w systemie głosowania, trzeba pamiętać, że można również uzyskać dystans do siebie sąsiadów k tak:

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

Doskonała odpowiedź, dziękuję ty! Miałem kilka pytań. Za każdym razem, gdy próbuję wydrukować 'indeksy', zwraca ona wartość null, czy powinienem robić coś innego niż twój przykład? Czy możesz polecić jakieś zasoby, aby dowiedzieć się więcej na temat tworzenia niestandardowego schematu ważenia? Albo przykłady kogoś, kto tworzy taki, na który mogę patrzeć? –

+0

To bardzo dziwne.Co otrzymasz, jeśli zrobisz "print (k)"? Jeśli chodzi o inne systemy ważenia - miałbyś tyle szczęścia, ile szukałbym w Google słowa "KNN ważony". Ale piszę trochę więcej o wadze w mojej odpowiedzi. –

+0

Ok, więc aby wyjaśnić, używam 'wyników' zamiast' k'. Zakładam, że to nie ma znaczenia, ale pomyślałem, że powinienem po prostu to tam rzucić. Kiedy robię 'print (wyniki)' To wypisuje 1000 elementów, które są ostatecznie zapisywane do mojego pliku csv. –

Powiązane problemy