2016-08-29 4 views
-1

Könnte mir jemand zeigen, wie man ein-Klasse SVM in Java zu verwenden? Mein Problem ist, ich habe ein Trainings-Dataset und ein Test-Set und ich möchte ein Klassen-SVM verwenden, um den Klassenwert vorherzusagen. Ich habe ein paar Beispiele auf GitHub versucht, aber sie haben nicht für mich funktioniert.eine Klasse Svm in Java

public static void main(String[] args){  
    DefaultDataset trainingSet = new DefaultDataset(); 
    LibSVM svmClassifier = new LibSVM(); 
    svm_parameter svmParam = new svm_parameter(); 
    svmParam.svm_type = svm_parameter.ONE_CLASS; //set one_class 
    svmParam.kernel_type = svm_parameter.LINEAR; // set type of kernel function 
    svmClassifier.setParameters(svmParam); 
    OneClassSVMTest oneClassSVM = new OneClassSVMTest(); 
    NormalizeMidrange normalizMid = new NormalizeMidrange(); 

    //loadValues loads data from mysql-db 
    //Double[] contains x,y,z values for example [0.123, 1.232, 0.342] 
    ArrayList<Double[]> myTrainValues = oneClassSVM.loadValues(myString1); 
    ArrayList<Double[]> myTestValue = oneClassSVM.loadValues(myString2); 
    for(Double[] value : myTrainValues) 
    { 
     //toRawArray converts Double[] to double[] 
     trainingSet.add(new DenseInstance(toRawArray(value)); 
    } 
    normalizMid.build(trainingSet); 
    normalizMid.filter(trainingSet); 
    svmClassifier.buildClassifier(trainingSet); 

    int correct = 0, wrong = 0; 
    for (Double[] d : myTestValues) 
    { 
     Instance inst = new DenseInstance(toRawArray(d)); 
     normalizMid.filter(inst); 
     //is always null !?!? 
     Object predictedClassValue = svmClassifier.classify(inst); 
     //is always null !?!? 
     Object realClassValue = inst.classValue(); 
     if (predictedClassValue.equals(realClassValue)) //<- Error shows up 
      correct++; 
     else 
      wrong++; 
    } 
    System.out.printf("correct: %d, wrong: %d%n", correct, wrong); 
} 

Als Ergebnis erhalte ich java.lang.NullPointerException weil svmClassifier.classify(inst) und inst.classValue() immer null zurückzukehren. Also habe ich versucht, etwas anderes:

Map<Object, Double> classDistributionMap; 
    for (Double[] a : myTestValue) 
    { 
     Instance inst = new DenseInstance(toRawArray(a)); 
     normalizMid.filter(inst); 
     classDistributionMap = svmClassifier.classDistribution(inst); 
     Set<Map.Entry<Object, Double>> entrySet = classDistributionMap.entrySet(); 
     for (Entry<Object, Double> entry : entrySet) 
      System.out.println(entry.getValue()); 

    } 

Als Ergebnisse nur 1.0. Ich kann nicht erklären, warum nur gibt es 1.0

+0

Welche Bibliothek verwenden Sie? kannst du bitte einen Zeiger hinzufügen. – Kai

Antwort

0

Die SVM-Klassifikator Funktion

y = f (x)

wobei y = {1, -1} y = 1,0 bedeutet, Daten zu der Klasse gehören, und -1.0 bedeutet, dass Daten zu einer anderen Klasse gehören.

x ist der Vektor von 1 durch n wobei n = Anzahl der Attribute jedes Datensatzes wo ist die Klasse der Daten. Aus dem Obigen kann es bedeuten, dass alle Daten in die gleiche Klasse wie die erwartete Klasse klassifiziert sind, die 1,0; Daten, die zu einer anderen Klasse gehören, sind -1.0.

Also, aus Ihrer Beobachtung, könnte es bedeuten, dass die Datensätze alle in die gleiche Klasse eingestuft werden

+0

Vielen Dank für die Erklärung. Kannst du mir etwas über die "NullpointerException" im obigen Code erzählen? – Bob

+0

NullPointerException tritt auf, wenn dem Abfrageobjekt kein Wert zugewiesen ist. Sie müssen den Rückgabetyp dieser Methode kennen oder besser noch die Dokumentation des Methodenaufrufs lesen. Dies wird Ihnen helfen zu wissen, was sie zurückgeben sollen. Meistens muss es sein, dass Sie den classValue über eine get-Methode in der libSvm bereitstellen müssen. Wenn der Wert vor der Abfrage nicht angegeben wird, führt dies zu NullPointerException. – Positive