貝葉斯機(jī)器學(xué)習(xí):經(jīng)典模型與代碼實(shí)現(xiàn)!
貝葉斯定理是概率模型中最著名的理論之一,在機(jī)器學(xué)習(xí)中也有著廣泛的應(yīng)用?;谪惾~斯理論常用的機(jī)器學(xué)習(xí)概率模型包括樸素貝葉斯和貝葉斯網(wǎng)絡(luò)。本文在對(duì)貝葉斯理論進(jìn)行簡(jiǎn)介的基礎(chǔ)上,分別對(duì)樸素貝葉斯和貝葉斯網(wǎng)絡(luò)理論進(jìn)行詳細(xì)的推導(dǎo)并給出相應(yīng)的代碼實(shí)現(xiàn),針對(duì)樸素貝葉斯模型,本文給出其NumPy和sklearn的實(shí)現(xiàn)方法,而貝葉斯網(wǎng)絡(luò)的實(shí)現(xiàn)則是借助于pgmpy。
貝葉斯理論簡(jiǎn)介
自從Thomas Bayes于1763年發(fā)表了那篇著名的《論有關(guān)機(jī)遇問題的求解》一文后,以貝葉斯公式為核心的貝葉斯理論自此發(fā)展起來。貝葉斯理論認(rèn)為任意未知量都可以看作為一個(gè)隨機(jī)變量,對(duì)該未知量的描述可以用一個(gè)概率分布來概括,這是貝葉斯學(xué)派最基本的觀點(diǎn)。當(dāng)這個(gè)概率分布在進(jìn)行現(xiàn)場(chǎng)試驗(yàn)或者抽樣前就已確定,便可將該分布稱之為先驗(yàn)分布,再結(jié)合由給定數(shù)據(jù)集 X 計(jì)算樣本的似然函數(shù)后,即可應(yīng)用貝葉斯公式計(jì)算該未知量的后驗(yàn)概率分布。經(jīng)典的貝葉斯公式表達(dá)如下:
上式左邊為后驗(yàn)分布,右邊分母為邊緣分布,其排除了任何有關(guān)未知量的信息,因此貝葉斯公式的等價(jià)形式可以寫作為:
上式可以歸納出貝葉斯公式的本質(zhì)就是基于先驗(yàn)分布和似然函數(shù)的統(tǒng)計(jì)推斷。其中先驗(yàn)分布的選擇與后驗(yàn)分布的推斷是貝葉斯領(lǐng)域的兩個(gè)核心問題。先驗(yàn)分布的選擇目前并沒有統(tǒng)一的標(biāo)準(zhǔn),不同的先驗(yàn)分布對(duì)后驗(yàn)計(jì)算的準(zhǔn)確度有很大的影響,這也是貝葉斯領(lǐng)域的研究熱門之一;后驗(yàn)分布曾因復(fù)雜的數(shù)學(xué)形式和高維數(shù)值積分使得后驗(yàn)推斷十分困難,而后隨著計(jì)算機(jī)技術(shù)的發(fā)展,基于計(jì)算機(jī)軟件的數(shù)值技術(shù)使得這些問題得以解決,貝葉斯理論又重新煥發(fā)活力。
與機(jī)器學(xué)習(xí)的結(jié)合正是貝葉斯理論的主要應(yīng)用方向。樸素貝葉斯理論是一種基于貝葉斯理論的概率分類模型,而貝葉斯網(wǎng)絡(luò)是一種將貝葉斯理論應(yīng)用到概率圖中的分類模型。
樸素貝葉斯
樸素貝葉斯原理與推導(dǎo)
樸素貝葉斯是基于貝葉斯定理和特征條件獨(dú)立假設(shè)的分類算法。具體而言,對(duì)于給定的訓(xùn)練數(shù)據(jù),樸素貝葉斯先基于特征條件獨(dú)立假設(shè)學(xué)習(xí)輸入和輸出的聯(lián)合概率分布,然后對(duì)于新的實(shí)例,利用貝葉斯定理計(jì)算出最大的后驗(yàn)概率。樸素貝葉斯不會(huì)直接學(xué)習(xí)輸入輸出的聯(lián)合概率分布,而是通過學(xué)習(xí)類的先驗(yàn)概率和類條件概率來完成。樸素貝葉斯的概率計(jì)算公式如圖1所示。
圖1 樸素貝葉斯基本公式
樸素貝葉斯中樸素的含義,即特征條件獨(dú)立假設(shè),條件獨(dú)立假設(shè)就是說用于分類的特征在類確定的條件下都是條件獨(dú)立的,這一假設(shè)使得樸素貝葉斯的學(xué)習(xí)成為可能。假設(shè)輸入特征向量為X,輸出為類標(biāo)記隨便變量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í)類先驗(yàn)概率分布和類條件概率分布來實(shí)現(xiàn)。
樸素貝葉斯學(xué)習(xí)步驟如下。先計(jì)算類先驗(yàn)概率分布:
其中Ck表示第k個(gè)類別,yi表示第i個(gè)樣本的類標(biāo)記。類先驗(yàn)概率分布可以通過極大似然估計(jì)得到。
然后計(jì)算類條件概率分布:
直接 對(duì)P(X=x|Y=Ck) 進(jìn)行估計(jì)不太可行,因?yàn)閰?shù)量太大。 但是樸素貝葉斯的一個(gè)最重要的假設(shè)就是條件獨(dú)立性假設(shè),即:
有了條件獨(dú)立性假設(shè)之后,便可基于極大似然估計(jì)計(jì)算類條件概率。
類先驗(yàn)概率分布和類條件概率分布都計(jì)算得到之后,基于貝葉斯公式即可計(jì)算類后驗(yàn)概率:
代入類條件計(jì)算公式,有:
基于上式即可學(xué)習(xí)一個(gè)樸素貝葉斯分類模型。給定新的數(shù)據(jù)樣本時(shí),計(jì)算其最大后驗(yàn)概率即可:
其中,分母 對(duì)于所有的 都是一樣的,所以上式 可進(jìn)一步簡(jiǎn)化為:
以上就是樸素貝葉斯分類模型的簡(jiǎn)單推導(dǎo)過程。
基于NumPy的樸素貝葉斯實(shí)現(xiàn)
本節(jié)我們基于NumPy來實(shí)現(xiàn)一個(gè)簡(jiǎn)單樸素貝葉斯分類器。樸素貝葉斯因?yàn)闂l件獨(dú)立性假設(shè)變得簡(jiǎn)化,所以實(shí)現(xiàn)思路也較為簡(jiǎn)單,這里我們就不給出實(shí)現(xiàn)的思維導(dǎo)圖了。根據(jù)前述推導(dǎo),關(guān)鍵在于使用極大似然估計(jì)方法計(jì)算類先驗(yà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:
- prior[(col, i, j)] = p_x_y[i]/class_count[j]
- return classes, class_prior, prior
在代碼1中,給定數(shù)據(jù)輸入和輸出均為Pandas數(shù)據(jù)框格式,先對(duì)標(biāo)簽類別數(shù)量進(jìn)行統(tǒng)計(jì),并以此基于極大似然估計(jì)計(jì)算類先驗(yàn)分布。然后對(duì)數(shù)據(jù)特征和類別進(jìn)行循環(huán)遍歷,計(jì)算類條件概率。
式(10)作為樸素貝葉斯的核心公式,接下來我們需要基于式(10)和nb_fit函數(shù)返回的類先驗(yàn)概率和類條件概率來編寫樸素貝葉斯的預(yù)測(cè)函數(shù)。樸素貝葉斯的預(yù)測(cè)函數(shù)如代碼2所示。
- def predict(X_test):
- res = []
- for c in classes:
- p_y = class_prior[c]
- p_x_y = 1
- for 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ù)測(cè)函數(shù)。以測(cè)試樣本X_test作為輸入,初始化結(jié)果列表并獲取當(dāng)前類的先驗(yàn)概率,對(duì)測(cè)試樣本字典進(jìn)行遍歷,先計(jì)算類條件概率的連乘,然后計(jì)算先驗(yàn)概率與類條件概率的乘積。最后按照式(21.10)取argmax獲得最大后驗(yàn)概率所屬的類別。
最后,我們使用數(shù)據(jù)樣例對(duì)編寫的樸素貝葉斯代碼進(jìn)行測(cè)試。手動(dòng)創(chuàng)建一個(gè)二分類的示例數(shù)據(jù) ,并對(duì)其使用nb_fit進(jìn)行訓(xùn)練,如代碼3所示。
- ### 創(chuàng)建數(shù)據(jù)集并訓(xùn)練
- # 特征X1
- x1 = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
- # 特征X2
- x2 = ['S','M','M','S','S','S','M','M','L','L','L','M','M','L','L']
- # 標(biāo)簽列表
- y = [-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]
- # 形成一個(gè)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ù)標(biāo)簽包括是1/-1的二分類數(shù)據(jù)集,類先驗(yàn)概率分布為{1:0.6,-1:0.4},各類條件概率如圖中所示。
最后,我們創(chuàng)建一個(gè)測(cè)試樣本,并基于nb_predict函數(shù)對(duì)其進(jìn)行類別預(yù)測(cè),如下所示。
- ### 樸素貝葉斯模型預(yù)測(cè)
- X_test = {'x1': 2, 'x2': 'S'}
- print('測(cè)試數(shù)據(jù)預(yù)測(cè)類別為:', nb_predict(X_test))
輸出:
- 測(cè)試數(shù)據(jù)預(yù)測(cè)類別為:-1
最后模型將該測(cè)試樣本預(yù)測(cè)為負(fù)類。
基于sklearn的樸素貝葉斯實(shí)現(xiàn)
sklearn也提供了樸素貝葉斯的算法實(shí)現(xiàn)方式,sklearn為我們提供了不同似然函數(shù)分布的樸素貝葉斯算法實(shí)現(xiàn)方式。比如高斯樸素貝葉斯、伯努利樸素貝葉斯、多項(xiàng)式樸素貝葉斯等。我們以高斯樸素貝葉斯為例,高斯樸素貝葉斯即假設(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_iris
- from sklearn.model_selection import train_test_split
- from sklearn.naive_bayes import GaussianNB
- from 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)建高斯樸素貝葉斯實(shí)例
- gnb = GaussianNB()
- # 模型擬合并預(yù)測(cè)
- 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ù)集并進(jìn)行訓(xùn)練測(cè)試劃分。 然后創(chuàng)建高斯樸素貝葉斯模型實(shí)例,基于訓(xùn)練集進(jìn)行擬合并對(duì)測(cè)試集進(jìn)行預(yù)測(cè),最后準(zhǔn)確率為0.947。
貝葉斯網(wǎng)絡(luò)
貝葉斯網(wǎng)絡(luò)原理與推導(dǎo)
樸素貝葉斯的最大的特點(diǎn)就是特征的條件獨(dú)立假設(shè),但在現(xiàn)實(shí)情況下,條件獨(dú)立這個(gè)假設(shè)通常過于嚴(yán)格,在實(shí)際中很難成立。特征之間的相關(guān)性限制了樸素貝葉斯的性能,所以本節(jié)我們將繼續(xù)介紹一種放寬了條件獨(dú)立假設(shè)的貝葉斯算法,即貝葉斯網(wǎng)絡(luò)(bayesian network)。
我們先以一個(gè)例子進(jìn)行引入。假設(shè)我們需要通過頭像真實(shí)性、粉絲數(shù)量和動(dòng)態(tài)更新頻率來判斷一個(gè)微博賬號(hào)是否為真實(shí)賬號(hào)。各特征屬性之間的關(guān)系如圖3所示。
圖3 微博賬號(hào)屬性關(guān)系
圖3是一個(gè)有向無環(huán)圖(directed acyclic graph,DAG),每個(gè)節(jié)點(diǎn)表示一個(gè)特征或者隨機(jī)變量,特征之間的關(guān)系則是用箭頭連線來表示,比如說動(dòng)態(tài)的更新頻率、粉絲數(shù)量和頭像真實(shí)性都會(huì)對(duì)一個(gè)微博賬號(hào)的真實(shí)性有影響,而頭像真實(shí)性又對(duì)粉絲數(shù)量有一定影響。但僅有各特征之間的關(guān)系還不足以進(jìn)行貝葉斯分析。除此之外,貝葉斯網(wǎng)絡(luò)中每個(gè)節(jié)點(diǎn)還有一個(gè)與之對(duì)應(yīng)的概率表。假設(shè)賬號(hào)是否真實(shí)和頭像是否真實(shí)有如下概率表:
圖4 貝葉斯網(wǎng)絡(luò)概率表
圖4是體現(xiàn)頭像和賬號(hào)是否真實(shí)的概率表。第一張概率表表示的是賬號(hào)是否真實(shí),因?yàn)樵摴?jié)點(diǎn)沒有父節(jié)點(diǎn),可以直接用先驗(yàn)概率來表示,表示賬號(hào)真實(shí)與否的概率。第二張概率表表示的是賬號(hào)真實(shí)性對(duì)于頭像真實(shí)性的條件概率。比如說在頭像為真實(shí)頭像的條件下,賬號(hào)為真的概率為0.88。在有了DAG和概率表之后,我們便可以利用貝葉斯公式進(jìn)行定量的因果關(guān)系推斷。假設(shè)我們已知某微博賬號(hào)使用了虛假頭像,那么其賬號(hào)為虛假賬號(hào)的概率可以推斷為:
利用貝葉斯公式,我們可知在虛假頭像的情況下其賬號(hào)為虛假賬號(hào)的概率為0.345。
通過上面的例子我們直觀的感受到貝葉斯網(wǎng)絡(luò)的用法。一個(gè)貝葉斯網(wǎng)絡(luò)通常由有向無環(huán)圖和節(jié)點(diǎn)對(duì)應(yīng)的概率表組成。其中DAG由節(jié)點(diǎn)(node)和有向邊(edge)組成,節(jié)點(diǎn)表示特征屬性或隨機(jī)變量,有向邊表示各變量之間的依賴關(guān)系。貝葉斯網(wǎng)絡(luò)的一個(gè)重要性質(zhì)是:當(dāng)一個(gè)節(jié)點(diǎn)的父節(jié)點(diǎn)概率分布確定之后,該節(jié)點(diǎn)條件獨(dú)立于其所有的非直接父節(jié)點(diǎn)。這個(gè)性質(zhì)方便于我們計(jì)算變量之間的聯(lián)合概率分布。
一般來說,多變量非獨(dú)立隨機(jī)變量的聯(lián)合概率分布計(jì)算公式如下:
有了節(jié)點(diǎn)條件獨(dú)立性質(zhì)之后,上式可以簡(jiǎn)化為:
當(dāng)由DAG表示節(jié)點(diǎn)關(guān)系和概率表確定后,相關(guān)的先驗(yàn)概率分布、條件概率分布就能夠確定,然后基于貝葉斯公式,我們就可以使用貝葉斯網(wǎng)絡(luò)進(jìn)行推斷。
借助于pgmpy的貝葉斯網(wǎng)絡(luò)實(shí)現(xiàn)
本小節(jié)基于pgmpy來構(gòu)造貝葉斯網(wǎng)絡(luò)和進(jìn)行建模訓(xùn)練。pgmpy是一款基于Python的概率圖模型包,主要包括貝葉斯網(wǎng)絡(luò)和馬爾可夫蒙特卡洛等常見概率圖模型的實(shí)現(xiàn)以及推斷方法。
我們以學(xué)生獲得的推薦信質(zhì)量的例子來進(jìn)行貝葉斯網(wǎng)絡(luò)的構(gòu)造。相關(guān)特征之間的DAG和概率表如圖5所示。
圖5 推薦信質(zhì)量的DAG和概率表
由圖5可知,考試難度、個(gè)人聰明與否都會(huì)影響到個(gè)人成績(jī),另外個(gè)人天賦高低也會(huì)影響到SAT分?jǐn)?shù),而個(gè)人成績(jī)好壞會(huì)直接影響到推薦信的質(zhì)量。下面我們直接來用pgmpy實(shí)現(xiàn)上述貝葉斯網(wǎng)絡(luò)模型。
(1)構(gòu)建模型框架,指定各變量之間的關(guān)系。如代碼5所示。
- # 導(dǎo)入pgmpy相關(guān)模塊
- from pgmpy.factors.discrete import TabularCPD
- from pgmpy.models import BayesianModel
- letter_model = BayesianModel([('D', 'G'),
- ('I', 'G'),
- ('G', 'L'),
- ('I', 'S')])
(2)構(gòu)建各個(gè)節(jié)點(diǎn)的條件概率分布,需要指定相關(guān)參數(shù)和傳入概率表,如代碼6所示。
- # 學(xué)生成績(jī)的條件概率分布
- grade_cpd = TabularCPD(
- variable='G', # 節(jié)點(diǎn)名稱
- variable_card=3, # 節(jié)點(diǎn)取值個(gè)數(shù)
- values=[[0.3, 0.05, 0.9, 0.5], # 該節(jié)點(diǎn)的概率表
- [0.4, 0.25, 0.08, 0.3],
- [0.3, 0.7, 0.02, 0.2]],
- evidence=['I', 'D'], # 該節(jié)點(diǎn)的依賴節(jié)點(diǎn)
- evidence_card=[2, 2] # 依賴節(jié)點(diǎn)的取值個(gè)數(shù)
- )
- # 考試難度的條件概率分布
- difficulty_cpd = TabularCPD(
- variable='D',
- variable_card=2,
- values=[[0.6], [0.4]]
- )
- # 個(gè)人天賦的條件概率分布
- 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.9, 0.6, 0.01]],
- evidence=['G'],
- evidence_card=[3]
- )
- # SAT考試分?jǐn)?shù)的條件概率分布
- sat_cpd = TabularCPD(
- variable='S',
- variable_card=2,
- values=[[0.95, 0.2],
- [0.05, 0.8]],
- evidence=['I'],
- evidence_card=[2]
- )
(3)將各個(gè)節(jié)點(diǎn)添加到模型中,構(gòu)建貝葉斯網(wǎng)絡(luò)。如代碼7所示。
- # 將各節(jié)點(diǎn)添加到模型中,構(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é)果可以看到,當(dāng)聰明的學(xué)生碰上較簡(jiǎn)單的考試時(shí),獲得第一等成績(jī)的概率高達(dá)90%。
小結(jié)
貝葉斯定理是經(jīng)典的概率模型之一,基于先驗(yàn)信息和數(shù)據(jù)觀測(cè)得到目標(biāo)變量的后驗(yàn)分布的方式,是貝葉斯的核心理論。貝葉斯理論在機(jī)器學(xué)習(xí)領(lǐng)域也有廣泛的應(yīng)用,最常用的貝葉斯機(jī)器學(xué)習(xí)模型包括樸素貝葉斯模型和貝葉斯網(wǎng)絡(luò)模型。
樸素貝葉斯模型是一種生成學(xué)習(xí)方法,通過數(shù)據(jù)學(xué)習(xí)聯(lián)合概率分布的方式來計(jì)算后驗(yàn)概率分布。之所以取名為樸素貝葉斯,是因?yàn)樘卣鞯臈l件獨(dú)立性假設(shè),能夠大大簡(jiǎn)化樸素貝葉斯算法的學(xué)習(xí)和預(yù)測(cè)過程,但也會(huì)帶來一定的精度損失。
進(jìn)一步地,將樸素貝葉斯的條件獨(dú)立假設(shè)放寬,認(rèn)為特征之間是存在相關(guān)性的貝葉斯模型就是貝葉斯網(wǎng)絡(luò)模型。貝葉斯網(wǎng)絡(luò)是一種概率無向圖模型,通過有向圖和概率表的方式來構(gòu)建貝葉斯概率模型。當(dāng)由有向圖表示節(jié)點(diǎn)關(guān)系和概率表確定后,相關(guān)的先驗(yàn)概率分布、條件概率分布就能夠確定,然后基于貝葉斯公式,就可以使用貝葉斯網(wǎng)絡(luò)進(jìn)行概率推斷。
本文參考代碼地址:
https://github.com/luwill/Machine_Learning_Code_Implementation/tree/master/charpter21_Bayesian_models