目前所说的文本分类是通过机器学习的方式对文本进行分类。
首先给出各类文本的样例,也就是训练集,然后程序会通过统计方法找出各类文本背后隐藏的统计规律,比如某类文本中某些词出现的次数比较多,然后对未知类别的文本进行判断。
具体可以分为以下流程:
1. 构建训练集:通过人工方式对原始文本进行标定,比如分为垃圾邮件和正常邮件。训练集中各类文本最好能偶达到数目平衡,避免出现某一类特别多,另外一类特别少的情况(如果出现了,可以通过一系列方法进行弥补,比如最简单的“向下取样法”或者“向上取样法”)
2. 分词:词是最小的语义单元,能够很大程度上代表文本的语义信息。而中文词汇之间没有天然的间隔,因此需要进行分词,在中文句子中各个词之间加入空格,这里推荐python的jieba分词工具包。
3. 去停止词:不论是中文词汇还是英文词汇,都包含了大量的无意义词汇,比如“的”,“一个”,“所以”,“the”,“a”,“is”……这些词在任何一类文本中都会大量出现,因此对文本分类没有实际帮助,需要提前去处,百度文库中有中文停止词表,可以下载来用。
4. 降维:随便一个训练集中都会有几万个中文词汇,想都保留必然会导致计算成本加大。
4.1 文档频率法(DF,document frequency):
文档频率法就是每一个词在训练集中多少篇文档中出现过,比如“邮箱”这个词在10篇训练集文档中出现过(不用考虑它们在每篇文档中具体出现几次),那么“邮箱”的DF值就是10。
事实上这几万个词里面百分之60以上的词只在一个文本中出现过。这些词没有“代表性”,不能代表某类文本的特征(什么样的词能够代表一类文本的特征呢?应该是:在这类文本中出现的次数很多,在其它类文本中出现的次数很少的词)。同时,也会有一些词出现次数过多,比如步骤3中的停止词,它们出现的次数肯定是很多的,因此对于这类出现次数过多的词也应予以删除,因为它们没有“区分度”。具体操作中,一般DF值大的词数目都非常少(撑死了三五十),删掉它们对降维的帮助不大,而DF值小的词则很多,如果把DF值为1的词删掉,起码可以降低一半的维度。
4.2 卡方检验法(test of chi2)
这个方法大家可以参考《文本分类入门》这篇文献,讲得非常详细。具体代码实现可以看后续的博文。
那么降维到什么程度对分类没有影响呢?经过本人的试验,发现把8w个词降低到5000以内对分类结果毫无影响,甚至1000多维的时候仍然有很好的分类表现。因此,放心大胆地降维吧。
5. 分类预测
本人毕设课题是对百度知道的垃圾回复和正常回复进行分类预测,采用了KNN,SVM,Logistic Regression 以及 Naive Bayes 等传统的分类器。
前三种分类器都是基于空间几何思想的,最后一种是基于条件概率思想的。
讲到这里,不得不提一下 VSM 模型,所谓 VSM 模型就是 vector space model 的缩写。这个模型将文本表示成高维空间中的一个点,VSM模型的维度就是词表的单词总量,各条训练样本中每个词出现了几次,其在相应维度上的值就是几。
例如:经过了分词和初步的统计,我有如下训练样本:
False求:1种子:1好人:1一生:1平安:1邮箱:2 你懂得:1
False代表是垃圾回复(为啥是垃圾回复你懂得,O(∩_∩)O哈哈~)每个词后面带的数字是这个词在这条训练样本中出现的次数。
现在我的训练集词表中假设有11个词(为了举例方便定为10个词,实际上一个训练集即使经过了降维,也得有1000+的词){求,计算机,北航,好人,种子,数学,邮箱,你懂得,一生,自习,平安}
那么对照词表,我的训练集可以表示成:[1,0,0,1,1,0,2,1,1,0,1],这就是所谓的VSM模型。
把训练集中所有的正类和负类都通过上面的方法表示成 VSM 模型中的点,剩下的就是分类预测了。
KNN的思路是:
把待分类样本也对照词表(词表是统计训练集中所有出现过的词,然后去停止词、降维之后得到的)转换成向量,然后统计离它距离最近的K个点中,哪一类的训练文本数目多,就把它判定为哪一类。这里的“距离”可以是欧氏距离,也可以是各种其它奇葩的距离(大家请自行百度)。
KNN的原理简单,直观易懂,分类精度高,缺点是计算量大。
logistic regression 和 SVM 的思路是在空间中构造超平面,将两类文本的点(比如垃圾邮件和正常邮件,垃圾回复和正常回复)用超平面最大程度地分开,那么再输入一个待测文本点,可以根据这个点与超平面的相对位置(在它上方或者下方)来判断这个文本属于哪一类。
logistic regression 只能分类线性可分的问题,SVM通过构造核函数也可以分类线性不可分的问题。
朴素贝叶斯的基本假设是:每个词都是独立的,它的出现与否不受句子中其他词的影响(其实是不对的,肯定有影响,但是影响貌似不大,这种假设虽然“朴素”,但效果很好)。
条件概率公式:
P(T|A)=P(A|T)*P(T)/P(A)
可以这样解释上述公式:某个文本A,它属于正类T的概率,等于训练集里面正类文本中出现文本A的概率,乘以正类的概率,除以训练集中出现A的概率。
那么怎么计算P(A|T),也就是训练集里面正类文本中出现A的概率呢?这里就要用到那个“朴素”的假设了:
P(A|T)=P(a1|T)*P(a2|T)*……*P(an|T)
其中a1,a2,……,an代表A中的每个词汇,那么P(ai|T)就是在训练集正类中,ai出现的次数,除以训练集中的总词数。
P(T)就是用训练集中正类文本的数目除以总文本的数目,P(A)对判断结果没有影响,原因是不论计算正类还是负类的条件概率,都需要除以P(A),而我们只需要比较P(T|A)和P(F|A)的大小即可得出判断。
6. 测试
测试这一步的目的是评判分类方法的性能优劣,测试集的构造和训练集一模一样,只不过不参与分类器的训练,最后用训练集训练好的分类器,在测试集上跑一遍,看看分类器预测的标签和人工标定的标签差多少,就可以判断分类器好坏了。
评价指标有:准确率(查准率,Precision),召回率(查全率,Recall),F1值,关于这三个指标,将在后续博客中介绍。
责任编辑:张柳影