之前做了一个简单的中文文本分类系统,采用的是朴素贝叶斯的算法,现在回顾一下并详细给出每一个步骤。若有源代码需求,请移步 https://github.com/chenfei0328/BayesProject
一、文本预处理
1.格式问题,比如删空格,删换行符等。
2.jieba分词 https://github.com/fxsjy/jieba
二、建立向量空间模型
1.加载训练集,每一篇文档作为一行数据,n篇文档则有n维。
2.生成词典,把训练集中每一个出现过的词添加到词典中,同时删除存在于停用词表(比如“的”)中的词。
实例:
词典=【我,是,中国,人,啊】
文本1=【我,是,人】
文本2=【中国,人,是,人】
a.建立tf矩阵(表示每一篇文档的词频信息)
(1)将每一篇文档投射到词典中,在词的索引位置处记录该词出现的次数。
文本1=【1, 1, 0, 1, 0】
文本2=【0, 1, 1, 2, 0】(词典中的“人”在该文本中出现两次)
(2)接下来,对整型计数方式进行归一化,可以避免句子长度不一致问题。
文本1=【1/3, 1/3, 0, 1/3, 0】
文本2=【0, 1/4, 1/4, 2/4, 0】
b.建立idf向量(表示整个词袋中的词频信息)
(1)词条的文档频率。
【1/2, 2/2, 1/2, 2/2, 0/2】
为了防止“0”在ln表达式中出现,故将分子分母各加“1”(或者用拉普拉斯原理进行处理)
【2/3, 3/3, 2/3, 3/3, 1/3】
(2)IDF权重。
【ln(3/2), ln(3/3), ln(3/2), ln(3/3), ln(3/1)】
c.建立tf-idf矩阵
tf矩阵的每一行都乘以idf权重向量。
文本1【1/3ln(3/2), 1/3ln(3/3), 0, 1/3ln(3/3), 0】
文本2【0, 1/4ln(3/3), 1/4ln(3/2), 2/3ln(3/3), 0】
每一条文本中数值最大的那个词就是该文档代表性最强的词,成为关键字。
三、贝叶斯分类器
2.生成类别标签,统计某一文档属于某一类的概率
{0:0.1,1:0.9} (键为类别标签,键值为该类的文档数所占比例)
3.生成条件概率矩阵
a.将TFIDF矩阵中属于相同类别的文档向量相加,形成m*n的矩阵,m代表类别数,n代表词典数。
【【1,2,0】
【0,1,1】】
b.将每一个词的权重除以该类所有词的总权重
【【1/3,2/3,0】
【0,1/2,1/2】】
四、应用
1.将测试文档经过jieba分词后映射到词典形成向量,如果有测试词在词典中不存在,则可删去该词(在词典中查找,若找到,则该词所在索引位置+1,若不存在,则跳转至下一个词)。
2.计算max{ P(x1|yi) * P(x2|yi) * …… * P(xn|yi) * P(yi) },输出最大值所对应的yi,即类别。
a.由于P(xn|yi)可能等于0(可在算法其他步骤中解决该问题),会导致输出结果总是等于0,这不符合要求,因此我在该式外层套上一个ln函数。
式子变成:max{ ln(P(x1|yi) * P(x2|yi) * …… * P(xn|yi)) * P(yi) }
等价于:max{ (ln(P(x1|yi)) + ln(P(x2|yi)) + …… + ln(P(xn|yi))) * P(yi) }
b.由于测试数据中可能包括n个某一特征,故应将条件概率乘上这个n权重。
式子变成:max{ (ln(n1 * P(x1|yi)) + ln(n2 * P(x2|yi)) + …… + ln(nn * P(xn|yi))) * P(yi) }
c.如果n=0,则会超过ln函数定义域,采取+1方法。
式子变成:max{ (ln(n1 * P(x1|yi) + 1) + ln(n2 * P(x2|yi) + 1) + …… + ln(nn * P(xn|yi) + 1)) * P(yi) }