【问题标题】:WEKA classification likelihood of the classes类的 WEKA 分类似然性
【发布时间】:2012-08-11 05:36:06
【问题描述】:

我想知道 WEKA 中是否有一种方法可以为分类输出一些“最佳猜测”。

我的场景是:例如,我使用交叉验证对数据进行分类,然后在 weka 的输出中我得到类似的信息:这些是该实例分类的 3 个最佳猜测。我想要的是,即使实例未正确分类,我也会得到该实例的 3 或 5 个最佳猜测的输出。

例子:

类:A、B、C、D、E 实例:1...10

输出将是: 实例 1 90% 可能是 A 类,75% 可能是 B 类,60% 可能是 C 类..

谢谢。

【问题讨论】:

    标签: machine-learning weka


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我不知道你是否可以原生地做到这一点,但你可以得到每个类的概率,对它们进行排序并取前三个。

      你想要的函数是distributionForInstance(Instance instance),它返回一个double[],给出每个类的概率。

      【讨论】:

        【解决方案3】:

        一般不会。并非所有分类器都提供您想要的信息——在大多数情况下(例如决策树),决策是明确的(尽管可能不正确),但没有置信度值。您的任务需要能够处理不确定性的分类器(例如朴素贝叶斯分类器)。

        从技术上讲,最简单的做法可能是训练模型,然后对单个实例进行分类,Weka 应该为您提供所需的输出。一般来说,您当然也可以为实例集执行此操作,但我不认为 Weka 提供了开箱即用的功能。您可能必须自定义代码或通过 API 使用它(例如在 R 中)。

        【讨论】:

        • 我打算通过 API 使用它
        【解决方案4】:

        当你计算实例的概率时,你具体是怎么做的?

        我已经为新实例here 发布了我的 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;    
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-04
          • 2015-08-19
          • 2015-10-21
          • 2014-05-07
          • 1970-01-01
          • 2023-04-08
          • 2021-06-01
          • 2014-09-26
          相关资源
          最近更新 更多