使用自己的Java代码在WEKA中获取风险预测

时间:2014-01-29 07:00:41

标签: java machine-learning weka probability prediction

我已经检查了WEKA的"Making predictions"文档,它包含有关命令行和GUI预测的明确说明。

我想知道如何在我自己的Java代码中使用Agrawal数据集(weka.datagenerators.classifiers.classification.Agrawal)从GUI获得的预测值如下所示:

inst#,  actual,     predicted,  error,  prediction
1,      1:0,        2:1,        +,      0.941
2,      1:0,        1:0,        ,       1
3,      1:0,        1:0,        ,       1
4,      1:0,        1:0,        ,       1
5,      1:0,        1:0,        ,       1
6,      1:0,        1:0,        ,       1
7,      1:0,        2:1,        +,      0.941
8,      2:1,        2:1,        ,       0.941
9,      2:1,        2:1,        ,       0.941
10,     2:1,        2:1,        ,       0.941
1,      1:0,        1:0,        ,       1
2,      1:0,        1:0,        ,       1
3,      1:0,        1:0,        ,       1

即使it说:

,我也无法复制此结果
  

爪哇

     

如果您想在自己的代码中执行分类,请参阅classifying instancesthis article部分,一般性地解释Weka API。

我去了link并说:

  

对实例进行分类

     

如果您想要使用新训练的分类器对未标记的数据集进行分类,则可以使用以下代码段。它加载文件/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.05333333333333334
NOM: 0.0 0.0 1.0 0.8947368421052632 0.10526315789473684
NOM: 0.0 0.0 1.0 0.9934883720930232 0.0065116279069767444
NOM: 0.0 0.0 1.0 0.9466666666666667 0.05333333333333334
NOM: 0.0 0.0 1.0 0.9912575655682583 0.008742434431741762
NOM: 0.0 0.0 1.0 0.9934883720930232 0.0065116279069767444
...

这与上面的相同吗?

1 个答案:

答案 0 :(得分:6)

经过深入的Google搜索(以及documentation provides minimal help)后,我终于找到了答案。

我希望这个明确的答案可以帮助其他人。

  • 对于示例代码,我看到了问题"How to print out the predicted class after cross-validation in 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);
    

    为了帮助您理解,我们需要在AbstractOutput对象中实现StringBuffer,以便函数crossValidateModel可以识别它。

    仅使用StringBuffer会导致java.lang.ClassCastException与问题中的PlainText相似,而使用StringBufferjava.lang.IllegalStateExceptionweka.classifiers.evaluation.output.prediction.AbstractOutput会显示weka.classifiers.evaluation.output.prediction.PlainText

    我要感谢ManChon U (Kevin)和他们的问题"How to identify the cross-evaluation result to its corresponding instance in the input data set?"给我一个关于这意味着什么的线索:

      

    ...你只需要一个加法参数,它是PlainText的具体子类。 AbstractOutput可能是。{1}   一个你想要使用。 Source

      

    ...尝试创建一个output.setBuffer(forPredictionsPrinting)对象,该对象扩展PlainText(例如,称为输出)实例并调用StringBuffer并将其传递给而不是缓冲区。 Source

    这些实际上只是为了创建一个setOutput(boolean)对象,在其中添加System.out.println(predictionOutput.getBuffer()); 并使用它来调整输出方法predictionOutput和其他方法。

    最后,要获得我们想要的预测,只需使用:

    PlainText

    其中CSV是来自AbstractOutput家庭的对象(XMLevaluation.predictions()Evaluation.predictions()等。

  • 此外,FastVector的结果与WEKA GUI中提供的结果不同。幸运的是Mark Hall在问题{​​{3}}

    中解释了这一点
      

    NominalPrediction会返回NumericPrediction包含weka.classifiers.evaluationEvaluation.crossValidateModel()AbstractOutput个对象的Nominal个对象。调用   带有NumericPrediction附加对象的StringBuffer会导致评估对象以{{1}} / {{1}}个对象的格式打印预测/分发信息到{{1}}请参阅资源管理器或命令行。

参考文献: