監督學習——樸素貝葉斯分類理論與實踐

對於給定的訓練數據,首先基於特徵條件獨立假設學習輸入/輸出的聯合概率分佈,然後基於此模型,對給定的輸入x,利用貝葉斯定理求出後驗概率最大的輸出y。

條件概率:


條件概率應該比較熟悉,P(A|B) 表示事件B已經發生的條件下,事件A發生的概率。計算公式如下:

貝葉斯定理:



image

獨立性


事件的獨立性:

假設 A,B是兩個事件,如果滿足等式: P(AB)  = P(A)*P(B) ,則稱時間A,B相互獨立.

由條件概率公式知:如果兩個事件獨立則: P(A|B) = P(A) .   (B的發生與否對於A的結果沒有影響)

參數(隨機變量)的獨立性:

假設(x1,x2)是二位的隨機變量,其聯合分佈函數爲F(x1,x2),隨機變量x1,x2的邊緣分佈函數爲Fx1(x1)和Fx2(x2),如果對於任意x1,x2均有:

F(x1,x2) = Fx1(x1) * Fx2(x2)

該公式等價於: P{X1<x1,X2<x2} = P{X1<x1} * P{X2<x2}

則 x1, x2爲相互獨立的隨機變量

在建模時,往往涉及到選取不同的特徵變量(如顏色形狀等等),這些參數的獨立就是這裏的參數獨立。

先驗概率


先驗概率(prior probability)是指根據以往經驗和分析得到的概率,如全概率公式,它往往作爲"由因求果"問題中的"因"出現的概率。

後驗概率:



極大似然估計


用處:極大似然估計往往用來計算一個模型中的參數。 使用前提:“模型已定,參數未知”

原理:通過微分(如果有多個參數,可能需要解微分方程組)的方法尋找使樣本集合(x1,x2,x3,x4…..)出現概率最大的模型參數。下面是概率論中通過極大似然估計,計算高斯分佈的兩個參數:(實際中的模型往往比高斯模型複雜的多,但是原理是一樣的)

image

至於爲什麼一階導數得到的方程組就能求得極大值,請參考這篇文章:http://www.cnblogs.com/hapjin/p/6633471.html

最大似然估計的一般求解過程:

  (1) 寫出似然函數;

  (2) 對似然函數取對數,並整理;

  (3) 求導數 ;

  (4) 解似然方程


樸素貝葉斯法


假如一個樣本的輸入爲X(可以爲一個向量x1,x2,x3…),輸出爲Y(可以是分類問題,也可以是連續值)

假設: 條件獨立性假設:用於分類的特徵在類確定額條件下都是條件獨立的。

樸素貝葉斯法通過訓練數據集學習聯合概率分佈P(X,Y)。

先驗概率:   P(Y)

條件概率:  P(X = x|Y = y)

條件獨立性假設: 

image

最終得到後驗概率的計算公式(4.4) 及 貝葉斯分類器的計算公式(4.7)

image

注: 分母做了歸一下處理(比較雙方分母都化作1)

這裏加一個問題: 爲什麼要條件獨立性假設,而不是直接利用數據求解條件概率 P(X = x|Y = y)?

這裏X涉及到關於x所有屬性的聯合概率,直接根據樣本出現的概率來估計將會遇到嚴重的困難。例如,假設樣本d個屬性都是二值的將有2^d種可能的取值,在現實中這個往往大於訓練樣本數。

基於樸素貝葉斯的文本分類


需求

1. 郵件分爲兩類,一種爲正常郵件,另一種爲侮辱性郵件(標籤分別用 0/1表示 )

2. 提供 正常郵件和侮辱性郵件(數據及其標籤)

3. 當輸入郵件數據時,系統需要輸出其標籤

文本數據預處理

1.  加載郵件數據以及他們的標籤(郵件分類:是否爲惡意郵件)

def loadDataSet():
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0,1,0,1,0,1]    #1 is abusive, 0 not
    return postingList,classVec

2. 基於已有的郵件構建”單詞表“(所有郵件中包含的單詞)

def createVocabList(dataSet):
    vocabSet = set([])  #create empty set
    for document in dataSet:
        vocabSet = vocabSet | set(document) #union of the two sets
    return list(vocabSet)

3. 將已有的郵件映射到詞表中(如果郵件中某個單詞出現則此表中該 位置爲 1 否則爲0)

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else: print "the word: %s is not in my Vocabulary!" % word
    return returnVec

訓練函數

將預處理好的數據輸入到該函數中,就能得到上面公式4.7中: P(x=xi | Y=1)或者 P(x=xi | Y=0) 的每項概率保存在返回的兩個數組。並且將 整體 的概率 P(Y=1) 也返回了。

# trainMatrix: 文本映射到“詞表”中的矩陣 
# trainCategory: 文本的 類別
def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)  # 文本的數量
    numWords = len(trainMatrix[0])   # 詞表的長度
    pAbusive = sum(trainCategory)/float(numTrainDocs)  # 類別爲1的概率
    p0Num = ones(numWords);     # 存放計算的條件概率 P(xi|Y=0)
    p1Num = ones(numWords)      # 存放計算的條件概率 P(xi|Y=1)
    p0Denom = 2.0;
    p1Denom = 2.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = log(p1Num/p1Denom)          #change to log()
    p0Vect = log(p0Num/p0Denom)          #change to log()
    return p0Vect,p1Vect,pAbusive

郵件分類

根據貝葉斯公式分別計算一封郵件是正常郵件還是侮辱性郵件的概率,如下所示:

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)    #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0


參考:

《機器學習實戰》

《統計學方法》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章