如何通过WEKA Java API计算分类器统计显著性并生成GUI式结果?
如何用WEKA Java API实现类似GUI的分类器统计显著性结果
我正在尝试用WEKA Java API计算分类器的统计显著性,查文档知道要用PairedCorrectedTTester的calculateStatistics方法,但不知道具体用法。我写了一段代码(如下),运行后得到的结果没有像WEKA GUI那样显示统计显著性标记(比如GUI里红圈标注的*、**符号),希望能指导怎么实现这个需求。
我的代码
public static void main(String[] args) throws Exception { ZeroR zr = new ZeroR(); Bagging bg = new Bagging(); Experiment exp = new Experiment(); exp.setPropertyArray(new Classifier[0]); exp.setUsePropertyIterator(true); SplitEvaluator se = null; Classifier sec = null; se = new ClassifierSplitEvaluator(); sec = ((ClassifierSplitEvaluator) se).getClassifier(); CrossValidationResultProducer cvrp = new CrossValidationResultProducer(); cvrp.setNumFolds(10); cvrp.setSplitEvaluator(se); PropertyNode[] propertyPath = new PropertyNode[2]; propertyPath[0] = new PropertyNode( se, new PropertyDescriptor("splitEvaluator", CrossValidationResultProducer.class), CrossValidationResultProducer.class ); propertyPath[1] = new PropertyNode( sec, new PropertyDescriptor("classifier", se.getClass()), se.getClass() ); exp.setResultProducer(cvrp); exp.setPropertyPath(propertyPath); // set classifiers here exp.setPropertyArray(new Classifier[]{zr, bg}); DefaultListModel model = new DefaultListModel(); File file = new File("dataset arff file"); model.addElement(file); exp.setDatasets(model); InstancesResultListener irl = new InstancesResultListener(); irl.setOutputFile(new File("output.csv")); exp.setResultListener(irl); exp.initialize(); exp.runExperiment(); exp.postProcess(); PairedCorrectedTTester tester = new PairedCorrectedTTester(); Instances result = new Instances(new BufferedReader(new FileReader(irl.getOutputFile()))); tester.setInstances(result); tester.setSortColumn(-1); tester.setRunColumn(result.attribute("Key_Run").index()); tester.setFoldColumn(result.attribute("Key_Fold").index()); tester.setResultsetKeyColumns( new Range( "" + (result.attribute("Key_Dataset").index() + 1))); tester.setDatasetKeyColumns( new Range( "" + (result.attribute("Key_Scheme").index() + 1) + "," + (result.attribute("Key_Scheme_options").index() + 1) + "," + (result.attribute("Key_Scheme_version_ID").index() + 1))); tester.setResultMatrix(new ResultMatrixPlainText()); tester.setDisplayedResultsets(null); tester.setSignificanceLevel(0.05); tester.setShowStdDevs(true); tester.multiResultsetFull(0, result.attribute("Percent_correct").index()); System.out.println("\nResult:"); ResultMatrix matrix = tester.getResultMatrix(); System.out.println(matrix.toStringMatrix()); }
当前问题
代码运行后仅输出基础的准确率等统计值,没有显示分类器之间性能差异的统计显著性标记(如WEKA GUI中的*、**符号)。
期望结果
输出类似WEKA GUI的结果,包含统计显著性标注,明确区分分类器性能差异是否显著。
参考过的资源
- WEKA官方Wiki的Experiment API使用文档
PairedCorrectedTTester的Javadoc文档
解决方法
1. 修正关键列配置
你搞反了ResultsetKeyColumns和DatasetKeyColumns的含义:
setResultsetKeyColumns:指定分类器相关列(区分不同分类器结果集)setDatasetKeyColumns:指定数据集相关列(区分不同数据集)
修正代码:
// 修正:结果集(分类器)关键列 tester.setResultsetKeyColumns( new Range( "" + (result.attribute("Key_Scheme").index() + 1) + "," + (result.attribute("Key_Scheme_options").index() + 1) + "," + (result.attribute("Key_Scheme_version_ID").index() + 1))); // 修正:数据集关键列 tester.setDatasetKeyColumns( new Range( "" + (result.attribute("Key_Dataset").index() + 1)));
2. 替换支持显著性标记的ResultMatrix
默认的ResultMatrixPlainText不显示显著性符号,换成ResultMatrixSignificance(或其子类):
// 使用支持显著性标记的矩阵实现 ResultMatrixSignificance matrix = new ResultMatrixSignificance(); // 可自定义显著性标记和对应阈值 matrix.setSignificanceSymbols(new String[]{"", "*", "**"}); matrix.setSignificanceLevels(new double[]{0.05, 0.01}); tester.setResultMatrix(matrix);
3. 确保统计计算逻辑正确
保留multiResultsetFull方法调用(内部会触发calculateStatistics),指定要对比的指标列即可:
int metricCol = result.attribute("Percent_correct").index(); tester.multiResultsetFull(0, metricCol);
修正后的完整关键代码片段
PairedCorrectedTTester tester = new PairedCorrectedTTester(); Instances result = new Instances(new BufferedReader(new FileReader(irl.getOutputFile()))); tester.setInstances(result); tester.setSortColumn(-1); tester.setRunColumn(result.attribute("Key_Run").index()); tester.setFoldColumn(result.attribute("Key_Fold").index()); // 修正关键列配置 tester.setResultsetKeyColumns( new Range( "" + (result.attribute("Key_Scheme").index() + 1) + "," + (result.attribute("Key_Scheme_options").index() + 1) + "," + (result.attribute("Key_Scheme_version_ID").index() + 1))); tester.setDatasetKeyColumns( new Range( "" + (result.attribute("Key_Dataset").index() + 1))); // 配置显著性矩阵 ResultMatrixSignificance matrix = new ResultMatrixSignificance(); matrix.setSignificanceSymbols(new String[]{"", "*", "**"}); matrix.setSignificanceLevels(new double[]{0.05, 0.01}); tester.setResultMatrix(matrix); tester.setDisplayedResultsets(null); tester.setSignificanceLevel(0.05); tester.setShowStdDevs(true); // 执行显著性计算 int metricCol = result.attribute("Percent_correct").index(); tester.multiResultsetFull(0, metricCol); System.out.println("\nResult:"); System.out.println(tester.getResultMatrix().toStringMatrix());
运行效果
修正后,输出结果会和WEKA GUI一致,在分类器性能差异显著的位置显示对应的*或**标记。
内容的提问来源于stack exchange,提问作者user20226932
相关产品推荐
相关产品推荐

