6

分類のためにいくつかの「最良の推測」を出力する方法がWEKAにあるかどうか知りたいです。

私のシナリオは次のとおりです。たとえば、クロス検証を使用してデータを分類すると、wekaの出力で次のようになります。これらは、このインスタンスの分類の3つの最良の推測です。私が欲しいのは、インスタンスが正しく分類されていなくても、そのインスタンスの3つまたは5つの最良の推測の出力を取得するようなものです。

例:

クラス:A、B、C、D、Eインスタンス:1 ... 10

そして、出力は次のようになります。インスタンス1はクラスAである可能性が90%、クラスBである可能性が75%、クラスCである可能性が60%です。

ありがとう。

4

4 に答える 4

6

Weka の API には、分類予測分布を取得するために使用できる Classifier.distributionForInstance() というメソッドがあります。次に、確率を減らして分布を並べ替え、上位 N 個の予測を取得できます。

以下は、出力する関数です。(1) テスト インスタンスのグラウンド トゥルース ラベル。(2) classifyInstance() から予測されたラベル。(3) distributionForInstance() からの予測分布。私はこれを J48 で使用しましたが、他の分類器でも動作するはずです。

入力パラメーターは、シリアル化されたモデル ファイル (モデルのトレーニング フェーズ中に -d オプションを適用して作成できます) と、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");
    }
}
于 2012-08-25T16:11:15.077 に答える
2

ネイティブにできるかどうかはわかりませんが、各クラスの確率を取得し、並べ替えて、最初の 3 つを取ることができます。

必要な関数は、各クラスの確率をdistributionForInstance(Instance instance)返すものです。double[]

于 2012-08-14T20:57:19.297 に答える
0

一般的ではありません。必要な情報がすべての分類子で利用できるわけではありません。ほとんどの場合(たとえば、決定木)、信頼値がなくても決定は明確です(潜在的に正しくない場合もあります)。タスクには、不確実性を処理できる分類器(単純ベイズ分類器など)が必要です。

技術的に最も簡単な方法は、おそらくモデルをトレーニングしてから個々のインスタンスを分類することです。これに対して、Wekaは目的の出力を提供する必要があります。一般的に、もちろんインスタンスのセットに対してもそれを行うことができますが、Wekaがこれをすぐに提供するとは思いません。おそらく、コードをカスタマイズするか、APIを介して使用する必要があります(たとえば、Rで)。

于 2012-08-14T21:00:13.043 に答える
0

インスタンスの確率を計算するとき、どのように正確に計算しますか?

新しいインスタンスの PART ルールとデータをここに投稿しましたが、手動で計算する限り、これを行う方法がよくわかりません! ありがとう

編集:計算されました:

プライベートフロート[] getProbDist(文字列分割){

// (52/2) のように、正しく分類された 52 個のインスタンスと正しく分類されていない 2 個のインスタンスを意味します。

    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;    
}
于 2012-08-20T21:45:01.250 に答える