Advertisement

Python和贝叶斯网络:贝叶斯理论(6)

阅读量:

在前面的章节中我们学习了贝叶斯网络的基本知识。本章将利用Python建立如下图所示的贝叶斯网络:

在Python中建立贝叶斯网络要引入pgmpy包和pandas包,然后编写如下代码:

复制代码
 from pgmpy.models import BayesianModel

    
 from pgmpy.factors.discrete.CPD import TabularCPD
    
 import pandas as pd
    
  
    
 m = BayesianModel()  # 创建一个贝叶斯网络
    
 m.add_edge('爱情', '幸福')
    
 m.add_edge('事业', '幸福')
    
 m.add_edge('幸福', '长寿')
    
 m.add_edge('爱情', '长寿')
    
  
    
 # 填写先验概率和条件概率
    
 m.add_cpds(TabularCPD('爱情', 2, [[0.98], [0.02]]))
    
 m.add_cpds(TabularCPD('事业', 2, [[0.8], [0.2]]))
    
 m.add_cpds(TabularCPD('幸福', 2, [[0.99, 0.9, 0.5, 0], [0.01, 0.1, 0.5, 1.0]],
    
                   evidence=['爱情', '事业'], evidence_card=(2, 2)))
    
 m.add_cpds(TabularCPD('长寿', 2, [[0, 0.1, 0.7, 0.1], [1.0, 0.9, 0.3, 0.9]],
    
                   evidence=['幸福','爱情'], evidence_card=(2, 2)))
    
 # 检查模型,如果有错会抛出异常
    
 m.check_model()
    
  
    
 # 准备数据
    
 data = pd.DataFrame([[1, 0]], columns=['爱情', '长寿'])
    
 print(m.predict_probability(data))

代码中我们假定爱情、事业、幸福和长寿都只有两个状态,比如爱情的两个状态是:没爱情和有爱情。事业的两个状态是:事业无成和事业有成。幸福的两个状态是:不幸福与幸福。长寿的两个状态是:不长寿和长寿。

爱情和事业是入度为0的结点,所以只需为它们定义先验概率即可。代码

复制代码
    m.add_cpds(TabularCPD('爱情', 2, [[0.98], [0.02]]))

的作用是为爱情的两个状态设置先验概率:没爱情的可能性是98%,有爱情的可能性仅2%。

代码

复制代码
 m.add_cpds(TabularCPD('幸福', 2, [[0.99, 0.9, 0.5, 0], [0.01, 0.1, 0.5, 1.0]],

    
                   evidence=['爱情', '事业'], evidence_card=(2, 2)))

的作用是为幸福定义条件概率。由于幸福有两个先驱结点,所以应该在evidence参数中列出这两个先驱结点的名字,在evidence_card参数中列出每个先驱结点的状态的数量。由于爱情和事业各有两个状态,所有一共有4种组合,因此第三个参数(values)必须是一个2*4的矩阵或者二维列表,其中第一维的长度2等于幸福的状态数量,第二维的长度4等于先驱结点的所有可能组合数。在定义条件概率时,要保证同一列上所有概率之和等于1,也就是说,在先驱结点的同一个组合下,当前结点的各种状态的概率和应该等于1。

接着调用

复制代码
    m.check_model()

检查一下模型以保证你提供的数据都是合理的。如果不合理这个方法会扔出异常。再调用

复制代码
    data = pd.DataFrame([[1, 0]], columns=['爱情', '长寿'])

以准备数据。上述数据的含义是,某人有爱情但是不长寿。最后调用

复制代码
    m.predict_probability(data)

以获知这个人的事业和幸福情况。结果是:

复制代码
    幸福_0  幸福_1  事业_0  事业_1

    
 0   0.4   0.6   0.8   0.2

这意味着这个人幸福的可能性是60%,事业有成的可能性是20%。

怎么样?贝叶斯网络是不是很有趣?

全部评论 (0)

还没有任何评论哟~