朴素贝叶斯分类

来源:互联网 发布:java比较好的书籍 编辑:程序博客网 时间:2024/04/19 18:09

摘自写在公司内部的wiki



要解决的问题:

表中增加字段classification,有四个取值:0:初始值,未分类、1:positive、2:normal、99:negative

review submit前,由朴素贝叶斯分类器决定该条review的flag属于negative还是positive

 

分类器分为两部分

训练脚本

贝叶斯公式:P(B|A) = P(B) * P(A|B) / P(A)

在本问题中我们需要求以下两个值:

  • P(positive | 当前review) = P(positive)* P(当前review | positive) / P(当前review)
  • P(negative| 当前review) = P(negative)* P(当前review | negative) / P(当前review)

然后比较这俩数的大小,比如P(positive | 当前review) > P(negative| 当前review) ,那么当前review就是positive,反之

由于P(当前review)都是一样的,因此等号左正相关等号右,可以忽略掉分母,直接求分子的值

这里用P(negative)* P(当前review | negative) 举例,将公式简化为P(n)* P(R | n) 

P(n) = 训练集中negative的总数 / 训练集总数

R由一个个单词w1,w2,w3 ... wi 组成,因此P(R | n) = P(w1,w2,w3 ... wi | n)

朴素贝叶斯假设各条件无关,因此将公式展开为 P(w1 | n)* P(w2 | n) * P(w3 | n) ... * P(wi | n)

这样只需要知道每个单词在negative的review所有单词中出现的概率就可以求得P(wi | n)

 

实际实现中想到了有一种情况,那就是一个单词在positive中出现了N次,结果在negative中出现了0次,乘积就变成了0,因此将公式转换为求log值,就不会出现上述情况

log(P(n)* P(R | n) )

= log(P(n)) + log(P(R | n))

= log(P(n)) + log(P(w1 | n)* P(w2 | n) * P(w3 | n) ... * P(wi | n))

= log(P(n)) + log(P(w1 | n))+ log(P(w2 | n))+ ... + log(P(wi | n))

 

训练脚本需要维护三个map到redis中,map<keyword, count> negative、map<keyword, count> positive和map<keyword, count> normal;一并将P(negative)和P(positive)记录到缓存中

把训练集按照review rating字段分为negative集、positive集和normal集

positive: approved且星级>=4 
negative: delete状态为1 或者是unapproved且星级不等于3 
normal:approved且星级<4,unapproved 且星级=3,且 非delete状态

 

使用分类器区分review

当一条review需要入库,首先分词,匹配各单词的P(w | n)求得P(positive | 当前review)和P(negative| 当前review)作比较即可求出这条review的flag

原创粉丝点击