機器學習演算法筆記之4:貝葉斯分類器

marsjhao發表於2020-04-06

一、貝葉斯分類器詳解

貝葉斯分類器是一類分類演算法的總稱,這類演算法均以貝葉斯定理為理論基礎。貝葉斯分類器的分類原理是通過先驗概率,利用貝葉斯公式計算出後驗概率,選擇最大後驗概率所對應的分類結果。

貝葉斯準則

其中,P(c)是先驗概率,P(x|c)樣本x相對於;類標記c的類條件概率,或稱為似然(likelihood);P(x)是用於歸一化的證據因子。對於給定樣本x,證據因子與類標記無關,則估計P(c|x)可轉換為基於訓練資料D來估計鮮豔P(c)和似然P(x|c)。類先驗概率P(c)可通過各類樣本出現的頻率來進行估計。對於類條件概率P(x|c),一種常用策略是先假定其具有某種確定的概率分佈形式,再基於訓練樣本對概率分佈的引數進行估計。

對於樸素貝葉斯分類器,樸素(naive)的含義是各個特徵屬性之間是相互獨立的。例如,在計算p(w|ci)時,我們將特徵向量w展開為獨立子特徵,則轉化為,這裡我們有假設所有特徵都獨立,即可以使用以下公式來計算,這就是利用了樸素的原則。(wi和下文的xi是相同含義,表示各個特徵屬性分量)

基於以上,樸素貝葉斯分類器的訓練過程就是基於訓練集D來估計類先驗概率P(c),併為每個特徵屬性估計條件概率P(xi|c)。對於類先驗概率,在有足夠獨立同分布訓練樣本的條件下,通過計算各類樣本佔總樣本數的比例來計算。計算條件概率時,對於離散屬性而言,,對於連續屬性考慮概率密度函式,

式中的兩個未知引數均值和方差極大似然法估計得到。假設概率密度函式,則引數的極大似然估計為:

這就是說,通過極大似然法得到的正態分佈均值就是樣本均值,方差就是的均值。

為了避免其他屬性攜帶的資訊被訓練集中未出現的屬性值“抹去”,在估計概率值時通常要進行“平滑”(smoothing),常用拉普拉斯修正。具體來說,令N表示訓練集D中可能的類別數,Ni表示第i個屬性可能的取值數,修正為

拉普拉斯修正避免了因訓練集樣本不充分而導致概率估值為零的問題,並且在訓練集變大時,修正過程所引入的先驗的影響也會逐漸變得可忽略,使得估值逐漸趨向於實際的概率值。

二、Sklearn程式程式碼及實驗結果

GaussianNB、MultinomialNB、BernoulliNB分別是高斯貝葉斯分類器、多項式貝葉斯分類器、伯努利貝葉斯分類器,他們的區別就在於假設了不同的P(xi|c)分佈。

完整程式碼:

from sklearn import datasets, cross_validation, naive_bayes
import matplotlib.pyplot as plt

# 視覺化手寫識別資料集Digit Dataset
def show_digits():
    digits = datasets.load_digits()
    fig = plt.figure()
    for i in range(20):
        ax = fig.add_subplot(4, 5, i+1)
        ax.imshow(digits.images[i], cmap = plt.cm.gray_r, interpolation='nearest')
    plt.show()

show_digits()

# 載入Digit資料集
def load_data():
    digits = datasets.load_digits()
    return cross_validation.train_test_split(digits.data, digits.target, 
                                             test_size = 0.25, random_state = 0)

def test_GaussianNB(*data):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.GaussianNB()
    cls.fit(X_train, y_train)
    print('GaussianNB Classifier')
    print('Training Score: %.2f' % cls.score(X_train, y_train))
    print('Test Score: %.2f' % cls.score(X_test, y_test))
    
X_train, X_test, y_train, y_test = load_data()
test_GaussianNB(X_train, X_test, y_train, y_test)

def test_MultinomialNB(*data):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.MultinomialNB()
    cls.fit(X_train, y_train)
    print('MultinomialNB Classifier')
    print('Training Score: %.2f' % cls.score(X_train, y_train))
    print('Test Score: %.2f' % cls.score(X_test, y_test))
    
X_train, X_test, y_train, y_test = load_data()
test_MultinomialNB(X_train, X_test, y_train, y_test)

def test_BernoulliNB(*data):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.BernoulliNB()
    cls.fit(X_train, y_train)
    print('BernoulliNB Classifier')
    print('Training Score: %.2f' % cls.score(X_train, y_train))
    print('Test Score: %.2f' % cls.score(X_test, y_test))
    
X_train, X_test, y_train, y_test = load_data()
test_BernoulliNB(X_train, X_test, y_train, y_test)

實驗結果:


GaussianNB Classifier
Training Score: 0.86
Test Score: 0.83
MultinomialNB Classifier
Training Score: 0.91
Test Score: 0.91
BernoulliNB Classifier
Training Score: 0.87
Test Score: 0.85

相關文章