weka使用朴素贝叶斯进行中文文本分类的试验,成功经验分享

网上找了两篇教程,但是有些错误,导致无法继续试验,通过摸索最终解决,将成功经验分享给大家,希望能帮到大家。NaiveBayes = 朴素贝叶斯

试验机器是hp g6 dl380,windows server 2012 R2 64位系统,300G硬盘,16g内存,Intel(R) Xeon(R) CPU E5520 @ 2.27GHz 单路4核8线程。

实验步骤:

1.下载weka数据挖掘软件,解压到系统,并安装目录中的jre。目前最新版下载地址:Weka 中文版 v0.4 发布 基于weka 3.7.12 x64

2.双击目录中的Weka 3.7快捷方式,窗口出现后,点击SimpleCli命令行工具按钮。

3.下载数据集或者使用自己的数据集也可以

使用的是路透新闻语料Reuters21578,直接下载的数据集不适合weka处理,需要转换成arff格式。可以从此处下载厦门大学邹博士已经处理好的数据
Reuters21578-Apte-90Cat

如果是自己的数据集,可能需要进行中文分词,包括去掉英文标点符号,停词处理等,现成的工具有计算所开发的汉语分词系统(http://ictclas.org/)等。

需要注意的是,由于是中文,所有文本文件的编码都必须为utf-8,可以用记事本另存为,选择编码为utf-8,或者使用你自己上手的工具。

4.数据预处理

Reuters21578-Apte-90Cat数据集解压后,训练数据和测试数据分别放在不同的目录下,并且还有下一级的子目录,在子目录中每个类别与一个文件夹对应,这个文件夹下放的就是对应类别的文本文件,每一个文本文件里都是空格分隔的词语,就是你前面中文分词后的结果。如果是你的数据,你也应该按照这个格式组织,便于以后分析挖掘使用。我的文件和子文件夹全部组织在D:\downloads\example\example下了。敲命令的时候路径可以用/或\表示,我的系统是兼容这两种路径分隔符的。本例为了简便起见,将同一个数据集分别作为训练集和测试集。

(1)将所有训练目录下的文本文档转换为一个arff文件:

java weka.core.converters.TextDirectoryLoader -dir D:\downloads\example\example > D:\downloads\example\arff/data.arff

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

(2)使用过滤器将文本转换为矢量(以下获取的是TF-IDF特征)

java weka.filters.unsupervised.attribute.StringToWordVector -I -C -i D:\downloads\example\arff/data.arff -o D:\downloads\example\arff/data_vsm.arff -c last

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

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

-I  将词频转化为fij*log(文档数目/包含词i的文档数目)(即TF-IDF特征),fij是词i出现在文档j里面的频率

后面的选项是通用的选项:

-i  输入

-o  输出

-c  指明类标签的位置,last表明标签为最后一个属性,first表明标签为第一个属性。

(3)数据离散化

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

java weka.filters.supervised.attribute.Discretize -i D:\downloads\example\arff/data_vsm.arff -o D:\downloads\example\arff/data_D_vsm.arff -c first

(4)数据分为训练集和测试集

训练集:
java weka.filters.supervised.instance.StratifiedRemoveFolds -i D:\downloads\example\arff/data_D_vsm.arff -o D:\downloads\example\arff/data_vsm_train.arff -c first -N 4 -F 1 -S 10 -V

同样可以参见StratifiedRemoveFolds类说明:

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

-F 1  指定第1折被选中

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

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

这里需要注意下,我用的这个版本如果不加-S 10选项的话,-V选项会报非法选项错误:Illegal options: –V ,这也是我的一个weka群友在做实验时遇到的错误,导致后面arff文件结构错误、模型错误、结果文件头无效等一系列错误。具体可以看这篇:

weka中文文本分类遇到几个错误

测试集:
java weka.filters.supervised.instance.StratifiedRemoveFolds -i D:\downloads\example\arff/data_D_vsm.arff -o D:\downloads\example\arff/data_vsm_test.arff -c first -N 4 -F 1 -S 10

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

5.模型训练

java weka.classifiers.bayes.NaiveBayes -t D:\downloads\example\arff/data_vsm_train.arff -k -d D:\downloads\example\arff/data_vsm_nb.model -c first

这里需要注意的是,原教程中带了参数-i,我这里报weka异常非法选项错误:Weka exception: Illegal options: -i
原教程有个重定向操作,实际是无效的也是不需要的。

6.在测试集上检验效果

java weka.classifiers.bayes.NaiveBayes -l D:\downloads\example\arff/data_vsm_nb.model -T D:\downloads\example\arff/data_vsm_test.arff -c first > D:\downloads\example\arff/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

115 22 | a = horror

88 512 | b = normal

7.模型使用

训练好的模型,文件是data_vsm_nb.model,已经序列化保存,后面可以使用-l,小写的L,用第6点里的命令,把测试集替换了直接使用即可。

java weka.classifiers.bayes.NaiveBayes -l D:\downloads\example\arff/data_vsm_nb.model -T D:\downloads\example\arff/data_vsm_test.arff -c first > D:\downloads\example\arff/data_vsm_NB_r.txt

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

java -Xmx1024M -jar weka.jar

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

《weka使用朴素贝叶斯进行中文文本分类的试验,成功经验分享》有一个想法

评论已关闭。