1. 程式人生 > >機器學習-貝葉斯網路

機器學習-貝葉斯網路

一,介紹

無論是樸素貝葉斯或者是半樸素貝葉斯,都是建立在所有屬性獨立或者僅僅只有很少的屬性有依賴的前提下。但是,現實環境中很多屬性之間都是相互關聯、相互影響的,因而我們用一個有向無黃網來刻畫屬性之間的關係,並用條件概率表來描述屬性的聯合概率分佈,這個就稱為貝葉斯網路,也叫信念網。

二,從全概率和貝葉斯公式到貝葉斯網路

全概率公式:

設事件是一個完備事件組,則對於任意一個事件C,若有如下公式成立:

                                            

那麼就稱這個公式為全概率公式。

全概率就是表示達到某個目的,有多種方式(或者造成某種結果,有多種原因),問達到目的的概率是多少。

貝葉斯公式:

                                                             

貝葉斯公式就是當已知結果,問導致這個結果的第i原因的可能性是多少?

根據以上公式,我們舉例如下,看如何構建一個貝葉斯網路:

我們有如下資料:

'色澤','根蒂','敲聲','紋理','頭部','觸感','好瓜'
 青綠,  蜷縮,  濁響,  清晰,  凹陷,  硬滑,  是
 烏黑,  蜷縮,  沉悶,  清晰,  凹陷,  硬滑,  是
 烏黑,  蜷縮,  濁響,  清晰,  凹陷,  硬滑,  是
 青綠,  蜷縮,  沉悶,  清晰,  凹陷,  硬滑,  是
 淺白,  蜷縮,  濁響,  清晰,  凹陷,  硬滑,  是
 青綠,  稍蜷,  濁響,  清晰,  稍凹,  軟粘,  是
 烏黑,  稍蜷,  濁響,  稍糊,  稍凹,  軟粘,  是
 烏黑,  稍蜷,  濁響,  清晰,  稍凹,  硬滑,  是
 烏黑,  稍蜷,  沉悶,  稍糊,  稍凹,  硬滑,  否
 青綠,  硬挺,  清脆,  清晰,  平坦,  軟粘,  否
 淺白,  硬挺,  清脆,  模糊,  平坦,  硬滑,  否
 淺白,  蜷縮,  濁響,  模糊,  平坦,  軟粘,  否
 青綠,  稍蜷,  濁響,  稍糊,  凹陷,  硬滑,  否
 淺白,  稍蜷,  沉悶,  稍糊,  凹陷,  硬滑,  否
 烏黑,  稍蜷,  濁響,  清晰,  稍凹,  軟粘,  否
 淺白,  蜷縮,  濁響,  模糊,  平坦,  硬滑,  否
 青綠,  蜷縮,  沉悶,  稍糊,  稍凹,  硬滑,  否

我們做出假設:1,紋理依賴於色澤;2,頭部依賴於根蒂;3,觸感依賴於頭部和敲聲;4,用所有屬性綜合來判斷是否為好瓜。

根據上面的資料和假設,我們開始構建貝葉斯網路。貝葉斯網路的構造一般分為兩步:確定網路拓撲和確定網路引數。

(1)確定網路拓撲。根據我們的假設可以畫出下拓撲圖:

                                                            

(2)確定網路引數。根據資料計算可得帶網路引數的拓撲圖:

我們的測試資料為: 色澤=淺白, 根蒂=稍蜷, 敲聲=沉悶, 紋理=清晰, 頭部=稍凹, 觸感=軟粘。我們可以計算:色澤=淺白&好瓜=是的概率為1/8;根蒂=稍蜷&好瓜=是的概率為5/8;敲聲=沉悶&好瓜=是的概率為2/8;紋理=清晰&色澤=淺白&好瓜=是的概率為1/1;頭部=稍凹& 根蒂=稍蜷&好瓜=是的概率為3/3;觸感=軟粘&頭部=稍凹&好瓜=是的概率為2/3;好瓜=是的概率為8/17,我們把求得的概率相乘得:0.006127。同理求得壞瓜為(紋理=清晰&色澤=淺白&好瓜=否概率為0 ,為了方便用0.01代替):0.0001936,歸一化結果為:好瓜概率=0.96936,壞瓜概率= 0.03064,。所以判定測試資料為好瓜。

三,程式碼實現

from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
import pandas as pd
import numpy as np

if __name__ == '__main__':
    watermelon_model = BayesianModel([('Good', 'Color'),                        # 構建貝葉斯網路
                                  ('Good', 'Texture'),
                                  ('Good', 'RootPedicle'),
                                  ('Good', 'Head'),
                                  ('Good', 'Stroke'),
                                  ('Good', 'Touch'),
                                  ('Color', 'Texture'),
                                  ('RootPedicle', 'Head'),
                                  ('Head', 'Touch')])
    cpd_Good = TabularCPD(variable='Good', variable_card=2,                       # 設定引數
                          values=[[0.47059],
                                  [0.52941]])
    cpd_Color = TabularCPD(variable='Color', variable_card=3,
                           values=[[0.375, 0.33333],
                                   [0.5,   0.22222],
                                   [0.125, 0.44445]],
                           evidence=['Good'], evidence_card=[2])
    cpd_Texture = TabularCPD(variable='Texture', variable_card=3,
                           values=[[1, 0.75, 1, 0.33333, 0.5, 0],
                                   [0, 0.25, 0, 0.66667, 0.5, 0.25],
                                   [0, 0,    0, 0,       0,   0.75]],
                           evidence=['Good','Color'], evidence_card=[2,3])
    cpd_RootPedicle = TabularCPD(variable='RootPedicle', variable_card=3,
                           values=[[0.625, 0.44445],
                                   [0.375, 0.33333],
                                   [0,     0.22222]],
                           evidence=['Good'], evidence_card=[2])
    cpd_Head = TabularCPD(variable='Head', variable_card=3,
                             values=[[1, 0, 0.33333, 0,       0.5, 0],
                                     [0, 1, 0.33333, 0.33333, 0.5, 0],
                                     [0, 0, 0.33334, 0.66667, 0,   1]],
                             evidence=['Good', 'RootPedicle'], evidence_card=[2, 3])
    cpd_Stroke = TabularCPD(variable='Stroke', variable_card=3,
                           values=[[0.75, 0.44445],
                                   [0.25, 0.33333],
                                   [0,    0.22222]],
                           evidence=['Good'], evidence_card=[2])
    cpd_Touch = TabularCPD(variable='Touch', variable_card=2,
                             values=[[1, 0.33333, 0.5, 1, 0.66667, 0.5],
                                     [0, 0.66667, 0.5, 0, 0.33333, 0.5]],
                             evidence=['Good', 'Head'], evidence_card=[2, 3])
    watermelon_model.add_cpds(cpd_Good,cpd_Color,cpd_Texture,cpd_RootPedicle,cpd_Head,cpd_Stroke,cpd_Touch)   # 將引數新增進網路
    watermelon_model.check_model()         # 檢查貝葉斯網路
    data = pd.DataFrame([[2,0,1,0,1,1]],columns = ['Color', 'Texture', 'RootPedicle', 'Head', 'Stroke','Touch'])   # 新增測試資料(色澤=淺白, 根蒂=稍蜷, 敲聲=沉悶, 紋理=清晰, 頭部=稍凹, 觸感=軟粘)
    reslut = watermelon_model.predict(data)   # 預測
    print(reslut)

結果為:Good