之前从来没写过文章,这是第一篇,希望自己能把这个习惯坚持下去,算是给自己定期做个总结,也希望能在这里跟大家交流一下心得。
以前一直在做system & network方面的工作,没有怎么接触过datamining,不过马上要去的公司在这方面很有建树,估计去了以后也免不了接触这些知识,更何况bigdata现在是最热门的话题,所以在学校的最后一个学期选了datamining这门课,先入个门,以后有机会的话再深入研究。
目前用weka做了一些简单的数据分析的工作,发现这个工具还是很强大的,所以写这篇文章简单介绍一下weka。
Weka(Waikato Environment for Knowledge Analysis) 由新西兰的Universityof Waikato研发,是一款基于java的machinelearning的软件套件。用户可以使用weka提供的可视化界面,也可以使用weka提供的api开发满足特定需求的模型和算法。同时weka也支持加载开发者自己开发的extensionpackages,所以在weka下几乎能找到了所有现在比较流行的datamining模型和算法的实现。
Weka现在有windows,linux以及mac os版本,可视化界面基本上是一样的。下面用几个例子简单介绍一下如何用weka进行简单的datamining的工作。
训练classifier:
首先在Preprocess标签下,点击Openfile选择一个你要打开的dataset,这个dataset需要符合一定的文件格式才能被weka解析,最常用的是arff格式的文件,所以最好先将你的dataset转换成这个格式的文件。打开文件后,weka会自动解析数据,并且显示关于这个dataset的统计信息在图形界面上。比如这个dataset含有多少instances,每个instances有多少attributes,attributes的分布情况,而且提供可视化图像使得数据更加直观。
如果要做一个简单的classifier的训练,首先我们打开一个weka自带的dataset :breast-cancer.arff,这是一个关于患者乳腺癌是否复发的dataset,数据比较简单,每一个instance代表一个病人,有9个attributes,包括age,tumor-size等等,所有attributes都是nominal属性的,每一个instance带有一个class属性,no-recur或者recur。
现在我们选择一个classifier来进行训练。切换到Classify标签下,点击Choose选择一个classifier,在weka-classifier-trees下选择DecisionStump,此时点击Choose旁边的文本栏可以设置DecisionStump的具体参数,调整完毕之后选择如何进行测试,这里我们选择使用cv进行测试,folds选择10,点击Start,好了,weka就会开始使用我们的dataset并且按照我们调整的参数来和训练方法来训练classifier了。训练完毕后classifier的结构以及测试结果都会输出在output栏,你可以很直观地看到当前模型的训练成果。拿我们这个例子来说,因为DecisionStump模型是在太过简单,仅仅根据deg-malig属性是否等于3来进行分类,正确率仅有68%左右。让我们换一个classifier再试试,这次我们选择J48,这是一个C4.5的实现。如果只是选择默认参数并且不prune的话,我们会发现训练出来的tree结构非常复杂,并且分类效果依然很差,仅有69%左右,很明显,训练出的模型出现了overfitting。此时我们设置一下J48的属性,将unpruned的参数调增为False,即允许prune,再次进行训练,可以看到,这次训练出来的tree结构得到了极大的简化,并且正确率也提升到了75%。当然,要想得到好的结果还需要进行参数调整,我们这里只是使用了默认设置。再换一个knnclassifier试试,选择weka-classifiers-lazy下面的IBK,并且设置它的KNN参数为5,即使用离输入点最近的5个样本点作为分类参考,训练完成后分类准确率在73%左右。
Unbalance数据预处理:
有时候我们的dataset会有严重的unbalance问题,会导致classifier建模过程受到极大影响。比如我曾经使用过一个dataset,数据总量为9688,但是其中8704个instances为class 0,而剩下的984个instances为class 1。使用J48训练过后,class0的分类效果较为理想,准确率可达96%,但是class1因为训练样本量过小,准确率仅有32%。在选择dataset时,我们应尽量保证其中的数据在各个class之中是平衡的,并且如实反映真实世界中的数据分布。如果手头数据偏差过大,那么我们就需要在将数据送入classifier进行训练之前对数据进行一些预处理。这里我们讨论两个比较典型的做法。
第一个是undersampling,即从class占比例较大instances中sample出一部分数据,从而和class占比例较小的instances组成更为均衡的dataset。在Preprocess标签下,在Filter下点击Choose,在weka-supervised-instance下选择SpreadSubsample,然后设置参数,其中distributionSpread选择1.0,代表uniformdistribution,使得从majorclass 中sample出的instances数量和minorclass保持一致,然后点击Apply,这时候我们得到的dataset 其中class 0和class 1的instances都是984个,这样就可以进行后续的数据处理了。
第二个是oversampling,我们讨论一个比较常用的算法:SMOTE,这个算法的特点是可以根据原有数据的特点生成原本不存在dataset里的instances,从而扩充minor的dataset。同样在weka-supervised-instance下选择SMOTE,然后设置参数,classValue采用默认值,这样SMOTE会自动识别哪一个class的数量是少数,并进行扩充,在percentege中选择你想要将minorclass的instances扩充到多少比例,比如我的数据中class0的数据有8704,而class1的数据有984,那么可以设置percentage为800,那么扩充后的class1就可以和class0保持平衡。结果显示class0的数据数量不变,而class1的数据量变成了8856.
数据降维:
使用weka还可以很方便的进行数据降维。当一个dataset中attributes太多的时候,会出现curseof dimensionality,这是因为数据维度空间过于复杂而造成数据难以处理。此时进行适当的降维就在所难免。我们这里也讨论两个weka中比较常用的降维方法。
第一个是使用weka的InfoGainAttributeEval进行attributes选择。基本原理是通过计算每一个attribute对于降低entropy的贡献来进行排序,然后选择排序较高的留下来,去掉排序较低的attributes,从而达到降维的目的。切换到Selectattributes标签下,选择weka-attributeSelection下的InfoGainAttributeEval,然后再选择一个SearchMethod,比如我们选择Ranker,然后设置Ranker的threshold为0.2,意思是去掉所有InfoGain低于0.2的attributes,那么剩下的attributes就是对分类作用比较大的。以我手头的一个dataset为例,降维后attributes数量从524降到了128。我们可以保存这个dataset到新的arff文件中。
第二个方法是PCA。基本思想是不删除任何一个attribute,但是将原有的attributes进行线性组合,从而生成一组新的attributes,但是数量远小于原有attributes,从而达到降维的目的。同样在weka-attributeSelection下选择PrincipalComponents,即可进行PCA降维,降维后的dataset同样可以保存并进行后续处理。
我使用的weka版本是3.7.13-snapshot,这个版本虽然不是稳定版,但是这个版本有一个可视化的Packagemanager,可以十分方便的添加你所需要的package,比如我在使用的过程中需要的SMOTE,LibSVM以及GridSearch这些算法和模型的实现,都可以很方便地在这里找到,省去了手动配置的麻烦。