我已经查看了WEKA的“进行预测“文档,其中包含了命令行和GUI预测的明确说明。
我想知道如何在自己的Java代码中使用Agrawal
数据集(weka.datagenerators.classifiers.classification.Agrawal
)获取类似于我在GUI中得到的下面的预测值:
inst#, actual, predicted, error, prediction1, 1:0, 2:1, +, 0.9412, 1:0, 1:0, , 13, 1:0, 1:0, , 14, 1:0, 1:0, , 15, 1:0, 1:0, , 16, 1:0, 1:0, , 17, 1:0, 2:1, +, 0.9418, 2:1, 2:1, , 0.9419, 2:1, 2:1, , 0.94110, 2:1, 2:1, , 0.9411, 1:0, 1:0, , 12, 1:0, 1:0, , 13, 1:0, 1:0, , 1
尽管它说可以做到,但我无法复制这个结果:
Java
我访问了链接,上面说:
分类实例
如果你有一个未标记的数据集,并且想用你新训练的分类器对其进行分类,你可以使用以下代码片段。它加载文件
/some/where/unlabeled.arff
,使用之前构建的分类器树对实例进行标记,并将标记后的数据保存为/some/where/labeled.arff
。
这并不是我想要的情况,因为我只想对当前数据集进行建模并获取k折交叉验证的预测结果。
更新
predictions
public FastVector predictions()
返回已收集的预测结果。
返回值:
指向包含已收集预测结果的
FastVector
的引用。如果没有收集预测结果,则应为null。
我找到了predictions()
方法,适用于类型为Evaluation
的对象,并使用以下代码:
Object[] preds = evaluation.predictions().toArray();for(Object pred : preds) { System.out.println(pred);}
结果是:
...NOM: 0.0 0.0 1.0 0.9466666666666667 0.05333333333333334NOM: 0.0 0.0 1.0 0.8947368421052632 0.10526315789473684NOM: 0.0 0.0 1.0 0.9934883720930232 0.0065116279069767444NOM: 0.0 0.0 1.0 0.9466666666666667 0.05333333333333334NOM: 0.0 0.0 1.0 0.9912575655682583 0.008742434431741762NOM: 0.0 0.0 1.0 0.9934883720930232 0.0065116279069767444...
这与上面的结果相同吗?
回答:
经过深入的Google搜索(因为文档提供的帮助很少),我终于找到了答案。
我希望这个明确的答案能在未来帮助其他人。
-
对于一个示例代码,我看到了问题“如何在WEKA中交叉验证后打印预测类“,我很高兴能够解码出那个不完整的答案,其中一些内容很难理解。
以下是与GUI输出相似的工作代码
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);
为了帮助你理解,我们需要实现将
StringBuffer
转换为AbstractOutput
对象,以便crossValidateModel
函数能够识别它。仅使用
StringBuffer
会导致java.lang.ClassCastException
,类似于问题中提到的,而不使用StringBuffer
的PlainText
会显示java.lang.IllegalStateException
。我想感谢ManChon U (Kevin)及其问题“如何将交叉评估结果与输入数据集中的相应实例匹配?“,因为它给了我一些线索:
…你只需要一个额外的参数,它是
weka.classifiers.evaluation.output.prediction.AbstractOutput
的具体子类。weka.classifiers.evaluation.output.prediction.PlainText
可能是你想要使用的。来源和
…尝试创建一个
PlainText
对象,它扩展了AbstractOutput
(例如称为output的实例),并调用output.setBuffer(forPredictionsPrinting)
,然后传递它而不是缓冲区。来源这些实际上是指创建一个
PlainText
对象,将StringBuffer
放入其中,并使用setOutput(boolean)
等方法来调整输出。最后,要获取我们想要的预测结果,只需使用:
System.out.println(predictionOutput.getBuffer());
其中
predictionOutput
是来自AbstractOutput
家族(PlainText
、CSV
、XML
等)的对象。 -
此外,
evaluation.predictions()
的结果与WEKA GUI中提供的结果不同。幸运的是,Mark Hall在问题“交叉验证后打印预测类“中解释了这一点Evaluation.predictions()
返回一个包含weka.classifiers.evaluation
包中的NominalPrediction
或NumericPrediction
对象的FastVector
。使用额外的AbstractOutput
对象调用Evaluation.crossValidateModel()
会导致评估对象将Nominal
/NumericPrediction
对象中的预测/分布信息打印到StringBuffer
中,你在Explorer或命令行中看到的格式就是这样的。
参考资料: