6 votes

Probabilité de classification WEKA des classes

J'aimerais savoir s'il existe un moyen dans WEKA de produire un certain nombre de "best-guesses" pour une classification.

Mon scénario est le suivant : Je classe les données avec une validation croisée par exemple, puis sur la sortie de Weka j'obtiens quelque chose comme : voici les 3 meilleures estimations pour la classification de cette instance. Ce que je veux, c'est que même si une instance n'est pas correctement classée, j'obtienne une sortie des 3 ou 5 meilleures estimations pour cette instance.

Exemple :

Les classes : A,B,C,D,E Instances : 1...10

Et la sortie serait : l'instance 1 a 90% de chances d'être de classe A, 75% de chances d'être de classe B, 60% de chances d'être de classe C..

Merci.

6voto

L'API de Weka possède une méthode appelée Classifier.distributionForInstance() qui peut être utilisée pour obtenir la distribution des prédictions de classification. Vous pouvez ensuite trier la distribution par probabilité décroissante pour obtenir vos prédictions les plus importantes.

Voici une fonction qui imprime : (1) l'étiquette de vérité de l'instance de test ; (2) l'étiquette prédite par classifyInstance() ; et (3) la distribution de prédiction par distributionForInstance(). J'ai utilisé cette fonction avec J48, mais elle devrait fonctionner avec d'autres classifieurs.

Les paramètres d'entrée sont le fichier modèle sérialisé (que vous pouvez créer pendant la phase d'apprentissage du modèle et en appliquant l'option -d) et le fichier de test au format 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");
    }
}

2voto

Antimony Points 13190

Je ne sais pas si vous pouvez le faire en natif, mais vous pouvez simplement obtenir les probabilités pour chaque classe, les trier et prendre les trois premières.

La fonction que vous voulez est distributionForInstance(Instance instance) qui renvoie un double[] donnant la probabilité pour chaque classe.

0voto

Lars Kotthoff Points 44924

Pas en général. L'information que vous voulez n'est pas disponible avec tous les classificateurs -- dans la plupart des cas (par exemple pour les arbres de décision), la décision est claire (bien que potentiellement incorrecte) sans valeur de confiance. Votre tâche nécessite des classificateurs qui peuvent gérer l'incertitude (comme le classificateur Bayes naïf).

Techniquement, la chose la plus simple à faire est probablement d'entraîner le modèle et ensuite de classer une instance individuelle, pour laquelle Weka devrait vous donner le résultat souhaité. En général, vous pouvez aussi le faire pour des ensembles d'instances, mais je ne pense pas que Weka le propose d'emblée. Vous devrez probablement personnaliser le code ou l'utiliser via une API (par exemple dans R).

0voto

redrubia Points 822

Lorsque vous calculez une probabilité pour l'instance, comment faites-vous exactement ?

J'ai posté mes règles PART et mes données pour la nouvelle instance. aquí mais pour ce qui est du calcul manuel, je ne sais pas trop comment faire ! Merci

EDIT : maintenant calculé :

private float[] getProbDist(String split){

// prend quelque chose comme (52/2) signifiant 52 instances correctement classées et 2 incorrectement classées.

    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;    
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X