机器学习-贝叶斯网络

一,介绍

无论是朴素贝叶斯或者是半朴素贝叶斯,都是建立在所有属性独立或者仅仅只有很少的属性有依赖的前提下。但是,现实环境中很多属性之间都是相互关联、相互影响的,因而我们用一个有向无黄网来刻画属性之间的关系,并用条件概率表来描述属性的联合概率分布,这个就称为贝叶斯网络,也叫信念网。

二,从全概率和贝叶斯公式到贝叶斯网络

全概率公式:

设事件是一个完备事件组,则对于任意一个事件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

猜你喜欢

转载自blog.csdn.net/lyn5284767/article/details/82491202