Suche…


Einführung

Dieses Tutorial zeigt Ihnen, wie Sie Weka in JAVA-Code verwenden, Datendateien laden, Klassifizierer trainieren und einige wichtige Konzepte des maschinellen Lernens erklären.

Weka ist ein Toolkit für maschinelles Lernen. Es enthält eine Bibliothek mit maschinellem Lernen und Visualisierungstechniken sowie eine benutzerfreundliche grafische Benutzeroberfläche.

Dieses Tutorial enthält Beispiele, die in JAVA geschrieben sind, und enthält mit der GUI erstellte Grafiken. Ich empfehle die Verwendung der GUI zur Untersuchung von Daten und JAVA-Code für strukturierte Experimente.

Erste Schritte: Laden eines Datensatzes aus einer Datei

Der Iris-Blumendatensatz ist ein weit verbreiteter Datensatz zu Demonstrationszwecken. Wir werden es laden, inspizieren und für den späteren Gebrauch leicht modifizieren.

import java.io.File;
import java.net.URL;
import weka.core.Instances;
import weka.core.converters.ArffSaver;
import weka.core.converters.CSVLoader;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.RenameAttribute;
import weka.classifiers.evaluation.Evaluation;
import weka.classifiers.rules.ZeroR;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.lazy.IBk;
import weka.classifiers.trees.J48;
import weka.classifiers.meta.AdaBoostM1;

public class IrisExperiments {
    public static void main(String args[]) throws Exception
     {
        //First we open stream to a data set as provided on http://archive.ics.uci.edu
         CSVLoader loader = new CSVLoader();
         loader.setSource(new URL("http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data").openStream());
         Instances data = loader.getDataSet();
         
         //This file has 149 examples with 5 attributes
         //In order:
         //  sepal length in cm
         //  sepal width in cm
         //  petal length in cm 
         //  petal width in cm
         //  class ( Iris Setosa , Iris Versicolour, Iris Virginica)

         //Let's briefly inspect the data
         System.out.println("This file has " + data.numInstances()+" examples.");
         System.out.println("The first example looks like this: ");
         for(int i = 0; i < data.instance(0).numAttributes();i++ ){
             System.out.println(data.instance(0).attribute(i));
         } 
         
         // NOTE that the last attribute is Nominal
         // It is convention to have a nominal variable at the last index as target variable
         
         // Let's tidy up the data a little bit
         // Nothing too serious just to show how we can manipulate the data with filters
         RenameAttribute renamer = new RenameAttribute();
         renamer.setOptions(weka.core.Utils.splitOptions("-R last -replace Iris-type"));
         renamer.setInputFormat(data);                          
         data = Filter.useFilter(data, renamer); 
         
         System.out.println("We changed the name of the target class.");
         System.out.println("And now it looks like this:");
         System.out.println(data.instance(0).attribute(4));
         
         //Now we do this for all the attributes
         renamer.setOptions(weka.core.Utils.splitOptions("-R 1 -replace sepal-length"));
         renamer.setInputFormat(data);                          
         data = Filter.useFilter(data, renamer); 
         
         renamer.setOptions(weka.core.Utils.splitOptions("-R 2 -replace sepal-width"));
         renamer.setInputFormat(data);                          
         data = Filter.useFilter(data, renamer); 
         
         renamer.setOptions(weka.core.Utils.splitOptions("-R 3 -replace petal-length"));
         renamer.setInputFormat(data);                          
         data = Filter.useFilter(data, renamer); 
         
         renamer.setOptions(weka.core.Utils.splitOptions("-R 4 -replace petal-width"));
         renamer.setInputFormat(data);                          
         data = Filter.useFilter(data, renamer); 
         
         //Lastly we save our newly created file to disk
         ArffSaver saver = new ArffSaver();
         saver.setInstances(data);
         saver.setFile(new File("IrisSet.arff"));
         saver.writeBatch();
  }
}

Trainieren Sie den ersten Klassifikator: Festlegen einer Basislinie mit ZeroR

ZeroR ist ein einfacher Klassifizierer. Es wird nicht pro Instanz ausgeführt, sondern es erfolgt eine allgemeine Verteilung der Klassen. Es wählt die Klasse mit der größten Wahrscheinlichkeit a priori aus. Es ist kein guter Klassifizierer in dem Sinne, dass er keine Informationen im Kandidaten verwendet, aber er wird oft als Basiswert verwendet. Hinweis: Andere Basislinien können wie folgt verwendet werden: Industriestandard-Klassifizierer oder handgefertigte Regeln

 // First we tell our data that it's class is hidden in the last attribute
 data.setClassIndex(data.numAttributes() -1);
 // Then we split the data in to two sets
 // randomize first because we don't want unequal distributions
 data.randomize(new java.util.Random(0));
 Instances testset = new Instances(data, 0, 50);
 Instances trainset = new Instances(data, 50, 99);
 
 // Now we build a classifier
 // Train it with the trainset
 ZeroR classifier1 = new ZeroR();
 classifier1.buildClassifier(trainset);
 // Next we test it against the testset
 Evaluation Test = new Evaluation(trainset);
 Test.evaluateModel(classifier1, testset);
 System.out.println(Test.toSummaryString());

Die größte Klasse im Set bietet eine korrekte Rate von 34%. (50 von 149)

Die tatsächliche Verteilung der Klassen im Satz

Hinweis: Der ZeroR ist rund 30% leistungsfähig. Dies liegt daran, dass wir uns zufällig in ein Zug- und Test-Set aufgeteilt haben. Der größte Satz im Zugsatz ist somit der kleinste im Testsatz. Das Erstellen eines guten Test- / Zugsatzes kann sich lohnen

Ein Gefühl für die Daten bekommen. Naive Bayes und KNN trainieren

Um einen guten Klassifizierer zu erstellen, müssen wir oft eine Vorstellung davon bekommen, wie die Daten im Merkmalsraum strukturiert werden. Weka bietet ein Visualisierungsmodul, das helfen kann.

Diagramme mit 2 Dimensionen, Klassen sind eingefärbt

Einige Dimensionen trennen die Klassen bereits recht gut. Blütenblattbreite ordnet das Konzept recht ordentlich an, beispielsweise im Vergleich zur Blütenblattbreite.

Das Training einfacher Klassifikatoren kann auch einige Informationen über die Struktur der Daten liefern. Normalerweise verwende ich gerne Nearest Neighbor und Naive Bayes für diesen Zweck. Naive Bayes geht von Unabhängigkeit aus, es zeigt, dass die Dimensionen in sich Informationen enthalten. k-Nearest-Neighbor funktioniert durch Zuweisen der Klasse der k nächstgelegenen (bekannten) Instanzen im Feature-Space. Es wird häufig verwendet, um die lokale geographische Abhängigkeit zu untersuchen. Wir werden damit prüfen, ob unser Konzept lokal im Merkmalsraum definiert ist.

 //Now we build a Naive Bayes classifier
 NaiveBayes classifier2 = new NaiveBayes();
 classifier2.buildClassifier(trainset);
 // Next we test it against the testset
 Test = new Evaluation(trainset);
 Test.evaluateModel(classifier2, testset);
 System.out.println(Test.toSummaryString());
 
//Now we build a kNN classifier
IBk classifier3 = new IBk();
// We tell the classifier to use the first nearest neighbor as example 
classifier3.setOptions(weka.core.Utils.splitOptions("-K 1"));
classifier3.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier3, testset);
System.out.println(Test.toSummaryString());

Naive Bayes ist wesentlich besser als unsere neu etablierte Basislinie und zeigt an, dass unabhängige Funktionen Informationen enthalten (Blütenblattbreite beachten?).

1NN ist ebenfalls gut (in diesem Fall sogar etwas besser), was darauf hinweist, dass einige unserer Informationen lokal sind. Die bessere Leistung könnte darauf hindeuten, dass einige Effekte zweiter Ordnung auch Informationen enthalten (Wenn x und y als Klasse z) .

Zusammensetzen: Einen Baum trainieren

Bäume können Modelle erstellen, die mit unabhängigen Funktionen und Effekten zweiter Ordnung arbeiten. Sie könnten also gute Kandidaten für diese Domäne sein. Bäume sind zusammengehörende Regeln, eine Regel, die Instanzen aufteilt, die in Untergruppen zu einer Regel gelangen, die an die Regeln der Regel übergeben wird.

Baumlernende erstellen Regeln, ketten sie zusammen und hören auf, Bäume zu bauen, wenn sie der Meinung sind, dass die Regeln zu spezifisch werden, um eine Überanpassung zu vermeiden. Überanpassung bedeutet, ein Modell zu konstruieren, das für das von uns gesuchte Konzept zu komplex ist. Überbeanspruchte Modelle bieten eine gute Leistung bei den Zugdaten, aber bei neuen Daten schlecht

Wir verwenden J48, eine JAVA-Implementierung von C4.5, einen populären Algorithmus.

//We train a tree using J48
//J48 is a JAVA implementation of the C4.5 algorithm
J48 classifier4 = new J48();
//We set it's confidence level to 0.1
//The confidence level tell J48 how specific a rule can be before it gets pruned
classifier4.setOptions(weka.core.Utils.splitOptions("-C 0.1"));
classifier4.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier4, testset);
System.out.println(Test.toSummaryString());

System.out.print(classifier4.toString());

//We set it's confidence level to 0.5
//Allowing the tree to maintain more complex rules
classifier4.setOptions(weka.core.Utils.splitOptions("-C 0.5"));
classifier4.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier4, testset);
System.out.println(Test.toSummaryString());
     
System.out.print(classifier4.toString());

Der mit dem höchsten Selbstbewusstsein trainierte Baumlerner generiert die genauesten Regeln und hat die beste Leistung im Testgerät. Offenbar ist die Spezifität geboten.

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Hinweis: Beide Lernenden beginnen mit einer Regel für die Blütenblattbreite. Erinnern Sie sich, wie wir diese Dimension in der Visualisierung bemerkt haben?



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow