概述
我知道可以通过GUI和命令行选项方便地获取训练好的WEKA模型中每个预测的百分比,这在文档文章“做出预测“中有详细解释和演示。
预测
我知道有三种记录在案的方法可以获取这些预测:
- 命令行
- GUI
- 使用Java代码/使用WEKA API,我在回答“使用自己的Java代码在WEKA中获取风险预测“中已经实现了这一点
- 第四种方法需要一个生成的WEKA
.MODEL
文件
我有一个训练好的 .MODEL
文件,现在我想使用它来对新实例进行分类,并获取类似于下面的预测百分比(这是GUI的Explorer的输出,格式为 CSV
):
inst#,actual,predicted,error,distribution,1,1:0,2:1,+,0.399409,*0.78112,1:0,2:1,+,0.3932409,*0.81913,1:0,2:1,+,0.399409,*0.6005914,1:0,2:1,+,0.139409,*0.645,1:0,2:1,+,0.399409,*0.6005936,1:0,2:1,+,0.3993209,*0.6005947,1:0,2:1,+,0.500129,*0.6005948,1:0,2:1,+,0.399409,*0.900119,1:0,2:1,+,0.211409,*0.6018210,1:0,2:1,+,0.21909,*0.11101
predicted
列是我希望从 .MODEL
文件中获取的内容。
我所知道的
根据我对WEKA API方法的经验,可以使用以下代码获取这些预测(将 PlainText
插入到 Evaluation
对象中),但我不希望使用 Evaluation
对象提供的 k 折交叉验证。
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());
来自WEKA文档
请注意,.MODEL
文件对来自 .ARFF
或相关输入的数据进行分类,这在“在你的Java代码中使用Weka”和“序列化“中讨论过,后者也称为”如何在你自己的Java代码中使用 .MODEL
文件对新实例进行分类“(为什么标题这么模糊,真是让人头疼)。
使用自己的Java代码进行分类
加载 .MODEL
文件是通过“反序列化”进行的,以下是适用于版本 > 3.5.5 的代码:
// 反序列化模型Classifier cls = (Classifier) weka.core.SerializationHelper.read("/some/where/j48.model");
Instance
对象是数据,并被输入到 classifyInstance
中。这里会提供一个输出(取决于结果属性的数据类型):
// 对 Instance 对象(testData)进行分类cls.classifyInstance(testData.instance(0));
问题“如何在Eclipse Java中重用从WEKA Explorer创建的保存的分类器“也有一个很好的答案!
Javadocs
我已经查看了Classifier
(训练好的模型)和Evaluation
(以防万一)的Javadocs,但没有一个直接且明确地解决这个问题。
最接近我想要的东西是 Classifier
的 classifyInstances
方法:
对给定的测试实例进行分类。分类时,实例必须属于一个数据集。请注意,分类器必须实现此方法或
distributionForInstance()
方法之一。
我如何才能同时使用WEKA的 .MODEL
文件对新实例进行分类并使用自己的Java代码(即使用WEKA API)获取预测?
回答:
这个答案只是更新了我对如何在Eclipse Java中重用从WEKA Explorer创建的保存的分类器的回答。
我将展示如何获取预测实例的值和预测百分比(或分布)。示例模型是一个在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