1. 程式人生 > >樸素貝葉斯原理及python實現

樸素貝葉斯原理及python實現

一、貝葉斯演算法引入

      樸素貝葉斯演算法是基於貝葉斯定理和特徵條件獨立假設的分類法,是一種基於概率分佈的分類演算法

      貝葉斯分類演算法,通俗的來講,在給定資料集的前提下,對於一個新樣本(未分類),在資料集中找到和新樣本特徵相同的樣本,最後根據這些樣本算出每個類的概率,概率最高的類即為新樣本的類

       哈哈,先用個樣例來大體感受下。

       這裡有大學生戀愛情況的資料集,見下表:

        首先要注意的是,貝葉斯演算法的特徵都是離散值,如果是連續值,得先對連續值進行離散化處理。對於這個資料集,我們有三個特徵,即性別、專業和身高,戀愛情況為類別,1代表談戀愛了,0代表還是single dog。

        若我們現在有了一個新樣本,特徵為(男,計算機技術,高),那怎麼用貝葉斯演算法來判斷這個樣本的類呢,首先,我們要在資料集中找出和這個新樣本特徵相同的樣本,即下圖的紅色部分:

                          

      然後,根據戀愛情況所有的類別(即0,1),計算在這些特徵下每個類別的概率,概率最高的類即為新樣本的類別。

      在這裡先不進行計算操作,由表可以大體看出,在(男,計算機技術,高)這特徵下,戀愛情況為1的概率更大,即新樣本的類別為1。

二、貝葉斯演算法思想及其原理

      通過前文我們知道,貝葉斯演算法是依據概率來進行分類的,通過我們直觀的感覺,對於特定的樣本,哪個類概率大,我們就選誰

      那麼這麼做是以什麼為科學依據?為什麼這麼做會預測的效果最好?下面,我們先來說說貝葉斯的思想

假設每個樣本用一個n維特徵向量X={x1x2,…,xn}來表示,描述屬性為A1A2、…、AnAi之間相互獨立)。類別屬性為C,假設樣本中共有m個類即C1C2、…、Cm,如下圖所示

                                                                                                  

      給定一個未知類別的樣本X,樸素貝葉斯分類將預測X屬於具有最高後驗概率P(Ci|X)的類,也就是說,將X分配給類Ci,當且僅當:

  P(Ci|X)>P(Cj|X),1≤j≤m,i≠j

     根據貝葉斯定理有:

                                                                                                 

     由於P(X)對於所有類為常數,只需要最大化P(X|Ci)P(Ci)即可。而:

                                           

     所以對於某個樣本(a1,a2,…,an),它所在類別為:

                                                          

      思想簡單易懂,在沒有給出精確率召回率等評測標準前,還是無法讓人信服,那麼接下來,我們給出貝葉斯演算法的數學推到

      樸素貝葉斯演算法將例項分到後驗概率最大的類中,這就等價於期望風險最小化。假設我們研究的是二分類問題,選擇0-1損失函式。即:

                                              

     公式中f(X)是分類決策函式,這時期望風險函式為:

                                             

      我們知道,要想得到的結果最好,我們要做的就是將期望風險函式降到最低。好了,我們接下來要做的就是細節化風險函式,得出最優解。

      我們知道,期望是對聯合分佈P(X,Y)取的,由此取條件期望為:

                                        

      接著,對X=x進行逐個極小化,就可使期望最小,由此接著推:

                                    

     到此,我們就得到了樸素貝葉斯演算法的後驗概率最大化準則,即:

                                 

三、程式碼實現

#二分類樸素貝克斯分類器訓練函式
def trainNB0(trainMatrix,trainCategory):    #trainMatrix為輸入引數的文件矩陣,trainCategory為class標籤
    numTrainDocs = len(trainMatrix) #資料集中樣本的數量
    numWords = len(trainMatrix[0])  #資料集中特徵的數量
    pAbusive = sum(trainCategory) / float(numTrainDocs) #計算class為1的概率
    #初始化概率
    p0Num = zeros(numWords)     #初始化class為0的特徵
    p1Num = zeros(numWords)     #初始化class為1的特徵
    p0Denmo = 0.0
    p1Denmo = 0.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denmo += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denmo += sum(trainMatrix[i])
    p1Vect = p1Num/p1Denmo
    p0Vect = p0Num/p0Denmo
    return p0Vect,p1Vect,pAbusive	


#構建樸素貝葉斯分類函式
def classifyNB(vec2Classify,p0Vec,p1Vec,PClass1):
    p1 = sum(vec2Classify * p1Vec) + log(PClass1)
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - PClass1)
    if p1 > p0 :
        return 1
    else:
        return 0