WEKA中十倍交叉验证的结果不准确



昨天,我用 2 种方法在 weka 中实现了 10 倍交叉验证,但结果不一致。

方式一:直接调用方法eval.crossValidateModel()

J48 j48 = new J48();
j48.buildClassifier(ins);  // ins is the Instances object
Evaluation eval = new Evaluation(ins);
eval.crossValidateModel(j48, ins, 10, new Random(1)); // 10-fold cross validation
... // get results by eval.getXX(0) or eval.getXXX(1)

方式二:采用方法testCV(),各折trainCV()

ins.randomize(new Random(1)); // ins is the Instances object
ins.stratify(10); // randomize the dataset then split into 10 folds
for(int i=0; i<10; i++){       
Instances trainData = ins.trainCV(10, i);
Instances testData = ins.testCV(10, i);
J48 j48 = new J48();
j48.buildClassifier(trainData);
Evaluation eval = new Evaluation(trainData);
eval.evaluateModel(j48, testData);
... // get results by eval.getXX(0) or eval.getXXX(1)
}

根据 weka api 文档,上述 2 种方式应该有相同的结果,即方式 2 的平均结果(例如精度、召回率(应该等于方式 1 的结果。但事实是它们不一样,任何人都可以找出我的代码中的错误,或者提供其他不错的评估方法吗?谢谢大家!

如果您查看weka.classifiers.Evaluation.crossValidateModel方法的代码(取决于您的版本,委托对象(,您将看到它使用weka.core.Instances.trainCV(int,int,Random)方法。此外,您需要使用完整数据集的类先验初始化Evaluation对象。

以下是更新的代码:

Evaluation eval = new Evaluation(ins);  // init evaluation
rand = new Random(1);
int numFolds = 10;  // 10-fold CV
ins.randomize(rand); // randomize the data
ins.stratify(numFolds); // stratify the randomized data for 10-fold CV
J48 template = new J48();  // classifier template for evaluation
//template.setOptions(...);  // if further options need to be set
for (int i = 0; i < numFolds; i++) {       
Instances trainData = ins.trainCV(numFolds, i, rand);
Instances testData = ins.testCV(numFolds, i);
Classifier cls = AbstractClassifier.makeCopy(template);  // copy of classifier template
cls.buildClassifier(trainData);
eval.evaluateModel(cls, testData);  // accumulate statistics
}
... // get results by eval.getXX(0) or eval.getXXX(1)

Way1是Weka GUI中广泛使用的基本方法,因此crossValidationModel()可以使用Weka Explorer给出相同的平均结果,如下所示。

1.打开维卡软糖

2.进入浏览器模块

3.在预处理选项卡中选择数据集

4.在分类选项卡中选择J4810 折交叉验证

5.单击开始按钮在分类器输出窗口中获取结果

Way2是一种替代方法,我们可以获得每个折叠的结果。每个折叠的结果与Weka Experimenter中的结果相同,如下操作。

  1. 打开维卡软件

  2. 进入实验者模块

  3. 单击"新建
  4. "按钮以在"设置"选项卡中新建简单实验

  5. 结果目标数据集算法中设置参数

  6. 单击"运行"选项卡中的"开始"按钮,每个折叠的结果都保存在"结果目标"中定义的文件中

总而言之,这 2 种方法肯定返回了 2 个不同的结果,根据其办公网站给出的源代码 https://weka.wikispaces.com/Generating+cross-validation+folds+(Java+approach(,上述方法应该会得到一致的结果,但事实恰恰相反,也许这是 Weka 的一个错误。

最新更新