我需要自动从我的训练分类器中获取阈值曲线,因此我正在研究如何使用命令行来实现这一点(目前使用Weka的SimpleCLI)。根据java weka.classifiers.functions.Logistic -h
的输出,我尝试使用-threshold-file
参数,其描述如下:
-threshold-file <file> 保存阈值数据的文件。 格式由扩展名决定,例如,'.arff'表示ARFF格式,'.csv'表示CSV格式。
这是我在SimpleCLI中尝试执行的命令行(为了便于阅读,分为两部分):
java weka.classifiers.functions.Logistic -t ".\data\iris.arff" -no-cv -R 1.0E-8 -M -1 \ -threshold-file "C:\Temp\somefile.csv"
这会给我以下错误之一:
java.lang.NullPointerException
或者是这个(或者两者都有):
weka.classifiers.evaluation.ThresholdCurve.getCurve(ThresholdCurve.java:125)weka.classifiers.evaluation.Evaluation.evaluateModel(Evaluation.java:1739)weka.classifiers.Evaluation.evaluateModel(Evaluation.java:650)weka.classifiers.AbstractClassifier.runClassifier(AbstractClassifier.java:359)weka.classifiers.functions.Logistic.main(Logistic.java:1134)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)java.lang.reflect.Method.invoke(Unknown Source)weka.gui.SimpleCLIPanel$ClassRunner.run(SimpleCLIPanel.java:199)at weka.classifiers.evaluation.ThresholdCurve.getCurve(ThresholdCurve.java:125)at weka.classifiers.evaluation.Evaluation.evaluateModel(Evaluation.java:1739)at weka.classifiers.Evaluation.evaluateModel(Evaluation.java:650)at weka.classifiers.AbstractClassifier.runClassifier(AbstractClassifier.java:359)at weka.classifiers.functions.Logistic.main(Logistic.java:1134)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at weka.gui.SimpleCLIPanel$ClassRunner.run(SimpleCLIPanel.java:199)
(在Windows cmd.exe中执行会得到大致相同的消息。请注意,我使用的是Weka 3.7.11,在Windows 7(64位)机器上运行,Java版本为7(更新55)。)
请注意,删除最后部分后,命令可以正常工作,尽管不会创建所需的阈值文件。
我尝试了这条命令的许多变体,结果都一样。我对Java不熟悉。我需要知道我哪里做错了。
提前感谢。
更新:有人指出,weka.classifiers.evaluation.ThresholdCurve.getCurve(ThresholdCurve.java:125)
这一行是:
if ((predictions.size() == 0) || (((NominalPrediction) predictions.get(0)).distribution().length <= classIndex)) { return null;}
(源码)
因此,问题似乎是因为根本没有进行任何预测。我不知道为什么会发生这种情况,以及如何解决这个问题。
回答:
您用来调用简单命令行分类器的代码没有生成任何评估结果,基于此您无法获取阈值曲线。
您可以执行以下操作:
- 删除-no-cv参数。
- 使用-T选项指定测试文件。