【機器學(xué)習(xí)】貝葉斯機器學(xué)習(xí):經(jīng)典模型與代碼實現(xiàn)
貝葉斯機器學(xué)習(xí)
Author:louwill
Machine Learning Lab
貝葉斯定理是概率模型中最著名的理論之一,在機器學(xué)習(xí)中也有著廣泛的應(yīng)用。基于貝葉斯理論常用的機器學(xué)習(xí)概率模型包括樸素貝葉斯和貝葉斯網(wǎng)絡(luò)。本章在對貝葉斯理論進行簡介的基礎(chǔ)上,分別對樸素貝葉斯和貝葉斯網(wǎng)絡(luò)理論進行詳細的推導(dǎo)并給出相應(yīng)的代碼實現(xiàn),針對樸素貝葉斯模型,本章給出其NumPy和sklearn的實現(xiàn)方法,而貝葉斯網(wǎng)絡(luò)的實現(xiàn)則是借助于pgmpy。
貝葉斯理論簡介
自從Thomas Bayes于1763年發(fā)表了那篇著名的《論有關(guān)機遇問題的求解》一文后,以貝葉斯公式為核心的貝葉斯理論自此發(fā)展起來。貝葉斯理論認為任意未知量都可以看作為一個隨機變量,對該未知量的描述可以用一個概率分布來概括,這是貝葉斯學(xué)派最基本的觀點。當這個概率分布在進行現(xiàn)場試驗或者抽樣前就已確定,便可將該分布稱之為先驗分布,再結(jié)合由給定數(shù)據(jù)集X計算樣本的似然函數(shù)后,即可應(yīng)用貝葉斯公式計算該未知量的后驗概率分布。經(jīng)典的貝葉斯公式表達如下:

上式左邊為后驗分布,右邊分母為邊緣分布,其排除了任何有關(guān)未知量的信息,因此貝葉斯公式的等價形式可以寫作為:
上式可以歸納出貝葉斯公式的本質(zhì)就是基于先驗分布和似然函數(shù)的統(tǒng)計推斷。其中先驗分布的選擇與后驗分布的推斷是貝葉斯領(lǐng)域的兩個核心問題。先驗分布的選擇目前并沒有統(tǒng)一的標準,不同的先驗分布對后驗計算的準確度有很大的影響,這也是貝葉斯領(lǐng)域的研究熱門之一;后驗分布曾因復(fù)雜的數(shù)學(xué)形式和高維數(shù)值積分使得后驗推斷十分困難,而后隨著計算機技術(shù)的發(fā)展,基于計算機軟件的數(shù)值技術(shù)使得這些問題得以解決,貝葉斯理論又重新煥發(fā)活力。
與機器學(xué)習(xí)的結(jié)合正是貝葉斯理論的主要應(yīng)用方向。樸素貝葉斯理論是一種基于貝葉斯理論的概率分類模型,而貝葉斯網(wǎng)絡(luò)是一種將貝葉斯理論應(yīng)用到概率圖中的分類模型。
樸素貝葉斯
樸素貝葉斯原理與推導(dǎo)
樸素貝葉斯是基于貝葉斯定理和特征條件獨立假設(shè)的分類算法。具體而言,對于給定的訓(xùn)練數(shù)據(jù),樸素貝葉斯先基于特征條件獨立假設(shè)學(xué)習(xí)輸入和輸出的聯(lián)合概率分布,然后對于新的實例,利用貝葉斯定理計算出最大的后驗概率。樸素貝葉斯不會直接學(xué)習(xí)輸入輸出的聯(lián)合概率分布,而是通過學(xué)習(xí)類的先驗概率和類條件概率來完成。樸素貝葉斯的概率計算公式如圖1所示。

圖1 樸素貝葉斯基本公式
樸素貝葉斯中樸素的含義,即特征條件獨立假設(shè),條件獨立假設(shè)就是說用于分類的特征在類確定的條件下都是條件獨立的,這一假設(shè)使得樸素貝葉斯的學(xué)習(xí)成為可能。假設(shè)輸入特征向量為X,輸出為類標記隨便變量Y,P(X,Y)為X和Y的聯(lián)合概率分布,T為給定訓(xùn)練數(shù)據(jù)集。樸素貝葉斯基于訓(xùn)練數(shù)據(jù)集來學(xué)習(xí)聯(lián)合概率分布P(X,Y)。具體地,通過學(xué)習(xí)類先驗概率分布和類條件概率分布來實現(xiàn)。
樸素貝葉斯學(xué)習(xí)步驟如下。先計算類先驗概率分布:

其中Ck表示第k個類別,yi表示第i個樣本的類標記。類先驗概率分布可以通過極大似然估計得到。
然后計算類條件概率分布:

直接對P(X=x|Y=Ck)進行估計不太可行,因為參數(shù)量太大。但是樸素貝葉斯的一個最重要的假設(shè)就是條件獨立性假設(shè),即:

有了條件獨立性假設(shè)之后,便可基于極大似然估計計算類條件概率。
類先驗概率分布和類條件概率分布都計算得到之后,基于貝葉斯公式即可計算類后驗概率:

代入類條件計算公式,有:

基于上式即可學(xué)習(xí)一個樸素貝葉斯分類模型。給定新的數(shù)據(jù)樣本時,計算其最大后驗概率即可:

其中,分母對于所有的都是一樣的,所以上式可進一步簡化為:

以上就是樸素貝葉斯分類模型的簡單推導(dǎo)過程。
基于NumPy的樸素貝葉斯實現(xiàn)
本節(jié)我們基于NumPy來實現(xiàn)一個簡單樸素貝葉斯分類器。樸素貝葉斯因為條件獨立性假設(shè)變得簡化,所以實現(xiàn)思路也較為簡單,這里我們就不給出實現(xiàn)的思維導(dǎo)圖了。根據(jù)前述推導(dǎo),關(guān)鍵在于使用極大似然估計方法計算類先驗概率分布和類條件概率分布。
我們直接定義樸素貝葉斯模型訓(xùn)練過程,如代碼1所示。
def nb_fit(X, y):classes = y[y.columns[0]].unique()class_count = y[y.columns[0]].value_counts()class_prior = class_count/len(y)prior = dict()for col in X.columns:for j in classes:p_x_y = X[(y==j).values][col].value_counts()for i in p_x_y.index:i, j)] = p_x_y[i]/class_count[j]return classes, class_prior, prior
在代碼1中,給定數(shù)據(jù)輸入和輸出均為Pandas數(shù)據(jù)框格式,先對標簽類別數(shù)量進行統(tǒng)計,并以此基于極大似然估計計算類先驗分布。然后對數(shù)據(jù)特征和類別進行循環(huán)遍歷,計算類條件概率。
式(10)作為樸素貝葉斯的核心公式,接下來我們需要基于式(10)和nb_fit函數(shù)返回的類先驗概率和類條件概率來編寫樸素貝葉斯的預(yù)測函數(shù)。樸素貝葉斯的預(yù)測函數(shù)如代碼2所示。
def predict(X_test):res = []for c in classes:p_y = class_prior[c]p_x_y = 1for i in X_test.items():p_x_y *= prior[tuple(list(i)+[c])]res.append(p_y*p_x_y)return classes[np.argmax(res)]
代碼2中定義了樸素貝葉斯的預(yù)測函數(shù)。以測試樣本X_test作為輸入,初始化結(jié)果列表并獲取當前類的先驗概率,對測試樣本字典進行遍歷,先計算類條件概率的連乘,然后計算先驗概率與類條件概率的乘積。最后按照式(21.10)取argmax獲得最大后驗概率所屬的類別。
最后,我們使用數(shù)據(jù)樣例對編寫的樸素貝葉斯代碼進行測試。手動創(chuàng)建一個二分類的示例數(shù)據(jù),并對其使用nb_fit進行訓(xùn)練,如代碼3所示。
### 創(chuàng)建數(shù)據(jù)集并訓(xùn)練# 特征X1x1 = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]# 特征X2x2 = ['S','M','M','S','S','S','M','M','L','L','L','M','M','L','L']# 標簽列表y = [-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]# 形成一個pandas數(shù)據(jù)框df = pd.DataFrame({'x1':x1, 'x2':x2, 'y':y})# 獲取訓(xùn)練輸入和輸出X, y = df[['x1', 'x2']], df[['y']]# 樸素貝葉斯模型訓(xùn)練classes, class_prior, prior_condition_prob = nb_fit(X, y)print(classes, class_prior, prior_condition_prob)

圖2 代碼21-3輸出截圖
在代碼3中,我們基于列表構(gòu)建了Pandas數(shù)據(jù)框格式的數(shù)據(jù)集,獲取訓(xùn)練輸入和輸出并傳入樸素貝葉斯訓(xùn)練函數(shù)中,輸出結(jié)果如圖21.2所示。可以看到,數(shù)據(jù)標簽包括是1/-1的二分類數(shù)據(jù)集,類先驗概率分布為{1:0.6,-1:0.4},各類條件概率如圖中所示。
最后,我們創(chuàng)建一個測試樣本,并基于nb_predict函數(shù)對其進行類別預(yù)測,如下所示。
### 樸素貝葉斯模型預(yù)測X_test = {'x1': 2, 'x2': 'S'}print('測試數(shù)據(jù)預(yù)測類別為:', nb_predict(X_test))
輸出:
測試數(shù)據(jù)預(yù)測類別為:-1最后模型將該測試樣本預(yù)測為負類。
基于sklearn的樸素貝葉斯實現(xiàn)
sklearn也提供了樸素貝葉斯的算法實現(xiàn)方式,sklearn為我們提供了不同似然函數(shù)分布的樸素貝葉斯算法實現(xiàn)方式。比如高斯樸素貝葉斯、伯努利樸素貝葉斯、多項式樸素貝葉斯等。我們以高斯樸素貝葉斯為例,高斯樸素貝葉斯即假設(shè)似然函數(shù)為正態(tài)分布的樸素貝葉斯模型。高斯樸素貝葉斯的似然函數(shù)如下式所示。

sklearn中高斯樸素貝葉斯的調(diào)用接口為sklearn.naive_bayes.GaussianNB,以iris數(shù)據(jù)集為例給出調(diào)用示例,如代碼4所示。
### sklearn高斯樸素貝葉斯示例# 導(dǎo)入相關(guān)庫from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import accuracy_score# 導(dǎo)入數(shù)據(jù)集X, y = load_iris(return_X_y=True)# 數(shù)據(jù)集劃分X_train, X_test, y_train, y_test =train_test_split(X, y, test_size=0.5, random_state=0)# 創(chuàng)建高斯樸素貝葉斯實例gnb = GaussianNB()# 模型擬合并預(yù)測y_pred = gnb.fit(X_train, y_train).predict(X_test)print("Accuracy of GaussianNB in iris data test:", accuracy_score(y_test, y_pred))
輸出:
Accuracy of GaussianNB in iris data test:0.9466666666666667在代碼4中,先導(dǎo)入sklearn中樸素貝葉斯相關(guān)模塊,導(dǎo)入iris數(shù)據(jù)集并進行訓(xùn)練測試劃分。然后創(chuàng)建高斯樸素貝葉斯模型實例,基于訓(xùn)練集進行擬合并對測試集進行預(yù)測,最后準確率為0.947。
貝葉斯網(wǎng)絡(luò)
貝葉斯網(wǎng)絡(luò)原理與推導(dǎo)
樸素貝葉斯的最大的特點就是特征的條件獨立假設(shè),但在現(xiàn)實情況下,條件獨立這個假設(shè)通常過于嚴格,在實際中很難成立。特征之間的相關(guān)性限制了樸素貝葉斯的性能,所以本節(jié)我們將繼續(xù)介紹一種放寬了條件獨立假設(shè)的貝葉斯算法,即貝葉斯網(wǎng)絡(luò)(bayesian network)。
我們先以一個例子進行引入。假設(shè)我們需要通過頭像真實性、粉絲數(shù)量和動態(tài)更新頻率來判斷一個微博賬號是否為真實賬號。各特征屬性之間的關(guān)系如圖3所示。

圖3 微博賬號屬性關(guān)系
圖3是一個有向無環(huán)圖(directed acyclic graph,DAG),每個節(jié)點表示一個特征或者隨機變量,特征之間的關(guān)系則是用箭頭連線來表示,比如說動態(tài)的更新頻率、粉絲數(shù)量和頭像真實性都會對一個微博賬號的真實性有影響,而頭像真實性又對粉絲數(shù)量有一定影響。但僅有各特征之間的關(guān)系還不足以進行貝葉斯分析。除此之外,貝葉斯網(wǎng)絡(luò)中每個節(jié)點還有一個與之對應(yīng)的概率表。假設(shè)賬號是否真實和頭像是否真實有如下概率表:

圖4 貝葉斯網(wǎng)絡(luò)概率表
圖4是體現(xiàn)頭像和賬號是否真實的概率表。第一張概率表表示的是賬號是否真實,因為該節(jié)點沒有父節(jié)點,可以直接用先驗概率來表示,表示賬號真實與否的概率。第二張概率表表示的是賬號真實性對于頭像真實性的條件概率。比如說在頭像為真實頭像的條件下,賬號為真的概率為0.88。在有了DAG和概率表之后,我們便可以利用貝葉斯公式進行定量的因果關(guān)系推斷。假設(shè)我們已知某微博賬號使用了虛假頭像,那么其賬號為虛假賬號的概率可以推斷為:
利用貝葉斯公式,我們可知在虛假頭像的情況下其賬號為虛假賬號的概率為0.345。
通過上面的例子我們直觀的感受到貝葉斯網(wǎng)絡(luò)的用法。一個貝葉斯網(wǎng)絡(luò)通常由有向無環(huán)圖和節(jié)點對應(yīng)的概率表組成。其中DAG由節(jié)點(node)和有向邊(edge)組成,節(jié)點表示特征屬性或隨機變量,有向邊表示各變量之間的依賴關(guān)系。貝葉斯網(wǎng)絡(luò)的一個重要性質(zhì)是:當一個節(jié)點的父節(jié)點概率分布確定之后,該節(jié)點條件獨立于其所有的非直接父節(jié)點。這個性質(zhì)方便于我們計算變量之間的聯(lián)合概率分布。
一般來說,多變量非獨立隨機變量的聯(lián)合概率分布計算公式如下:

有了節(jié)點條件獨立性質(zhì)之后,上式可以簡化為:

當由DAG表示節(jié)點關(guān)系和概率表確定后,相關(guān)的先驗概率分布、條件概率分布就能夠確定,然后基于貝葉斯公式,我們就可以使用貝葉斯網(wǎng)絡(luò)進行推斷。
借助于pgmpy的貝葉斯網(wǎng)絡(luò)實現(xiàn)
本小節(jié)基于pgmpy來構(gòu)造貝葉斯網(wǎng)絡(luò)和進行建模訓(xùn)練。pgmpy是一款基于Python的概率圖模型包,主要包括貝葉斯網(wǎng)絡(luò)和馬爾可夫蒙特卡洛等常見概率圖模型的實現(xiàn)以及推斷方法。
我們以學(xué)生獲得的推薦信質(zhì)量的例子來進行貝葉斯網(wǎng)絡(luò)的構(gòu)造。相關(guān)特征之間的DAG和概率表如圖5所示。

圖5 推薦信質(zhì)量的DAG和概率表
由圖5可知,考試難度、個人聰明與否都會影響到個人成績,另外個人天賦高低也會影響到SAT分數(shù),而個人成績好壞會直接影響到推薦信的質(zhì)量。下面我們直接來用pgmpy實現(xiàn)上述貝葉斯網(wǎng)絡(luò)模型。
(1)構(gòu)建模型框架,指定各變量之間的關(guān)系。如代碼5所示。
# 導(dǎo)入pgmpy相關(guān)模塊from pgmpy.factors.discrete import TabularCPDfrom pgmpy.models import BayesianModelletter_model = BayesianModel([('D', 'G'),('I', 'G'),('G', 'L'),('I', 'S')])
(2)構(gòu)建各個節(jié)點的條件概率分布,需要指定相關(guān)參數(shù)和傳入概率表,如代碼6所示。
# 學(xué)生成績的條件概率分布grade_cpd = TabularCPD(variable='G', # 節(jié)點名稱variable_card=3, # 節(jié)點取值個數(shù)values=[[0.3, 0.05, 0.9, 0.5], # 該節(jié)點的概率表0.25, 0.08, 0.3],0.7, 0.02, 0.2]],evidence=['I', 'D'], # 該節(jié)點的依賴節(jié)點evidence_card=[2, 2] # 依賴節(jié)點的取值個數(shù))# 考試難度的條件概率分布difficulty_cpd = TabularCPD(variable='D',variable_card=2,values=[[0.6], [0.4]])# 個人天賦的條件概率分布intel_cpd = TabularCPD(variable='I',variable_card=2,values=[[0.7], [0.3]])# 推薦信質(zhì)量的條件概率分布letter_cpd = TabularCPD(variable='L',variable_card=2,values=[[0.1, 0.4, 0.99],0.6, 0.01]],evidence=['G'],evidence_card=[3])# SAT考試分數(shù)的條件概率分布sat_cpd = TabularCPD(variable='S',variable_card=2,values=[[0.95, 0.2],0.8]],evidence=['I'],evidence_card=[2])
(3)將各個節(jié)點添加到模型中,構(gòu)建貝葉斯網(wǎng)絡(luò)。如代碼7所示。
# 將各節(jié)點添加到模型中,構(gòu)建貝葉斯網(wǎng)絡(luò)letter_model.add_cpds(grade_cpd,difficulty_cpd,intel_cpd,letter_cpd,sat_cpd)# 導(dǎo)入pgmpy貝葉斯推斷模塊from pgmpy.inference import VariableElimination# 貝葉斯網(wǎng)絡(luò)推斷letter_infer = VariableElimination(letter_model)# 天賦較好且考試不難的情況下推斷該學(xué)生獲得推薦信質(zhì)量的好壞prob_G = letter_infer.query(variables=['G'],evidence={'I': 1, 'D': 0})print(prob_G)
輸出如圖6所示。

從圖6的輸出結(jié)果可以看到,當聰明的學(xué)生碰上較簡單的考試時,獲得第一等成績的概率高達90%。
小結(jié)
貝葉斯定理是經(jīng)典的概率模型之一,基于先驗信息和數(shù)據(jù)觀測得到目標變量的后驗分布的方式,是貝葉斯的核心理論。貝葉斯理論在機器學(xué)習(xí)領(lǐng)域也有廣泛的應(yīng)用,最常用的貝葉斯機器學(xué)習(xí)模型包括樸素貝葉斯模型和貝葉斯網(wǎng)絡(luò)模型。
樸素貝葉斯模型是一種生成學(xué)習(xí)方法,通過數(shù)據(jù)學(xué)習(xí)聯(lián)合概率分布的方式來計算后驗概率分布。之所以取名為樸素貝葉斯,是因為特征的條件獨立性假設(shè),能夠大大簡化樸素貝葉斯算法的學(xué)習(xí)和預(yù)測過程,但也會帶來一定的精度損失。
進一步地,將樸素貝葉斯的條件獨立假設(shè)放寬,認為特征之間是存在相關(guān)性的貝葉斯模型就是貝葉斯網(wǎng)絡(luò)模型。貝葉斯網(wǎng)絡(luò)是一種概率無向圖模型,通過有向圖和概率表的方式來構(gòu)建貝葉斯概率模型。當由有向圖表示節(jié)點關(guān)系和概率表確定后,相關(guān)的先驗概率分布、條件概率分布就能夠確定,然后基于貝葉斯公式,就可以使用貝葉斯網(wǎng)絡(luò)進行概率推斷。
本文參考代碼地址:
https://github.com/luwill/Machine_Learning_Code_Implementation/tree/master/charpter21_Bayesian_models
往期精彩回顧 本站qq群851320808,加入微信群請掃碼:
