1. 程式人生 > >樸素貝葉斯演算法學習及程式碼示例

樸素貝葉斯演算法學習及程式碼示例

       最近工作中涉及到文字分類問題,於是就簡單的看了一下樸素貝葉斯演算法(Naive Bayes),以前對該演算法僅僅停留在概念上的瞭解,這次系統的查閱資料學習了一下。樸素貝葉斯演算法以貝葉斯定理為理論基礎,想起大學時學習概率論與數理統計時,老師僅僅講授貝葉斯定理,卻沒有引申講一下樸素貝葉斯演算法。上學時,學習很多數學定理時,心裡都有個疑問,這個到底有什麼用?到底哪些領域用到了這個定理?但是老師往往就是按照所謂的講義、教學大綱授課,如果能做一下引申,相信大家對所學知識會有一個感性認識,理解的也會更深入,相信學習也會更有積極性。        那麼,到底什麼是樸素貝葉斯演算法呢,基本可以一句話概括:貝葉斯定理 + 條件獨立假設。貝葉斯定理就是我們數理統計課上學的定理, P(A|B) = P(B|A) P(A) / P(B);而條件獨立假設指的是:解決分類問題時,會選取很多資料特徵,為了降低計算複雜度,那麼假設資料各個維度的特徵相互獨立。而演算法的計算過程也可以用一句話概括:把計算“具有某特徵的條件下屬於某類”的概率轉換成需要計算“屬於某類的條件下具有某特徵”的概率。整個演算法沒有什麼複雜的計算環節,無非就是計算概率,真的很樸素。由於網路上資料很多,我就不面面俱到的介紹了,下面是我學習該演算法過程中參考的一些連結,有純理論介紹,也有的詼諧幽默介紹。看了下面幾篇文章,樸素貝葉斯演算法應該基本掌握了。
上面文章中,提到樸素貝葉斯演算法訓練問題,我對訓練的理解是:開始迭代、梯度下降、更新權值w、偏至b,在打亂樣本,在迭代這個過程。而樸素貝葉斯里的訓練,其實並不是上述過程,而是一個構建查詢表的過程,對於離散特徵值,其實就是計算各種概率,然後把概率存起來,感覺就是一個數據預處理的過程,但是大家都這麼說,應該是我理解的訓練過於狹義了。而預測就是解析所有後驗概率,並找出最大值。所以所謂的訓練集其實也是可以作為測試集的,反正都是統計。        另外,根據資料特徵的資料型別,樸素貝葉斯演算法還可以分為三種模型:多項式、高斯、伯努利,不同的模型,適用不同的場景。當特徵值是離散的時候,使用多項式模型,如:文字中詞語的重複數;當特徵值是連續的時候,使用高斯模型,如:人的身高、體重;當特徵值取值僅為1和0時,使用伯努利模型,該模型相當於多項式模型的簡化版。
       下面是程式碼示例, 不過我並沒有從頭編寫樸素貝葉斯演算法,而是直接呼叫sklearn機器學習庫中的貝葉斯模組。剛開始用python不久,python程式碼寫的一般。寫python不像寫c,寫c程式碼時,基本寫完每一個程式碼塊都會考慮是不是最優,是不是最簡潔實現,有沒有及時釋放記憶體,甚至還會考慮cpu快取命中。而寫python,還談不上程式碼優化,僅停留在功能實現上。python版本為3.5,以樸素貝葉斯高斯模型為例,資料來自維基百科:根據身體測量特徵,判斷一個人是男性還是女性。                                                      

import numpy
from sklearn.naive_bayes import GaussianNB


def test_gaussian_nb():
    X = numpy.array([
        [6, 180, 12],
        [5.92, 190, 11],
        [5.58, 170, 12],
        [5.92, 165, 10],
        [5, 100, 6],
        [5.5, 150, 8],
        [5.42, 130, 7],
        [5.75, 150, 9],
    ])

    Y = numpy.array([1, 1, 1, 1, 0, 0, 0, 0])

    gnb = GaussianNB()
    gnb.fit(X, Y)

    test = numpy.array([6, 130, 8]).reshape(1, -1)
    result = gnb.predict(test)
    print(result)
    print("\n")

    result = gnb.predict_proba(test)
    print(result[0][0])
    print(result[0][1])


if __name__ == '__main__':
    test_gaussian_nb()
       下面是執行結果,從結果來看,對於身高6英尺,體重130磅,腳掌8英寸的某人,其性別為女。