Weka使用笔记之一

前些日子基于weka初步做了一下文本分类,使用的是最频繁使用的矢量空间模型(Vector Space Model),即假设正负样本在特征空间的分布迥异,基于某种规则将它们转化为矢量,然后训练分类器来区分这些矢量,测试样本来时送进分类器进行分类就行。在我的实验里面,特征降维使用的是基于TFIDF的特征选择,分类器使用的是朴素贝叶斯(naïve bayes)分类器。

 

前期预处理

编码不一致:由于我的中文样本是从网站各个地方收集来的,因此编码很可能不一致,有的是ANSI,有的是Unicode,需要统一编码便于后续处理。本实验里面,所有的文本都被统一成ANSI编码。下载一个文本编码转换器(TxtEdit)即可转换。

中文分词:由于样本是中文文本,因此需要进行中文分词,包括去掉英文标点符号,停词处理等,现成的工具有计算所开发的汉语分词系统(http://ictclas.org/)等。

 

Weka进行分类

Weka功能实在是太强大,剩下的事情可以全部交给weka做了。

先引用weka中文论坛的资料介绍下Weka:

WEKA的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),它的源代码可通过http://www.cs.waikato.ac.nz/ml/weka得到。同时weka也是新西兰的一种鸟名,而WEKA的主要开发者来自新西兰。
WEKA作为一个公开的数据挖掘工作平台,集合了大量能承担数据挖掘任务的机器学习算法,包括对数据进行预处理,分类,回归、聚类、关联规则以及在新的交互式界面上的可视化。如果想自己实现数据挖掘算法的话,可以看一看weka的接口文档。在weka中集成自己的算法甚至借鉴它的方法自己实现可视化工具并不是件很困难的事情。2005年8月,在第11届ACM SIGKDD国际会议上,怀卡托大学的Weka小组荣获了数据挖掘和知识探索领域的最高服务奖,Weka系统得到了广泛的认可,被誉为数据挖掘和机器学习历史上的里程碑,是现今最完备的数据挖掘工具之一(已有11年的发展历史)。Weka的每月下载次数已超过万次。

 

介绍完毕,使用weka之前必须安装weka,具体参见weka中文论坛http://www.wekacn.org/index.php,注意weka的安装文件有带java运行环境和不带java运行环境的,按照自己的机器情况安装。

 

安装完weka以后,由于要处理的是中文文本,需要将安装文件夹内的RunWeka.ini文件打开,将fileEncoding的值Cp1252换成Cp936。

 

Weka使用的数据格式是arff,因此第一步是将txt转化为arff文件(命令行在GUI里面的Simple CLI键入,下同):

 java weka.core.converters.TextDirectoryLoader -dir my_data_folder > my_arff_save _path/data.arff

其中,my_data_folder是包含样本txt的文件夹,如果是二值化的分类问题,则该文件夹应该包含两个子文件夹,每个子文件夹装每个类的样本,多类的分类问题就是多个子文件夹,类同。子文件夹的名字就是该类的类标签,在生成的arff文件可以看到这一点。  my_arff_save _path是想要保存文件的目录,data.arff是生成的数据文件,也可以是自己想要的任何名字。

 

获得TFIDF数据,将文本转化为矢量:

java weka.filters.unsupervised.attribute.StringToWordVector -I -C -i my_arff_save _path/data.arff -o my_arff_save_path/data_vsm.arff -c last  

可以在weka的StringToWordVector类说明里面看到如下选项的意义:

-C  对word进行词频计数而不是二值化表示

-I  将词频转化为fij*log(文档数目/包含词i的文档数目),fij是词i出现在文档j里面的频率 后面的选项是通用的选项:-i  输入-o  输出-c  指明类标签的位置,last表明标签为最后一个属性,first表明标签为第一个属性。

注:在这篇文章http://fengshenbang.javaeye.com/blog/695153里面,指出了转化后产生的第一类的类标签缺失的情况,其实没什么问题,对后续的处理没有任何影响,实在不放心,也可以采用AddString方法修复。

 

转化后的数据还不能直接用来分类,需要进行离散化:

java weka.filters.supervised.attribute.Discretize -i my_arff_save_path/data_vsm.arff -o my_arff_save_path/data_D_vsm.arff -c first

注:-c的参数设置成了first后类标签已经成为属性的第一项

 

将数据分成训练集和测试集:

java weka.filters.supervised.instance.StratifiedRemoveFolds -i my_arff_save_path/data_D_vsm.arff -o my_arff_save_path/data_vsm_train.arff -c first -N 4 -F 1 –V

同样可以参见StratifiedRemoveFolds类说明:

-N 4  指定将数据集分成的折数为4

-F 1  指定第1折被选中

-V    取反,设置-V将导致剩下没被选中的作为输出

可以加个-S的选项在分折的时候随机选择样本

 

测试集:

java weka.filters.supervised.instance.StratifiedRemoveFolds -i my_arff_save_path/data_D_vsm.arff -o my_arff_save_path/data_vsm_test.arff -c first -N 4 -F 1

经过上述操作后,数据被分成了4折,其中3折作为训练集,还有1折数据作为测试集。

 

训练模型:

java weka.classifiers.bayes.NaiveBayes -t my_arff_save_path/data_D_vsm.arff -i -k -d my_arff_save_path/data_vsm_nb.model -c first > my_arff_save_path/data_vsm_nb.model

>为输出定位符,前后都要有空格

 

在测试集上检验效果:

java weka.classifiers.bayes.NaiveBayes -l my_arff_save_path/data_vsm_nb.model -T my_arff_save_path/data_vsm_test.arff –c first > my_arff_save_path/data_vsm_NB_r.txt

注:输出结果的data_vsm_NB_r.txt文件用记事本打开格式是乱的,用ultraedit之类的工具打开看的清楚。

 

在输出文件的最后可以看到分类结果:

=== Error on test data ===

 

Correctly Classified Instances         627               85.0746 %

Incorrectly Classified Instances       110               14.9254 %

Kappa statistic                          0.5842

Mean absolute error                      0.1487

Root mean squared error                  0.3852

Total Number of Instances              737     

 

 

=== Confusion Matrix ===

 

   a   b   <-- classified as

 115  22 |   a = horror

  88 512 |   b = normal

 

注:如果数据集过于庞大,可能会报out of memory的错误,这时候需要加大java虚拟机从操作系统所获得内存的大小,在java后加选项-Xmx1024m就能获得1024m的内存(当然,需要操作系统至少剩余这么大的内存才行),具体参数意义请参考http://sun-xyun.javaeye.com/blog/416054。也可以新建一个bat文件,直接获取1024m的内存启动weka:

java -Xmx1024M -jar weka.jar

一劳永逸的解决问题,从该文件启动weka,免得每一条命令都要带上-Xmx参数。

 

你可能感兴趣的:(IT)