2017-01-30 1 views
1

Ich habe ein Programm, das einen Algorithmus mit einem 2-Klassen-kategorischen Ergebnis trainiert, dann Vorhersagen (Wahrscheinlichkeiten jeder der 2 Klassen) für einen unmarkierten Datensatz ausführt und ausgibt.Korrekte Kennzeichnung vorhergesagter Klassen bei Verwendung der Java-WEKA-Bibliothek

Alle Datensätze, die für dieses Programm ausgeführt werden, haben die gleichen 2 Klassen wie das Ergebnis. Vor diesem Hintergrund lief ich die Vorhersagen und verwendet, um eine kleine Post-hoc-Statistiken, um herauszufinden, welche Spalte der Ergebnisse beschrieben, die Ergebnisse, und fuhr fort, hart zu codieren sie:

public class runPredictions { 
public static void runPredictions(ArrayList al2) throws IOException, Exception{ 
    // Retrieve objects 
    Instances newTest = (Instances) al2.get(0); 
    Classifier clf = (Classifier) al2.get(1); 

    // Print status 
    System.out.println("Generating predictions..."); 

    // create copy 
    Instances labeled = new Instances(newTest); 

    BufferedWriter outFile = new BufferedWriter(new FileWriter("silverbullet_rro_output.csv")); 
    StringBuilder builder = new StringBuilder(); 

    builder.append("Prob_Retain"+","+"Prob_Attrite"+"\n"); 
    for (int i = 0; i < labeled.size(); i++)  
    { 
     double[] clsLabel = clf.distributionForInstance(newTest.instance(i)); 
     for(int j=0;j<2;j++){ 
      builder.append(clsLabel[j]+""); 
      if(j < clsLabel.length - 1) 
       builder.append(","); 
     } 
     builder.append("\n"); 
    } 
    outFile.write(builder.toString());//save the string representation 
    System.out.println("Output file written."); 
    System.out.println("Completed successfully!"); 
    outFile.close();  
}  
} 

Das Problem dabei ist, dass es stellt sich heraus, Welche der beiden Spalten beschreibt, welche der beiden Ergebniskategorien nicht festgelegt ist. Es scheint damit zu tun zu haben, welche Kategorie zuerst im Trainingsdatensatz erscheint, was völlig willkürlich ist. Wenn also andere Datensätze mit diesem Programm verwendet wurden, waren die hartcodierten Etiketten rückwärts.

Also, ich brauche eine bessere Möglichkeit, sie zu beschriften, aber in der Dokumentation für Classifier und distributionForInstance und ich sehe nichts nützliches.

aktualisieren:

ich, wie es drucken auf den Bildschirm heraus (dank this), hatte aber immer noch Probleme mit ihm zu csv schreiben:

for (int i = 0; i < labeled.size(); i++)  
    { 
     // Discreet prediction 
     double predictionIndex = 
      clf.classifyInstance(newTest.instance(i)); 

     // Get the predicted class label from the predictionIndex. 
     String predictedClassLabel = 
      newTest.classAttribute().value((int) predictionIndex); 

     // Get the prediction probability distribution. 
     double[] predictionDistribution = 
      clf.distributionForInstance(newTest.instance(i)); 

     // Print out the true predicted label, and the distribution 
     System.out.printf("%5d: predicted=%-10s, distribution=", 
          i, predictedClassLabel); 

     // Loop over all the prediction labels in the distribution. 
     for (int predictionDistributionIndex = 0; 
      predictionDistributionIndex < predictionDistribution.length; 
      predictionDistributionIndex++) 
     { 
      // Get this distribution index's class label. 
      String predictionDistributionIndexAsClassLabel = 
       newTest.classAttribute().value(
        predictionDistributionIndex); 

      // Get the probability. 
      double predictionProbability = 
       predictionDistribution[predictionDistributionIndex]; 

      System.out.printf("[%10s : %6.3f]", 
           predictionDistributionIndexAsClassLabel, 
           predictionProbability); 

      // Attempt to write to CSV 
      builder.append(i+","+predictedClassLabel+","+ 
        predictionDistributionIndexAsClassLabel+","+predictionProbability); 
          //.charAt(0)+','+predictionProbability.charAt(0)); 

     } 

     System.out.printf("\n"); 
     builder.append("\n"); 

Antwort

1

angepasst ich den Code unten von diesem answer und diesem answer. Grundsätzlich können Sie die Testdaten für das Klassenattribut abfragen und dann den spezifischen Wert für jede mögliche Klasse erhalten.

for (int i = 0; i < labeled.size(); i++)  
{ 
// Discreet prediction 

double predictionIndex = 
    clf.classifyInstance(newTest.instance(i)); 

// Get the predicted class label from the predictionIndex. 
String predictedClassLabel = 
    newTest.classAttribute().value((int) predictionIndex); 

// Get the prediction probability distribution. 
double[] predictionDistribution = 
    clf.distributionForInstance(newTest.instance(i)); 

// Print out the true predicted label, and the distribution 
System.out.printf("%5d: predicted=%-10s, distribution=", 
        i, predictedClassLabel); 

// Loop over all the prediction labels in the distribution. 
for (int predictionDistributionIndex = 0; 
    predictionDistributionIndex < predictionDistribution.length; 
    predictionDistributionIndex++) 
{ 
    // Get this distribution index's class label. 
    String predictionDistributionIndexAsClassLabel = 
     newTest.classAttribute().value(
      predictionDistributionIndex); 

    // Get the probability. 
    double predictionProbability = 
     predictionDistribution[predictionDistributionIndex]; 

    System.out.printf("[%10s : %6.3f]", 
         predictionDistributionIndexAsClassLabel, 
         predictionProbability); 

    // Write to CSV 
    builder.append(i+","+ 
      predictionDistributionIndexAsClassLabel+","+predictionProbability); 


} 

System.out.printf("\n"); 
builder.append("\n"); 

} 


// Save results in .csv file 
outFile.write(builder.toString());//save the string representation 
+1

Sie haben absolut Recht, dass ich ein anderer Index sein sollte! Es ist einfach die Instanz, die Sie bewerten. Ich werde korrigieren – Walter

+0

Danke nochmal. Also sollte die for-Schleife für die erste Zeile etwas wie 'for (int j = 0; j

+1

Ich denke, es könnte einen kleinen Fehler oder eine fehlende Komponente geben (siehe Kommentar oben), aber ich habe das gerade in meiner Version funktioniert und du verdienst den Kredit, also bin ich gerade dabei, deinen Beitrag mit meiner Version zu bearbeiten und als zu markieren die Lösung. Wenn Sie die Bearbeitung, die ich gerade mache, rückgängig machen und Ihre Version einfach optimieren wollen, ist das total cool. Nochmals vielen Dank für Ihre Hilfe, ich schätze es sehr! –

Verwandte Themen