2015-07-10 34 views
9

Mam plik csv, gdzie każdy wiersz jest wektorem liczb reprezentujących punkt danych. Chcę użyć weka z wiersza poleceń, aby obliczyć najbliższego sąsiada każdego punktu danych w pliku csv. Wiem, jak wykonać klasyfikację najbliższego sąsiada z wiersza poleceń, ale tego nie chcę. Chcę prawdziwych sąsiadów. Jak mam to zrobic?Jak obliczyć najbliższych sąsiadów za pomocą Weka z wiersza poleceń?

Chcę to zrobić za pomocą Weka, a nie innego narzędzia.

Odpowiedz

5

Weka nie posiada jedną wkładkę do robienia tego, co myślę, że sugeruje (łykać plik, przekształcić ją w przypadkach, a następnie znaleźć wszystkie N najbliższych sąsiadów każdej instancji)

ale można ustawić w stylu linii komend jeden liniowiec, wykorzystując Weka i kilka linii Javy w następujący sposób:

Skompiluj następujący kod. Użyłem Eclipse, ale równie dobrze możesz użyć javac z linii poleceń - upewnij się, że masz weka.jar w swojej ścieżce klas. Pokażę wam przykład jak zadzwonić to jako jedną wkładką z linii cammand po kodzie poniżej

import weka.core.Instances; 
import weka.core.converters.ConverterUtils.DataSource; 
import weka.core.neighboursearch.LinearNNSearch; 

public class WekaCLFindNN { 
    public static void main(String[] args) throws Exception { 

      //report that the code is running 
      System.out.println("Weka Command Line Find Nearest " + args[0] + " Neighbors for each Instance in " + args[1]); // Display the string. 

      //setup datasources, grab instances, and calculate the nearest neighbors 
      DataSource source = new DataSource(""+args[1]); 
      Instances instances = source.getDataSet(); 
      weka.core.neighboursearch.LinearNNSearch knn = new LinearNNSearch(instances); 

      //cycle through the dataset and get instances for the nearestneighbors 
      for(int j=0;j<instances.numInstances();j++){ 
      Instances nearestInstances= knn.kNearestNeighbours(instances.instance(j), Integer.parseInt(args[0])); 

      //cycle through the instances and printout the nearestneighbors 
      System.out.println("\n\n" + instances.instance(j)); 
      for(int i =0;i<Integer.parseInt(args[0]);i++) 
      { 
       System.out.println("\n\t" + nearestInstances.instance(i)); 

      } 

      } 

      //close the code 
      System.out.println("\n"+"Nearest Neighbors found"); // Display the string. 

    } 
} 

Teraz wystarczy uruchomić go z linii poleceń przy użyciu następującego polecenia.

java -cp weka.jar ;. WekaCLFindNN numNNcsvfile

tu jest zrzut ekranu z nim pracować na moim komputerze. Zauważ, że mam plik weka.jar i plik WekaCLFindNN w katalogu, w którym się znajduję, gdy uruchamiam java. Należy również pamiętać, że używam tego pod Windows, gdzie separater ścieżka klasy jest średnik (;), jeśli zostały uruchomione to pod Linuksem trzeba by użyć dwukropka (:)

weka working from command line

można zignorować część o sterowniku bazy danych to tylko Weka wyrzucając coś na stderr. ale jak widzisz, wektory są wyrównane do lewej, a ich najbliżsi sąsiedzi są wypisani tak, jak prosiłeś.

jeśli chcesz dane w pliku dziennika po prostu wykonać to w ten sposób

java cp weka.jar ;. WekaCLFindNN> outputlog

plik dziennika będzie wyglądać, i zauważyć, że nie ma błędów na temat bazy danych:

outputlog

Chociaż byłoby miło mieć zarówno najbliższych sąsiadów i ich indeks w oryginalnym zestawie danych instancji, sprawdziłem metodę kNearestNeighbours i odkryłem, że dane indeksu są wyrzucane tuż przed raportowaniem. Jeśli chcesz, to będziesz musiał dziedziczyć klasę LinearNNSearch i napisać nową metodę, która wyświetli zarówno instancje, jak i indeksy.

Mam nadzieję, że to pomoże. Szkoda, że ​​Weka nie oferuje tego po wyjęciu z pudełka, ale można to zrobić za pomocą zaledwie kilku linii kodu.