使用自己的Java代码和模型获取WEKA中的预测百分比

时间:2014-02-10 10:25:03

标签: java machine-learning classification weka prediction

概述

我知道可以通过GUI和命令行选项在训练有素的WEKA模型中获得每个预测的百分比,如文档文章"Making predictions"中所方便解释和演示的那样。

WHAT I WANT WITH MY WEKA OOOHH *LADY GAGA PIANO*

预测

我知道有三种方法可以记录这些预测:

  1. command line
  2. GUI
  3. Java代码/使用WEKA API,我在答案"Get risk predictions in WEKA using own Java code"
  4. 时能够做到这一点
  5. 第四个需要生成的WEKA .MODEL文件
  6. 我有一个经过培训的.MODEL文件,现在我想用新的实例和预测百分比对新实例进行分类类似于下面的那个(GUI的资源管理器的输出,在{ {1}}格式):

    CSV

    我想从inst#,actual,predicted,error,distribution, 1,1:0,2:1,+,0.399409,*0.7811 2,1:0,2:1,+,0.3932409,*0.8191 3,1:0,2:1,+,0.399409,*0.600591 4,1:0,2:1,+,0.139409,*0.64 5,1:0,2:1,+,0.399409,*0.600593 6,1:0,2:1,+,0.3993209,*0.600594 7,1:0,2:1,+,0.500129,*0.600594 8,1:0,2:1,+,0.399409,*0.90011 9,1:0,2:1,+,0.211409,*0.60182 10,1:0,2:1,+,0.21909,*0.11101 文件中获取predicted列。


    我所知道的

    根据我对WEKA API方法的经验,可以使用以下代码(插入.MODEL对象的PlainText)获得这些预测但是我不想做 k - 由Evaluation对象提供的交叉验证。

    Evaluation

    来自WEKA文档

    请注意,在"Use Weka in your Java code""Serialization"又名“如何使用{{1}中讨论StringBuffer predictionSB = new StringBuffer(); Range attributesToShow = null; Boolean outputDistributions = new Boolean(true); PlainText predictionOutput = new PlainText(); predictionOutput.setBuffer(predictionSB); predictionOutput.setOutputDistribution(true); Evaluation evaluation = new Evaluation(data); evaluation.crossValidateModel(j48Model, data, numberOfFolds, randomNumber, predictionOutput, attributesToShow, outputDistributions); System.out.println(predictionOutput.getBuffer()); 文件对来自.MODEL或相关输入的数据进行分类你自己的Java代码中的文件来分类新的实例“(为什么模糊的标题为smfh)。

    使用自己的Java代码进行分类

    加载.ARFF文件是通过“反序列化”,以下是版本> 3.5.5:

    .MODEL

    .MODEL对象是数据,它被送到// deserialize model Classifier cls = (Classifier) weka.core.SerializationHelper.read("/some/where/j48.model"); 。此处提供输出(取决于结果属性的数据类型):

    Instance

    问题"How to reuse saved classifier created from explorer(in weka) in eclipse java"也有一个很好的答案!

    Javadoc中

    我已经检查过Javadocs Classifier(经过训练的模型)和Evaluation(以防万一),但没有一个直接明确地解决了这个问题。

    唯一最接近我想要的是classifyInstance的{​​{1}}方法:

      

    对给定的测试实例进行分类。实例在被分类时必须属于数据集。请注意,分类器必须实现this或distributionForInstance()。


    如何使用我自己的Java代码(又称使用WEKA API)同时使用WEKA // classify an Instance object (testData) cls.classifyInstance(testData.instance(0)); 文件对新实例进行分类和预测?

    WHAT I WANT WITH MY WEKA OOOHH *LADY GAGA PIANO*

1 个答案:

答案 0 :(得分:3)

这个答案只是从How to reuse saved classifier created from explorer(in weka) in eclipse java更新我的回答。

我将展示如何获得预测的实例值和预测百分比(或分布)。示例模型是在Weka Explorer中创建并保存的J48决策树。它是根据Weka提供的名义天气数据建造的。它被称为“tree.model”。

import weka.classifiers.Classifier;
import weka.core.Instances;

public class Main {

    public static void main(String[] args) throws Exception
    {
        String rootPath="/some/where/"; 
        Instances originalTrain= //instances here

        //load model
        Classifier cls = (Classifier) weka.core.SerializationHelper.read(rootPath+"tree.model");

        //predict instance class values
        Instances originalTrain= //load or create Instances to predict

        //which instance to predict class value
        int s1=0;

        //perform your prediction
        double value=cls.classifyInstance(originalTrain.instance(s1));

        //get the prediction percentage or distribution
        double[] percentage=cls.distributionForInstance(originalTrain.instance(s1));

        //get the name of the class value
        String prediction=originalTrain.classAttribute().value((int)value); 

        System.out.println("The predicted value of instance "+
                                Integer.toString(s1)+
                                ": "+prediction); 

        //Format the distribution
        String distribution="";
        for(int i=0; i <percentage.length; i=i+1)
        {
            if(i==value)
            {
                distribution=distribution+"*"+Double.toString(percentage[i])+",";
            }
            else
            {
                distribution=distribution+Double.toString(percentage[i])+",";
            }
        }
        distribution=distribution.substring(0, distribution.length()-1);

        System.out.println("Distribution:"+ distribution);
    }

}

这个输出是:

The predicted value of instance 0: no  
Distribution: *1, 0