問題:
判斷給定的一個評論是否為垃圾評論(spam)
大致:
應(yīng)用樸素貝葉斯公式計算該評論為垃圾評論的概率,如果大于一個指定值纯赎,則判斷該評論為垃圾評論
具體思路:
第一步
對于一個評論來說傅蹂,它由多個單詞組成,在考慮評論是否為垃圾評論的時候刨秆,先簡化問題為考慮包含某一個特定的單詞的評論是否為垃圾評論:
這個公式便是貝葉斯凳谦,它計算出了在已知某一個單詞的情況下這個評論是spam的可能性Pr(S|W),這個概率由先驗概率進(jìn)行計算衡未。
- Pr(S)代表了一個評論是spam的概率
- Pr(H)代表了一個評論是ham的概率
- Pr(W|S)代表了在spam評論中這個單詞出現(xiàn)的概率
- Pr(W|H)代表了在ham評論中這個單詞出現(xiàn)的概率
而以上的這些概率均可以通過已有的評論資源進(jìn)行獲取尸执,使用統(tǒng)計得到的頻率進(jìn)行替換家凯。值得一提的是,對于Pr(S)與Pr(H)來說如失,很多時候雖然大致的概率比在80%:20%绊诲,但經(jīng)過試驗,一般來說褪贵,不對需要判斷的評論做這個假設(shè)掂之,而認(rèn)為這個評論是垃圾評論或正常評論的概率是一樣的,所以公式中的Pr(S)與Pr(H)都設(shè)為0.5脆丁,約掉后公式簡化為
在計算公式中的兩項的時候世舰,也有一個值得注意的地方,以Pr(W|S)為例槽卫,計算垃圾評論中這個單詞出現(xiàn)的概率跟压,也有兩種方式,一種是晒夹,以評論為單位裆馒,該單詞出現(xiàn)的垃圾評論數(shù) / 總的垃圾評論數(shù),另一種是該單詞在垃圾評論中出現(xiàn)的次數(shù)(該垃圾評論中可能出現(xiàn)多個該單詞)/ 總的垃圾評論中的單詞數(shù)丐怯。本文最終使用的是前一種方式喷好。
第二步
在得到評論中出現(xiàn)某一個單詞它的垃圾評論的可能性后,要考慮的就是這個評論包含的所有的單詞對于這個評論是垃圾評論可能性的影響读跷。如果按概率論來討論所有的單詞出現(xiàn)在這個評論中的概率會十分復(fù)雜梗搅,這里就假設(shè)所有的單詞出現(xiàn)在這個評論中是條件獨立的事件,那么對于已知評論中所有的單詞效览,求這條評論為垃圾評論的概率的公式可以簡化為:
p1 = Pr(S|W1)
pn = Pr(S|WN)
這個條件獨立的假設(shè)也就是樸素貝葉斯里的樸素(Naive)无切,公式具體的解釋可以看http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_two.html
將所有的概率連乘計算得到整條評論的垃圾評論概率,雖然公式很簡單丐枉,但是在具體計算的時候哆键,由于概率都是0-1的浮點數(shù),所以為了避免出現(xiàn)向下的overflow瘦锹,在計算的時候使用了對數(shù)的加減法籍嘹,公式如下:
公式的具體解釋參看https://en.wikipedia.org/wiki/Naive_Bayes_spam_filtering#Combining_individual_probabilities
第三步
計算得到了概率之后,和一個閾值進(jìn)行比較弯院,如果大于這個閾值(0.9)辱士,那么就可以判斷這個評論為垃圾評論。
優(yōu)化
- 針對罕見詞听绳,可能在計算的時候出現(xiàn)概率為0颂碘,為了避免這種情況,可以有兩種方式優(yōu)化:
a. 拉普拉斯平滑
http://blog.csdn.net/xueyingxue001/article/details/52396170#t4
Pr(W|S)= (n1 + 1) / (n + N)
這里n1是該單詞在spam中出現(xiàn)的次數(shù)椅挣,n為垃圾評論數(shù)头岔,分子分母增加了1和N保證了這一項在任何情況下都不會為0塔拳,N為單詞的總類數(shù)。
b. 修正
s為3切油,n為單詞出現(xiàn)的全部次數(shù)蝙斜。
https://en.wikipedia.org/wiki/Naive_Bayes_spam_filtering#Dealing_with_rare_words
- 只有|Pr - 0.5|的越大,這個單詞才越能判斷這個評論是否為垃圾評論澎胡,越接近1說明這個單詞在垃圾評論中出現(xiàn)的概率遠(yuǎn)大于在正常評論中,越接近0則相反娩鹉,所以只取最有用的30個單詞攻谁,也就是|Pr - 0.5|最大的30個詞,用它們來計算概率弯予。
具體實現(xiàn):
分詞
中文分詞涉及到的內(nèi)容非常多戚宦,現(xiàn)在市面上提供分詞服務(wù)的也有很多,免費的付費的都有锈嫩,從成本考慮受楼,本文選擇了Ansj分詞,使用時只要添加Maven依賴就好呼寸。
<dependency>
<groupId>org.ansj</groupId>
<artifactId>ansj_seg</artifactId>
<version>5.1.1</version>
</dependency>
本文借助于Ansj實現(xiàn)的分詞器艳汽,目前使用的詞典文件由library.properties來配置,其中ambiguity.dic是歧義詞詞典对雪,synonyms.dic是同義詞詞典河狐,banwords.dic則是禁止詞詞典。
分詞器在分詞后瑟捣,將結(jié)果進(jìn)行過濾與處理:
- 過濾掉不需要的詞性馋艺,如標(biāo)點(w)、未知(null)
- 過濾掉不需要的單詞符號迈套,如“%”捐祠,“'”,“.”等
- 對同義詞進(jìn)行處理桑李,將具有相同意義的詞語以一個標(biāo)準(zhǔn)符號返回踱蛀。
- 對數(shù)字與英文符號進(jìn)行處理鳖链,數(shù)字返回"__NUM_SHORT__", "__NUM_LONG__", "__NUM_PHONE__"這些類別莲组,英文符號返回"__EN__", "__EN_MEANINGLESS__"附鸽,而鏈接地址返回"__URL__ "蔗喂,這樣不會出現(xiàn)太多數(shù)字與英文符號绝骚,也有助于后面的判斷蒸播。
處理之后的單詞符號結(jié)果就可以進(jìn)行判斷了茂腥。
spam判斷
-
流程圖
- 數(shù)據(jù)庫表
CREATE TABLE `T_EBK_TOKEN` (
`FID` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
`FNAME` varchar(32) NOT NULL COMMENT '詞語名',
`FSPAM_A` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '詞語出現(xiàn)的spam評論數(shù)',
`FHAM_A` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '詞語出現(xiàn)的ham評論數(shù)',
`FSPAM_B` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '詞語出現(xiàn)的spam單詞數(shù)',
`FHAM_B` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '詞語出現(xiàn)的ham單詞數(shù)',
PRIMARY KEY (`FID`),
UNIQUE KEY `UIDX_FNAME` (`FNAME`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8mb4 COMMENT='評論中詞語的spam|ham表'
其中的A與B分別代表了以評論為單位以及以單詞為單位兩種統(tǒng)計方法井联,實際使用中這兩種方式計算出來的結(jié)果差距并不大圈浇。
在表的第一行寥掐,F(xiàn)ID = 1靴寂,統(tǒng)計的是當(dāng)前所有評論的數(shù)量以及單詞數(shù)量,后面的每一行記錄是某一個單詞的結(jié)果召耘。
- 計算中的參數(shù)
a. 是否有預(yù)設(shè)百炬,也就是Pr(S)與(1-Pr(S))的值,沒有的情況下都為0.5污它,有的情況下根據(jù)數(shù)據(jù)進(jìn)行計算剖踊。
b. 使用拉普拉斯平滑處理罕見詞
c. 使用評論數(shù)或是單詞數(shù)進(jìn)行計算
模型訓(xùn)練
- 手動分揀數(shù)據(jù),得到一個垃圾評論數(shù)據(jù)集和一個正常評論數(shù)據(jù)集
- 分詞后對數(shù)據(jù)進(jìn)行更新衫贬。