2012-08-14 7 views
6

Vorrei sapere se c'è un modo in WEKA per produrre una serie di "migliori ipotesi" per una classificazione.Probabilità di classificazione WEKA delle classi

Il mio scenario è: classifico i dati con convalida incrociata, ad esempio, quindi sull'output di weka ottengo qualcosa del tipo: queste sono le 3 migliori ipotesi per la classificazione di questa istanza. Quello che voglio è come, anche se un'istanza non è correttamente classificata, ottengo un output delle 3 o 5 migliori ipotesi per quell'istanza.

Esempio:

classi: A, B, C, D, E istanze: 1 ... 10

E uscita sarebbe: esempio 1 è del 90% di probabilità di essere di classe A, Il 75% probabilmente è di classe B, il 60% gradisce essere classe C.

Grazie.

risposta

2

Non so se è possibile farlo in modo nativo, ma è possibile ottenere solo le probabilità per ogni classe, ordinate e prendere i primi tre.

La funzione desiderata è distributionForInstance(Instance instance) che restituisce un valore double[] fornendo la probabilità per ciascuna classe.

+0

ok grazie, ci provo. – user1454263

0

Non in generale. Le informazioni che desideri non sono disponibili con tutti i classificatori - nella maggior parte dei casi (ad esempio per gli alberi decisionali), la decisione è chiara (anche se potenzialmente errata) senza un valore di confidenza. Il tuo compito richiede classificatori in grado di gestire l'incertezza (come il classificatore naive Bayes).

Tecnicamente la cosa più semplice da fare è probabilmente quella di addestrare il modello e quindi classificare una singola istanza, per la quale Weka dovrebbe darti l'output desiderato. In generale, puoi ovviamente farlo anche per serie di istanze, ma non penso che Weka fornisca questo fuori dalla scatola. Probabilmente dovresti personalizzare il codice o usarlo tramite un'API (ad esempio in R).

+0

Sono inteso a usarlo tramite l'API – user1454263

0

quando si calcola una probabilità per l'istanza, con quale precisione si esegue questa operazione?

Ho pubblicato le mie regole PART e dati per la nuova istanza here ma per quanto riguarda il calcolo manualmente non sono sicuro di come farlo! Grazie

EDIT: ora calcolata:

privato float [] getProbDist (String split) {

// prende in qualcosa come (52/2) che significa 52 casi correttamente classificati e 2 erroneamente classificata.

if(prob_dis.length > 2) 
     return null; 

    if(prob_dis.length == 1){ 
     String temp = prob_dis[0]; 
     prob_dis = new String[2]; 
     prob_dis[0] = "1"; 
     prob_dis[1] = temp; 
    } 

    float p1 = new Float(prob_dis[0]); 
    float p2 = new Float(prob_dis[1]); 
    // assumes two tags 
    float[] tag_prob = new float[2]; 

    tag_prob[1] = 1 - tag_prob[1]; 
    tag_prob[0] = (float)p2/p1; 

// returns double[] as being the probabilities 

return tag_prob;  
} 
5

API Weka ha un metodo chiamato Classifier.distributionForInstance() tha può essere utilizzato per ottenere la distribuzione di classificazione predizione. È quindi possibile ordinare la distribuzione diminuendo la probabilità per ottenere le previsioni top-N.

Di seguito è riportata una funzione che stampa: (1) l'etichetta di verità di terra dell'istanza di test; (2) l'etichetta prevista da classifyInstance(); e (3) la distribuzione di predizione da distributionForInstance(). Ho usato questo con J48, ma dovrebbe funzionare con altri classificatori.

I parametri di input sono il file di modello serializzato (che è possibile creare durante la fase di addestramento del modello e l'applicazione dell'opzione -d) e il file di test in formato ARFF.

public void test(String modelFileSerialized, String testFileARFF) 
    throws Exception 
{ 
    // Deserialize the classifier. 
    Classifier classifier = 
     (Classifier) weka.core.SerializationHelper.read(
      modelFileSerialized); 

    // Load the test instances. 
    Instances testInstances = DataSource.read(testFileARFF); 

    // Mark the last attribute in each instance as the true class. 
    testInstances.setClassIndex(testInstances.numAttributes()-1); 

    int numTestInstances = testInstances.numInstances(); 
    System.out.printf("There are %d test instances\n", numTestInstances); 

    // Loop over each test instance. 
    for (int i = 0; i < numTestInstances; i++) 
    { 
     // Get the true class label from the instance's own classIndex. 
     String trueClassLabel = 
      testInstances.instance(i).toString(testInstances.classIndex()); 

     // Make the prediction here. 
     double predictionIndex = 
      classifier.classifyInstance(testInstances.instance(i)); 

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

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

     // Print out the true label, predicted label, and the distribution. 
     System.out.printf("%5d: true=%-10s, predicted=%-10s, distribution=", 
          i, trueClassLabel, 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 = 
       testInstances.classAttribute().value(
        predictionDistributionIndex); 

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

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

     o.printf("\n"); 
    } 
}