機器學習-貝葉斯網路
一,介紹
無論是樸素貝葉斯或者是半樸素貝葉斯,都是建立在所有屬性獨立或者僅僅只有很少的屬性有依賴的前提下。但是,現實環境中很多屬性之間都是相互關聯、相互影響的,因而我們用一個有向無黃網來刻畫屬性之間的關係,並用條件概率表來描述屬性的聯合概率分佈,這個就稱為貝葉斯網路,也叫信念網。
二,從全概率和貝葉斯公式到貝葉斯網路
全概率公式:
設事件是一個完備事件組,則對於任意一個事件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