Weka 交叉验证相关类的使用

来源:互联网 发布:oracle数据库统计分析 编辑:程序博客网 时间:2024/05/18 15:55


交叉验证是机器学习算法中常用的一种评价算法的方法。Weka的Explorer提供了非常简单的用户UI,这让大部分人都能非常舒服的使用交叉验证。但是,如果你想自定义一些算法,或者想做一系列实验却又不想挨个挨个的手去点击的话,可能你需要用直接使用weka的jar来调用算法和交叉验证。

其实大部分的算法在weka的文档和其源码的设计上都是非常清晰的,只需简单几分钟就能让人迅速学会如何使用。不料,昨天我正想做100组需要交叉验证的实验,却发现这交叉验证的实现真的让人摸不着头脑。经过长时间研究,终于是能够正常使用了,这里简单总结一下,顺便让需要的人少走弯路。


首先必须明白一次实验后结果产生的流程:

Weka 使用一个接口 ResultProducer 来产生结果,结果会直接传送给一个指定的ResultListener。最终通过操纵ResultListener来获得实验结果。下面通过一个例子来详细分析


//该例中,我使用随机森林算法(randomforest)作为分类器。默认使用10倍交叉验证//读入数据集DataSource source = new DataSource("2006distanceClusters.csv");Instances instances = source.getDataSet();//注意:必须设置类标签。我的数据集中,类标签为最后一个属性instances.setClassIndex(instances.numAttributes() - 1);//初始化分类器,你可以使用其他分类器RandomForest randomForest = new RandomForest();String options[] = new String[2];options[0] = "-I";options[1] = "10";randomForest.setOptions(options);//SplitEvaluator 用来实现对数据的划分,在此需设置分类器为之前我们初始化的分类器。//分类器和SplitEvaluator二者已经关联起来了ClassifierSplitEvaluator  sv = new ClassifierSplitEvaluator();sv.setClassifier(randomForest);//交叉验证的ResultProducer类,用来实现交叉验证,需设置其使用的SplitEvaluator。CrossValidationResultProducer cvrp = new CrossValidationResultProducer();//设置SplitEvaluator为刚刚实例化的svcvrp.setSplitEvaluator(sv);//设置将使用的数据集集。这样,数据集,分类器,SplitEvaluator和CrossValidationResultProducer都已经关联起来了cvrp.setInstances(instances);//因为上面的CrossValidationResultProducer会生成10次结果(因为是10倍交叉),所以需要另一个ResultProducer来生成平均后的结果。这个//ResultProducer就是这里使用的AveragingResultProducerAveragingResultProducer arp = new AveragingResultProducer();//设置AveragingResultProducer的结果来源。这里需要注意的是AveragingResultProducer是非常特殊的一个ResultProducer。因为它同时实现了//ResultProducer接口和ResultListener接口。所以它能够接收来自其他ResultProducer产生的结果,并产生新的结果。arp.setResultProducer(cvrp);//这句多余arp.setInstances(instances);//最后设置接收来自AveragingResultProducer结果的ResultListener。这里采用的是CSVResultListener,能够直接将结果写csv文件CSVResultListener csvListener = new CSVResultListener();arp.setResultListener(csvListener);//设置输出的文件File file = new File("result.csv");csvListener.setOutputFile(file);//这里很奇怪了,必须调用这一句,否则必出问题。Weka的文档没有做出明确解释,所以很难揣测这里是在做什么。这里也是让我久久没有测试成功的地方arp.preProcess(arp);//进行试验!参数为int。不同的值代表不同的划分。arp.doRun(0);String[] key = new String[30];String[] result = new String[30];//最后接收结果。搞定!csvListener.acceptResult(arp, key, result);

可以看出,整个过程真的比较繁琐。尤其是一些没有明确解释的方法让人很难受。不过至少看来是能够运行了,该例最后的结果会直接写文件。

遗憾的是,我任然没有找到方法能够从key和result两个数组中读出结果。如有人知道,请赐教.

0 0