预备知识:
1)svm:svm(supportvectormachine)即支持向量机,是一种机器学习算法,2000年左右开始火爆,被认为是(2005年论文上写的)目前分类算法中最好的二个之一(还有一个是boost方法,即使用多个低分辨率的分类器线性组合成一个高分辨率的模式);根据它的原理,个人认为它和人工神经网络的计算公式本质一样,虽然它们的类切分方式不一样。至少svm是完全的基于超平面,利用核函数进行扩展。已有的证据表面对于基本的多分类来说,RBF(核函数)是效果还比较好的。
2)svm特点:svm具有一个其他分类方法(可能会有,但笔者不知道)都不具备的特点,即不用进行特征简约。特征简约是一个十分麻烦的问题,传统上面的(2000年论文)方法不过那么几种,最好的就是IG(informationgain)。但用在文本分类上面,传统的特征简约(feature selection/ dimensionality reduction)达到不了什么很好的效果。之前我们的一个项目就是人工进行特征简约的,大约花费了1人1周时间,效果还不怎么样(KNN算法,80%左右精度。KNN的平均性能比除了SVM的其他普通分类算法都好,有论文里面有实验结果)。现在使用的特征简约方法一般都会基于文本分类的特点,比如,会先进行特征的分类。svm则不需要进行特征简约!它具有很强的抗干扰能力,特别是,有人研究表明,大部分时候,不进行特征简约得到的精度比进行了特征简约之后得到的精度还要高。这或许是因为有些看起来十分没有用的词语,比如,“有限公司”,它可能也代表了一种很强烈的区分方式,比如,名字含有“有限公司”的公司可能一般都是纺织(石油)等行业。
3)svm分类精度:knn出现的时间很早了,在它出现之后,大量出现了各种机器学习算法,比如,决策树(decisiontree),人工神经网络,贝叶斯分类等等,可惜的是,研究结果表明,这些算法的平均分类精度居然还不如knn(一般差10%左右)。svm是第一个(论文里面说的)达到knn分类精度的分类算法。当然了,并不是说所有的时候,knn都最好,精度高不高,要看环境,要看使用者。
本文主要说明一下使用libsvm这个著名的软件来进行文本分类的具体方式。首先,请大家看看入门文章:http://ntu.csie.org/~piaip/svm/svm_tutorial.html。
现在假设大家已经看过入门文章,并且实际的操作过之后,我们来解决几个应用上的问题:
1)scale的必要性:scale就是把每个特征的值映射到[0,1]或者[-1,1]上面。首先应该明白,libsvm里面的svmtrain.exe是不要求输入的样本矩阵的每个值一定要在[0,1]或者[-1,1]范围的。那为什么要把值映射到这2个范围内呢?2个原因:a)为了计算速度;b)为了计算精度。第一个原因在入门文章里说的很清楚了,那第二个原因是怎么回事呢?在使用easy.py进行c和g参数选择的时候,会在某个范围内进行选择的,问题就是在这里。这个范围是一个小范围,只有在特征的值都在上述范围的时候,才比较有可能从这个范围中找到很好的参数。
2)scale的处理:scale的处理方法有多种,但是,libsvm里面提供的svmscale.exe是很不好的一种。为什么?因为它的算法是基于样本列表的。可能会发生将来待分类的数据的特征值都比较大,最后会被分到同一个类里面!所以,你自己需要做一个scale的方法来处理这类情况。一个简单的做法就是,给每个特征一个最大的可能值,然后再线性映射到[0,1]上面。注意,是[0,1],不是[-1,1],这是因为文本分类的时候,得到的特征向量里面,大部分特征的值都为0,映射到[0,1]可以加快计算速度。
3)easy.py的说明:仔细的分析easy.py里面的命令代码,你可以看到,easy.py做了几件事:a)调用svmscale.exe来scale原始样本向量;b)遍历预设的c和g参数;c)调用svmtrain.exe的交叉检验功能(-v参数)来计算c和g参数的精度;d)获得一个最好的精度,根据对应的c和g计算一个模型。如果你已经scale过输入了,就应该在这里把第一步注释掉,因为默认是把值scale到[-1,1]范围。
4)提高计算速度:文本分类的时候,特征一般选取为词语(关键词),特征的值一般选取为词语的出现次数。这样一来,数据的空间维度很高(经常是5K-10K之间)。easy.py会扫描大约11*10=110次,每次都调用svmtrain.exe的交叉检验功能,而svmtrain的交叉检验功能,需要n(样本分成n份进行交叉检验)次计算和(n-1)*n次predict。反正就是说,easy.py运行一次,时间很长很长,一般在110*5*(2-10)分钟左右。提高计算速度的方法至少有:a)svmtrain.exe的-m参数,设置cache特别大(800M?);b)修改easy.py里面的c和g的范围,然后跑多个进程(多cpu时)。
简简单单的使用libsvm,在理解了svm的基础上,你就会发现,文本分类非它莫属了。
后记:
1)特征选取:
2)特征值的计算:
3)文档分类: