利用貝葉斯公式通過python過濾垃圾郵件

樸素貝葉斯公式

樸素貝葉斯公式

也可以簡寫為:


轉載請注明出處:Michael孟良

其中:

P(A)叫做A事件的先驗概率,即一般情況下特漩,認為A發(fā)生的概率黄娘。

P(B|A)叫做似然度,是A假設條件成立的情況下發(fā)生B的概率天通。

P(A|B)叫做后驗概率泊窘,在B發(fā)生的情況下發(fā)生A的概率,也就是要求的概率像寒。P(B)叫做標準化常量烘豹,即在一般情況下,認為B發(fā)生的概率诺祸。

理解樸素貝葉斯

假設現(xiàn)在有一堆郵件携悯,正常郵件的比例是80%,垃圾郵件的比例是20%序臂,這堆郵件中蚌卤,5%的郵件中出現(xiàn)Viagra單詞,如果有一封郵件奥秆,這封郵件中包含Viagra單詞,求這封郵件是垃圾郵件的概率咸灿。



顯然不能使用5%*20%=1%得到這封郵件是垃圾郵件的概率构订,因為垃圾郵件中有可能出現(xiàn)Viagra也有可能不會出現(xiàn)Viagra單詞。那么根據(jù)貝葉斯公式可得包含Viagra單詞的郵件是垃圾郵件的概率為:


P(spam)是已知20%避矢,P(Viagra)也是已知 5%悼瘾,那么如果求出P(Viagra|spam)的概率,結果就可以知道审胸。我們可以根據(jù)郵件的數(shù)據(jù)集統(tǒng)計得到單詞頻率表:

其中P(spam|Viagra)表示在垃圾郵件中出現(xiàn)Viagra單詞的概率亥宿,通過統(tǒng)計得出為4/20∩芭妫可以得出如果一封郵件中有Viagra單詞烫扼,這封郵件是垃圾郵件的概率為:



通過同樣的計算可以得到,含有Viagra單詞但不是垃圾郵件的概率為0.2碍庵。那么可以認為這封郵件是垃圾郵件的概率比較大映企。這里的Viagra可以理解為郵件中的一個特征悟狱。那么當一封郵件有額外更多的特征時,貝葉斯如何擴展堰氓?
假設所有歷史郵件中只出現(xiàn)了4個單詞挤渐,也就是4個特征,根據(jù)歷史郵件統(tǒng)計的單詞頻率表如下:



假設現(xiàn)在給定一封郵件中有Viagra和Unsubscribe(取消訂閱)兩個單詞双絮,求這封郵件是垃圾郵件的概率浴麻、不是垃圾郵件的概率?
利用貝葉斯公式囤攀,我們可以得到:

是垃圾郵件的概率:



最后約等于98.07%
不是垃圾郵件的概率:

最后約等于17.4%

拉普拉斯估計

根據(jù)以上例子白胀,假設有一封郵件這4個單詞都出現(xiàn)了,求這封郵件是垃圾郵件的概率:



由于P(W3)的概率為0/20抚岗,會導致整個結果是垃圾郵件的概率為0或杠,那么就否定了其他單詞出現(xiàn)的權重。

拉普拉斯估計本質上是給頻率表中的每個單詞的計數(shù)加上一個較小的數(shù)宣蔚,這樣就保證每一類中每個特征發(fā)生的概率非零向抢。通常,拉普拉斯估計中加上的數(shù)值為1胚委,這樣就保證了每一個特征至少在數(shù)據(jù)中出現(xiàn)一次挟鸠。

以上例子如果四個單詞都出現(xiàn)情況下計算是否是垃圾郵件,出現(xiàn)P(W3)的概率為0/20亩冬,可以增加4封垃圾郵件艘希,使4封郵件中每個郵件中只有一個單詞出現(xiàn),這樣就避免了垃圾郵件中有的單詞出現(xiàn)概率為0的情況硅急。同樣在不是垃圾郵件中也增加4封覆享,避免在正常郵件中出現(xiàn)有的單詞出現(xiàn)概率為0的情況。

Python 貝葉斯案例

# coding:utf-8

import os
import sys
import codecs


# #####################################################
# Multinomial Naive Bayes Classifier
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer

print('*************************\nNaive Bayes\n*************************')

if __name__ == '__main__':
    # read the file
    corpus = []
    labels = []
    corpus_test = []
    labels_test = []
    f = codecs.open("./sms_spam.txt", "rb")
    count = 0
    while True:
        # readline() read every line营袜,including "\n"
        line = f.readline().decode("utf-8")
        # read the first line and ignore it
        if count == 0:
            count = count + 1
            continue
        if line:
            count = count + 1
            line = line.split(",")
            label = line[0]
            sentence = line[1]
            corpus.append(sentence)
            if "ham" == label:
                labels.append(0)
            elif "spam" == label:
                labels.append(1)
            if count > 5550:
                corpus_test.append(sentence)
                if "ham" == label:
                    labels_test.append(0)
                elif "spam" == label:
                    labels_test.append(1)
        else:
            break
    # 文本特征提热龆佟:
    #     將文本數(shù)據(jù)轉化成特征向量的過程
    #     比較常用的文本特征表示法為詞袋法
    #
    # 詞袋法:
    #     不考慮詞語出現(xiàn)的順序,每個出現(xiàn)過的詞匯單獨作為一列特征
    #     這些不重復的特征詞匯集合為詞表
    #     每一個文本都可以在很長的詞表上統(tǒng)計出一個很多列的特征向量
    # CountVectorizer是將文本向量轉換成稀疏表示數(shù)值向量(字符頻率向量)  vectorizer 將文檔詞塊化,只考慮詞匯在文本中出現(xiàn)的頻率
    # 詞袋
    vectorizer = CountVectorizer()
    # 每行的詞向量荚板,fea_train是一個矩陣
    fea_train = vectorizer.fit_transform(corpus)

    print("vectorizer.get_feature_names is ", vectorizer.get_feature_names())
    print("fea_train is ", fea_train.toarray())

    # vocabulary=vectorizer.vocabulary_ 只計算上面vectorizer中單詞的tf(term frequency 詞頻)
    vectorizer2 = CountVectorizer(vocabulary=vectorizer.vocabulary_)
    fea_test = vectorizer2.fit_transform(corpus_test)
    print("vectorizer2.get_feature_names()",vectorizer2.get_feature_names())
    print("fea_test.toarray()",fea_test.toarray())

    # create the Multinomial Naive Bayesian Classifier
    # alpha = 1 拉普拉斯估計給每個單詞個數(shù)加1
    clf = MultinomialNB(alpha=1)
    clf.fit(fea_train, labels)

    pred = clf.predict(fea_test);
    for p in pred:
        if p == 0:
            print("正常郵件")
        else:
            print("垃圾郵件")

sms_spam.txt:

type,text
ham,you are having a good week. Just checking in 00 00 00 0089 0089
ham,K..give back my thanks.
ham,Am also doing in cbe only. But have to pay.
spam,"complimentary 4 STAR Ibiza Holiday or £10,000 cash needs your URGENT collection. 09066364349 NOW from Landline not to lose out! Box434SK38WP150PPM18+"
...

邏輯思路:

sms_spam.txt有5560條數(shù)據(jù)凤壁, 取5550條數(shù)據(jù)作為訓練,后十條作為測試數(shù)據(jù)跪另。每一行的第一個詞是這份郵件的類型拧抖,就是之前已經(jīng)人為判斷過,ham表示它為正常郵件免绿, spam為垃圾郵件唧席。
這里labels就是收集人為判斷的結果

    # 詞袋
    vectorizer = CountVectorizer()
    # 每行的詞向量,fea_train是一個矩陣
    fea_train = vectorizer.fit_transform(corpus)

vectorizer 拿到所有郵件的所有單詞,fea_train 是所有郵件每個詞在每份郵件出現(xiàn)的次數(shù)袱吆,相當一個矩陣厌衙。

# create the Multinomial Naive Bayesian Classifier
# alpha = 1 拉普拉斯估計給每個單詞個數(shù)加1
clf = MultinomialNB(alpha=1)
clf.fit(fea_train, labels)

這里 alpha = 1 ,就是前面講到的拉普拉斯估計绞绒,給每個單詞個數(shù)加1婶希,防止它出現(xiàn)0的情況。
fea_train是訓練出來的矩陣蓬衡,labels是人為判斷的結果喻杈,把他們fit到clf里面。

pred = clf.predict(fea_test);
for p in pred:
    if p == 0:
        print("正常郵件")
    else:
        print("垃圾郵件")

fea_test是后面十條的數(shù)據(jù)狰晚,把它放到我們之前訓練好的貝葉斯模型clf筒饰,然后預測出這十條數(shù)據(jù)。

打印出來的結果

代碼:https://github.com/MichaelYipInGitHub/PythonTest/tree/master/com/test/bayes

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末壁晒,一起剝皮案震驚了整個濱河市瓷们,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秒咐,老刑警劉巖谬晕,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異携取,居然都是意外死亡攒钳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門雷滋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不撑,“玉大人,你說我怎么就攤上這事晤斩』烂剩” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵尸昧,是天一觀的道長揩页。 經(jīng)常有香客問我,道長烹俗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任萍程,我火速辦了婚禮幢妄,結果婚禮上,老公的妹妹穿的比我還像新娘茫负。我一直安慰自己蕉鸳,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潮尝,像睡著了一般榕吼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勉失,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天羹蚣,我揣著相機與錄音,去河邊找鬼乱凿。 笑死顽素,一個胖子當著我的面吹牛,可吹牛的內容都是我干的徒蟆。 我是一名探鬼主播胁出,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼段审!你這毒婦竟也來了全蝶?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤寺枉,失蹤者是張志新(化名)和其女友劉穎抑淫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體型凳,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡丈冬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了甘畅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埂蕊。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疏唾,靈堂內的尸體忽然破棺而出蓄氧,到底是詐尸還是另有隱情,我是刑警寧澤槐脏,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布喉童,位于F島的核電站,受9級特大地震影響顿天,放射性物質發(fā)生泄漏堂氯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一牌废、第九天 我趴在偏房一處隱蔽的房頂上張望咽白。 院中可真熱鬧,春花似錦鸟缕、人聲如沸晶框。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽授段。三九已至蹲蒲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侵贵,已是汗流浹背届搁。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留模燥,地道東北人咖祭。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像蔫骂,于是被迫代替她去往敵國和親么翰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容