2017-05-13 5 views
2

Ich benutze LibSVM mit dem Weka in meinem Java-Code. Ich versuche eine Regression zu machen. Unten ist mein Code,Java, weka LibSVM sagt nicht richtig voraus

public static void predict() { 

    try { 
     DataSource sourcePref1 = new DataSource("train_pref2new.arff"); 
     Instances trainData = sourcePref1.getDataSet(); 

     DataSource sourcePref2 = new DataSource("testDatanew.arff"); 
     Instances testData = sourcePref2.getDataSet(); 

     if (trainData.classIndex() == -1) { 
      trainData.setClassIndex(trainData.numAttributes() - 2); 
     } 

     if (testData.classIndex() == -1) { 
      testData.setClassIndex(testData.numAttributes() - 2); 
     } 

     LibSVM svm1 = new LibSVM(); 

     String options = ("-S 3 -K 2 -D 3 -G 1000.0 -R 0.0 -N 0.5 -M 40.0 -C 1.0 -E 0.001 -P 0.1"); 
     String[] optionsArray = options.split(" "); 
     svm1.setOptions(optionsArray); 

     svm1.buildClassifier(trainData); 

     for (int i = 0; i < testData.numInstances(); i++) { 

      double pref1 = svm1.classifyInstance(testData.instance(i));     
      System.out.println("predicted value : " + pref1); 

     } 

    } catch (Exception ex) { 
     Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

Aber der vorhergesagte Wert ich von diesem Code bin immer anders ist als der vorhergesagte Wert I unter Verwendung des Weka GUI bin immer.

Beispiel: Unten finden Sie eine einzelne Testdaten, die ich sowohl für Java-Code und Weka-GUI angegeben habe.

Der Java-Code vorhergesagt den Wert als 1,9064516129032265 während des vorhergesagten Wert des Weka GUI 10,043 ist. Ich verwende den gleichen Trainingsdatensatz und die gleichen Parameter für Java-Code und Weka GUI.

Ich hoffe, Sie verstehen meine Frage.Könnte mir jemand sagen, was ist falsch mit meinem Code?

Antwort

2

Sie verwenden den falschen Algorithmus, um die SVM-Regression durchzuführen. LibSVM wird zur Klassifizierung verwendet. Die gewünschte ist SMOreg, die eine bestimmte SVM für die Regression.

Unten finden Sie ein vollständiges Beispiel, das zeigt, wie SMOreg sowohl mit der Weka Explorer-GUI als auch mit der Java-API verwendet wird. Für Daten verwende ich die Datei cpu.arff, die mit der Weka-Distribution geliefert wird. Beachten Sie, dass ich diese Datei sowohl für das Training als auch für den Test verwende, aber im Idealfall würden Sie separate Datensätze haben.

Mit dem Weka Explorer GUI

  1. Öffnen Sie die WEKA Explorer GUI, klicken Sie auf die Registerkarte Preprocess, klicken Sie auf Open File, und öffnen Sie dann die cpu.arff-Datei, die in Ihrem Weka Verteilung sein sollte. Auf meinem System befindet sich die Datei unter weka-3-8-1/data/cpu.arff. Das Explorer-Fenster sollte wie folgt aussehen:

Weka Explorer - Choosing the file

  1. Klicken Sie auf die Registerkarte Classify. Es sollte wirklich "Vorhersage" genannt werden, weil Sie hier sowohl Klassifizierung als auch Regression durchführen können. Unter Classifier, klicken Sie auf Choose und wählen Sie dann weka ->classifiers ->functions ->SMOreg, wie unten gezeigt.

Weka Explorer - Choosing the regression algorithm

  1. nun das Regressionsmodell bauen und bewerten. Unter wählen Sie Use training set, so dass unser Trainingssatz auch zum Testen verwendet wird (wie oben erwähnt, ist dies nicht die ideale Methode). Drücken Sie nun Start, und das Ergebnis sollte wie folgt aussehen:

Weka Explorer - Results from testing

Notieren Sie den RMSE-Wert (74,5996).Wir werden das in der Java-Code-Implementierung noch einmal betrachten.

die API Java verwenden

Nachfolgend finden Sie ein komplettes Java-Programm, das das Weka-API verwendet die Ergebnisse gezeigt früher in der Weka Explorer GUI zu replizieren.

Ich habe zwei Funktionen geschrieben, die ein SMOreg-Modell trainieren und das Modell durch Ausführen einer Vorhersage für die Trainingsdaten evaluieren.

  • buildAndEvaluate() wertet das Modell durch die Weka Evaluation Rahmen mit einer Reihe von Tests ausführen, um die exakt gleichen Ergebnisse wie die Explorer GUI zu bekommen. Bemerkenswerterweise erzeugt es einen RMSE-Wert.

  • buildAndTestEachInstance() wertet das Modell durch explizite über jede Testinstanz Looping, eine Vorhersage zu machen, die Berechnung die Fehler und Berechnen einen Gesamt RMSE. Beachten Sie, dass dieser RMSE mit demjenigen von buildAndEvaluate() übereinstimmt, der wiederum mit dem vom Explorer-GUI übereinstimmt.

Unten ist das Ergebnis der Kompilierung und Ausführung des Programms.

prompt> javac -cp weka.jar Tester.java 

prompt> java -cp .:weka.jar Tester 

buildAndEvaluate() called. 
Options used: 
-C 1.0 -N 0 -I weka.classifiers.functions.supportVector.RegSMOImproved -T 0.001 -V -P 1.0E-12 -L 0.001 -W 1 -K weka.classifiers.functions.supportVector.PolyKernel -E 1.0 -C 250007 

Algorithm: 
SMOreg 

weights (not support vectors): 
+  0.01 * (normalized) MYCT 
+  0.4321 * (normalized) MMIN 
+  0.1847 * (normalized) MMAX 
+  0.1175 * (normalized) CACH 
+  0.0973 * (normalized) CHMIN 
+  0.0235 * (normalized) CHMAX 
-  0.0168 



Number of kernel evaluations: 21945 (93.081% cached) 

Results 
===== 

Correlation coefficient     0.9044 
Mean absolute error      31.7392 
Root mean squared error     74.5996 
Relative absolute error     33.0908 % 
Root relative squared error    46.4953 % 
Total Number of Instances    209  

buildAndTestEachInstance() called. 
RMSE = 74.59964 
+0

Eigentlich Libsvm hat 2 SVM-Typen für Regression, Nu-SVR und Epsilon-SVR. Ich kann entscheiden, welcher SVM-Typ verwendet werden soll, indem ich den -S-Parameter des Algorithmus definiere. In meinem Code habe ich den epsilon-SVR (-S 3) verwendet. Aber Ihr Code hat mir wirklich geholfen, den Fehler in meinem Code zu finden. setClassIndex ist falsch in meinem Code. Ich habe deinen Code benutzt und es hat funktioniert. Vielen Dank für Ihre Hilfe. – udi