一、簡介
要介紹樸素貝葉斯(naive bayes)分類器,就不得不先介紹貝葉斯決策論的相關理論:
貝葉斯決策論(bayesian decision theory)是機率架構下實施決策的基本方法。對分類任務來說,在所有相關機率都已知的理想情況下,貝葉斯決策論考慮如何基于這些機率和誤判損失來選擇最優的類别标記結果。
二、貝葉斯決策論的基本原理
我們以多分類任務為例:
假設有N種可能的類别标記,即y={c1,c2,...,cN},λij是将一個真實類别為cj的樣本誤分類為ci的損失,基于後驗機率P(ci|cj)可獲得将樣本x分類為ci所産生的期望損失(expected loss),即在樣本x上的“條件風險”(conditional risk)
我們的目的是尋得一個判定準則h:X-->Y,以最小化總體風險: 對每一個樣本x,若h能最小化條件風險 則總體風險R(h)也将被最小化,這就産生了貝葉斯判定準則(Bayes decision rule):為最小化總體風險,隻需要在每個樣本上選擇能使條件風險R(c|x)最小的類别标記,即h*被稱作貝葉斯最優分類器(Bayes optimal classifier),與之對應的總體風險R(h*)稱為貝葉斯風險(Bayes risk)。1-R(h*)反映了分類器所能達到的最佳性能,即通過機器學習所能達到的模型精度的理論上限。
若目标是最小化分類錯誤率,則誤判損失λij可寫作
此時的條件風險 于是,最小化分類錯誤率的貝葉斯最優分類器為:即對每個樣本x,選擇使得後驗機率P(c|x)最大的類别标記,是以利用貝葉斯判定準則來最小化決策風險的首要工作是求得後驗機率P(c|x),這在現實任務中通常難以直接獲得,而機器學習所要實作的是基于有限的訓練樣本集來盡可能準确地估計後驗機率,主要有兩種政策:
1、“判定式模型”(discriminative model)
給定x,通過直接對P(c|x)模組化來預測c;
2、“生成式模型”(generative model)
對聯合機率分布P(x,c)模組化,然後再由此獲得P(c|x);
貝葉斯分類器便是一種生成式模型,對生成式模型,考慮條件機率公式:
基于貝葉斯定理,P(c|x)可寫為:其中,P(c)是類先驗機率(prior);P(x|c)是樣本x對應類别c的類條件機率(class-condtional probability),或稱為“似然”(likelihood);P(x)是用于歸一化的“證據”(evidence)因子。對給定樣本x,證據因子P(x)與類别無關,是以估計P(c|x)的問題就轉化為如何基于訓練資料D來估計P(c)和似然P(x|c),類先驗機率P(c)表達了樣本空間中各類樣本所占的比例,根據大數定律,當樣本資料規模足夠大時,就可以用樣本資料的各類别出現的頻率來估計P(c)。
上述過程雖然看起來很簡單,但是應用到現實任務中就會遇到很多局限,對類條件機率P(x|c),由于它涉及所有關于x的屬性的聯合機率,直接根據樣本出現的頻率來估計将會遇到困難,因為實際任務中的訓練樣本集是有限的,而要估計聯合分布就需要獲得各種可能狀态的樣本,這顯然無法辦到,因為自變量各個次元上的組合方式是指數式增長的,遠遠大于樣本數量,導緻很多可能的樣本取值從未在訓練集中出現過,是以直接用頻率來估計P(x|c)不可行,因為這樣會直接把未出現過與機率為0畫上等号。
為了克服貝葉斯分類器中的局限,我們基于更寬松的理論條件建構出樸素貝葉斯分類器;
三、樸素貝葉斯分類器
為了避開貝葉斯公式的訓練障礙,樸素貝葉斯分類器采用了“屬性條件獨立性假設”(attribute conditional independence assumption),即對已知類别,假設所有屬性互相獨立,即每個屬性各自獨立地對分類結果産生影響,則我們前面提到的貝葉斯公式:
其中d表示屬性的個數,xi表示x在第i個屬性上的取值,又因為P(x)由樣本集唯一确定,即對所有類别P(x)都相同,于是樸素貝葉斯分類器的表達式: 樸素貝葉斯分類器的訓練過程就是基于訓練集D來估計類先驗機率P(c),并為每個屬性估計條件機率P(xi|c),用Dc表示訓練集D中第c類樣本組成的集合,若有充足的獨立同分布樣本,則可以容易地估計出類先驗機率: 對離散屬性而言,令Dc,xi表示Dc中在第i個屬性上取值為xi的樣本組成的集合,則條件機率P(xi|c)為: 對連續型屬性,假定: 其中μc,i,σ2c,i分别為第c類樣本在屬性i上的均值與方差(這裡要假設對應的連續型變量服從正态分布),則:下面以一個簡單的例子來詳細說明這個過程:
對給定的訓練集D,以類别c{c=1/0}作為分類目标,對所有在訓練集出現過的屬性xi屬于X,依此進行下列計算(估計):
1、類先驗機率P(c)
2、各屬性的條件機率
以x1為例:
若xi為連續型變量,則利用不同類别中該屬性的樣本均值與樣本方差來估計真實的不同類别中該屬性的正态分布對應的參數,求出對應的密度函數;計算出所有屬性對所有可能的類别的條件機率;
3、對樣本進行分類
針對我們所舉的例子,有如下兩種情況:
取其中結果較大者對應類别作為最終對樣本的分類結果。
修正情況:
有些時候,若某個屬性值在訓練集中沒有與某個類同時出現過,則直接使用上述過程估計後驗機率會将整個結果拖累至0,是以這種情況下我們進行如下處理:
平滑(smoothing)
為了避免上面描述的,樣本的其他屬性攜帶的資訊被訓練集中未出現過的屬性抹去,則在估計機率值的時候要進行“平滑”處理,常用“拉普拉斯修正”(Laplacian correction),具體操作如下:
我們用N表示訓練集D中可能的類别數,Ni表示第i個屬性可能的取值個數,則:
這種修正方法避免了因訓練集樣本不充分而導緻機率估值為0的問題,并且在訓練集變大時,修正過程所引入的先驗(prior)的影響也會逐漸變得可以忽略,使得估值漸漸趨向于實際機率值。
現實中的使用方式:
1、任務對預測速度要求較高時
可以事先将樣本中所有先驗機率和類條件機率計算好并儲存起來,等到需要預測新樣本類别時查表計算對應的後驗機率即可;
2、任務資料更替頻繁時
可采用“懶惰學習”(lazy learning)的方式,先不進行任何事先訓練,僅在有預測需求時才根據目前樣本進行機率估計與預測;
3、資料不斷增加時
若資料不斷增加,則可在現有機率估值的基礎上,僅對新增樣本的屬性值所涉及的機率估值進行修正即可實作增量學習(線上學習);
四、Python實作
我們使用sklearn.naive_bayes中的GaussianNB()來進行樸素貝葉斯分類,這種方法基于的就是我們前面提到的假設非類别型的連續數值變量服從正态分布即高斯分布,其參數非常簡單(因為整個模組化過程沒有什麼需要調參數的地方)如下:
priors:數組型,控制針對各類别比例的先驗分布,若本參數有輸入,則接下來的先驗分布将不再基于樣本集進行計算;
函數輸出項:
class_prior_:輸出基于樣本集計算出的各類别的先驗分布
class_count_:輸出訓練集中各個類别的樣本數量
theta_:輸出計算出的對應各連續型特征各類别的樣本均值
sigma_:輸出計算出的對應各連續型特征各類别的樣本方差
下面以我們喜聞樂見的鸢尾花資料進行示範:
from sklearn.naive_bayes import GaussianNB
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
'''載入資料'''
X,y = datasets.load_iris(return_X_y=True)
'''分割訓練集與驗證集,這裡采用分層抽樣的方法控制類别的先驗機率'''
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,stratify=y)
'''初始化高斯樸素貝葉斯分類器'''
clf = GaussianNB()
'''訓練分類器'''
clf = clf.fit(X_train,y_train)
'''列印分類器在驗證集上的混淆矩陣'''
print('混淆矩陣:')
print(confusion_matrix(y_test,clf.predict(X_test)))
'''列印測試集上的正确率'''
print('測試集正确率:'+str(clf.score(X_test,y_test)))
'''列印分類器訓練後的各傳回項'''
print('類别的先驗分布:',clf.class_prior_)
print('各類别樣本數量:',clf.class_count_)
print('各類别對應各連續屬性的正态分布的均值:','\n',clf.theta_)
print('各類别對應各連續屬性的正态分布的方差:','\n',clf.sigma_)
運作結果:
五、R實作
在R中有很多包支援樸素貝葉斯分類(事實上自己寫自編函數實作也不是件難事),這裡選用比較有代表性的e1071包中的naiveBayes()來完成相應功能,其主要參數如下:
formula:這時R中常見的一種格式,類别标簽~自變量 的輸入形式
data:指定訓練資料所在的資料框
laplace:控制前面提到的平滑進行中的拉普拉斯修正,預設值為0,即不進行平滑,若需要進行拉普拉斯修正,這裡建議值為1
下面是一個簡單的示範:
> rm(list=ls())
> library(e1071)
> data(iris)
>
> #留出法分割訓練集與驗證集
> sam <- sample(1:dim(iris)[1],dim(iris)[1]*0.8)
> X_train <- iris[sam,1:4]
> y_train <- iris[sam,5]
> X_test <- iris[-sam,1:4]
> y_test <- iris[-sam,5]
> train <- cbind(y_train,X_train)
>
> #利用訓練集訓練樸素貝葉斯分類器
> clf <- naiveBayes(y_train~.,data=train)
>
> #混淆矩陣
> table(y_test,predict(clf,X_test))
y_test setosa versicolor virginica
setosa 9 0 0
versicolor 0 7 1
virginica 0 0 13
>
> #測試正确率
> sum(diag(prop.table(table(y_test,predict(clf,X_test)))))
[1] 0.9666667
以上就是關于樸素貝葉斯的基本内容,其實樸素貝葉斯方法運用最多的是文本分類問題,接下來的幾篇部落格我将圍繞樸素貝葉斯的文本分類方法進行詳細介紹(包含網絡文本資料采集的過程)