您的位置:首页 > 其它

Weka 交叉验证相关类的使用

2014-07-02 16:56 423 查看
交叉验证是机器学习算法中常用的一种评价算法的方法。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为刚刚实例化的sv
cvrp.setSplitEvaluator(sv);

//设置将使用的数据集集。这样,数据集,分类器,SplitEvaluator和CrossValidationResultProducer都已经关联起来了
cvrp.setInstances(instances);

//因为上面的CrossValidationResultProducer会生成10次结果(因为是10倍交叉),所以需要另一个ResultProducer来生成平均后的结果。这个
//ResultProducer就是这里使用的AveragingResultProducer
AveragingResultProducer 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两个数组中读出结果。如有人知道,请赐教.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  机器学习 Weka 算法