PGMPY手册01:安装、基本数据结构

PGMPY手册01:安装、基本数据结构,第1张

PGMPY文档

简介: PGMPY的全称是Probability Graph Model in PYthon,顾名思义是基于python开发的概率图模型工具包,包含贝叶斯网模型、动态贝叶斯网模型、结构方程模型、NoisyOr模型、马尔可夫网模型、联合树模型、团树模型、因子图模型、马尔可夫链等。利用该工具包,可进行贝叶斯网推理、参数学习、结构学习,和因果推理等。

文章目录
  • 1. 安装
  • 2. 基本数据结构
    • 2.1 有向无回路图(DAG)
      • 2.1.1 添加节点、边
      • 2.1.2 有效迹
      • 2.1.3 干预
      • 2.1.4 端正化缺边
      • 2.1.5 独立性
      • 2.1.6 获取叶节点
      • 2.1.7 获取根节点
      • 2.1.8 获取父节点
      • 2.1.9 马尔可夫边界
      • 2.1.10 随机生成贝叶斯网
      • 2.1.11 迹连接
      • 2.1.12 独立性等价
      • 2.1.13 局部马尔可夫性(局部独立性)
      • 2.1.14 最小d分隔节点集
      • 2.1.15 端正化
      • 2.1.16 绘图
      • 2.1.17 转换为PDAG
    • 2.2 部分有向无回路图(Partial Directed Acyclic Graph, PDAG)
      • 2.2.1 复制副本
      • 2.2.2 转换为DAG

1. 安装

PGMPY支持的Python最低版本为3.7。在pypi、anaconda以及国内各镜像平台都有部署。可通过如下命令安装:

pip install pgmpy

conda install -c ankurnkan pgmpy

也可通过github安装最新开发版:

pip install git+https://github.com/pgmpy/pgmpy.git@dev

PGMPY采用MIT开源协议,可自由使用、复制、修改,限制较少。

2. 基本数据结构 2.1 有向无回路图(DAG)
class pgmpy.base.DAG(ebunch=None, latents={})

该类是所有有向图模型的基类。参数ebunch是边集合,见下方示例。
首先,我们可以构建空图:

>>> from pgmpy.base import DAG
>>> G = DAG()
2.1.1 添加节点、边

可通过加节点或加边的方式扩充图:

>>> G.add_node(node='a') # 添加一个节点
>>> G.add_nodes_from(nodes=['a','b']) # 添加一组节点
>>> G.add_edge(u='a',v='b') # 添加一条边
>>> G.add_edges_from(ebunch=[('a','b'),('b','c')]) # 添加一组边
>>> G.nodes()
NodeView(('a', 'b', 'c'))
>>> G.edges()
OutEdgeView([('a', 'b'), ('b', 'c')])

若在添加边时,边的节点不在图中,则节点会被自动添加。
重复添加边和节点不会报错。
针对G,还有一些符合python语法的快捷 *** 作:

>>> 'a' in G # 检查节点a是否在G中
True
>>> len(G) # G中节点数
3
2.1.2 有效迹

在贝叶斯网专题3中介绍过迹的概念,表示一条通路。有效迹(active trail)是指在给定某些观察变量后,仍有效的通路。比如x->z->y通路,给定z后经过x的迹只有x,若z未知,则经过x的迹为x->z->y。分连和汇连情况参考前面给出的专题3.
PGMPY通过函数activate_trail_nodes来判断有效迹。

active_trail_nodes(variables,ovserved=None,include_latents=False)

输入参数:

  • variables(str or array): 经过这些节点去寻找迹
  • observed(list of nodes): 观察到的节点
  • include_latents(boolean): 是否包含隐变量

例:

>>> from pgmpy.base import DAG
>>> student = DAG()
>>> student.add_nodes_from(['diff', 'intel', 'grades'])
>>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades')])
>>> student.active_trail_nodes('diff')
{'diff': {'diff', 'grades'}}
>>> student.active_trail_nodes(['diff', 'intel'], observed='grades')
{'diff': {'diff', 'intel'}, 'intel': {'diff', 'intel'}}
2.1.3 干预

因果推理中的do算子,do(X)即删除所有指向X节点的边,并将X设定为给定的值x。

do(nodes, inplace=False)

输入参数:

  • nodes(list, array-like): 应用do算子的节点名列表
  • inplace(boolean (default: False)): 若为True,则在原图上就地修剪,否则返回一个新图

返回值:

  • (pgmpy.base.DAG): 修改后的DAG图

例:

>>> from pgmpy.base import DAG
>>> graph = DAG() 
>>> graph.add_edges_from([(‘X’, ‘A’),(‘A’, ‘Y’),(‘A’, ‘B’)]) 
>>> graph_do_A = graph.do(‘A’) 
>>> graph_do_A.edges 
OutEdgeView([(‘A’, ‘B’), (‘A’, ‘Y’)])
2.1.4 端正化缺边

将DAG图转化为无向图时,为了保持变量之间的相关关系,对于汇连节点,应增加父节点之间的关联边,转换后的无向图称为端正图(moral graph)。

get_immoralities()

返回值:

  • (set): DAG图转换为端正图所需要添加的边集

例:

>>> from pgmpy.base import DAG
>>> student = DAG()
>>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'),
...                         ('intel', 'SAT'), ('grade', 'letter')])
>>> student.get_immoralities()
{('diff', 'intel')}
2.1.5 独立性

通过检查d-分隔计算变量之间的独立性。

get_independencies(latex=False, include_latents=False)

输入参数:

  • latex(boolean): 若为True,则输出用latex表达的独立性断言
  • include_latents(boolean): 若为True,则输出的独立性断言中包含隐变量,否则不包括隐变量

例:

>>> from pgmpy.base import DAG
>>> chain = DAG([('X', 'Y'), ('Y', 'Z')])
>>> chain.get_independencies()
(X ⟂ Z | Y)
(Z ⟂ X | Y)
2.1.6 获取叶节点

get_leaves()

返回值:

  • (list): 图的叶节点列表

例:

>>> from pgmpy.base import DAG
>>> graph = DAG([('A', 'B'), ('B', 'C'), ('B', 'D')])
>>> graph.get_leaves()
['C', 'D']
2.1.7 获取根节点

get_roots()

返回值:

  • (list): 图的根节点列表

例:

>>> from pgmpy.base import DAG
>>> graph = DAG([('A', 'B'), ('B', 'C'), ('B', 'D'), ('E', 'B')])
>>> graph.get_roots()
['A', 'E']
2.1.8 获取父节点

get_parents(node)

输入参数:

  • node(string, int or any hashable python object): 目标节点

返回值:

  • (list): 目标节点的父节点列表

例:

>>> from pgmpy.base import DAG
>>> G = DAG(ebunch=[('diff', 'grade'), ('intel', 'grade')])
>>> G.get_parents(node='grade')
['diff', 'intel']
2.1.9 马尔可夫边界

在贝叶斯网专题3中介绍过马尔可夫边界的概念:一个节点的马尔可夫边界包括其父节点、子节点,以及子节点的父节点。给定某节点的马尔可夫边界,该节点与贝叶斯网中其它节点独立。

get_markov_blanket(node)

输入参数:

  • node(string, int or any hashable python object): 待计算马尔可夫边界的节点

返回值:

  • (list): 马尔可夫边界中的节点列表

例:

>>> from pgmpy.base import DAG
>>> from pgmpy.factors.discrete import TabularCPD
>>> G = DAG([('x', 'y'), ('z', 'y'), ('y', 'w'), ('y', 'v'), ('u', 'w'),
                       ('s', 'v'), ('w', 't'), ('w', 'm'), ('v', 'n'), ('v', 'q')])
>>> G.get_markov_blanket('y')
['s', 'w', 'x', 'u', 'z', 'v']
2.1.10 随机生成贝叶斯网

static get_random(n_nodes=5, edge_prob=0.5, latents=False)

输入参数:

  • n_nodes(int): 生成图的节点数
  • edge_prob(float): 任意两节点之间存在边的概率
  • latents(bool): 是否包含隐变量

返回值:

  • (pgmpy.base.DAG): 随机生成的DAG图

例:

>>> from pgmpy.base import DAG
>>> random_dag = DAG.get_random(n_nodes=10, edge_prob=0.3)
>>> random_dag.nodes()
NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
>>> random_dag.edges()
OutEdgeView([(0, 6), (1, 6), (1, 7), (7, 9), (2, 5), (2, 7), (2, 8), (5, 9), (3, 7)])
2.1.11 迹连接

判断两个节点之间是否存在有效迹。

is_dconnected(start, end, observed=None)

输入参数:

  • start(int, str, any hashable python object): 有效迹起点
  • end(int,str, any hashable python object): 有效迹终点
  • observed(list): 已观测节点列表,会根据已观测节点计算有效迹

返回值:

  • (bool): 起点和终点间是否存在有效迹

例:

>>> from pgmpy.base import DAG
>>> student = DAG()
>>> student.add_nodes_from(['diff', 'intel', 'grades', 'letter', 'sat'])
>>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades'), ('grades', 'letter'),
...                         ('intel', 'sat')])
>>> student.is_dconnected('diff', 'intel')
False
>>> student.is_dconnected('grades', 'sat')
True
2.1.12 独立性等价

两个DAG图端正化后,若具有相同拓扑结构,则称为独立性等价(I-equivalent)。

is_iequivalent(model)

输入参数:

  • model(pgmpy.base.DAG): 判断是否独立性等价的DAG对象

返回值:

  • (bool): 是否独立性等价

例:

>>> from pgmpy.base import DAG
>>> G = DAG()
>>> G.add_edges_from([('V', 'W'), ('W', 'X'),
...                   ('X', 'Y'), ('Z', 'Y')])
>>> G1 = DAG()
>>> G1.add_edges_from([('W', 'V'), ('X', 'W'),
...                    ('X', 'Y'), ('Z', 'Y')])
>>> G.is_iequivalent(G1)
True
2.1.13 局部马尔可夫性(局部独立性)

在贝叶斯网专题3中介绍过局部马尔可夫性的概念:给定某节点的父节点集,则该节点条件独立于它的所有非后代节点。

local_independencies(variables)

输入变量:

  • variables(str or array like): 寻找局部独立的目标节点

返回值:

  • (Independencies对象): 独立性断言

例:

>>> from pgmpy.base import DAG
>>> student = DAG()
>>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'),
>>>                         ('grade', 'letter'), ('intel', 'SAT')])
>>> ind = student.local_independencies('grade')
>>> ind
(grade ⟂ SAT | diff, intel)
2.1.14 最小d分隔节点集

寻找最小d分隔节点集的算法可参考文献:Algorithm 4, Page 10: Tian, Jin, Azaria Paz, and Judea Pearl. Finding minimal d-separators. Computer Science Department, University of California, 1998.

minimal_dseparator(start, end)

输入变量:

  • start(node): 第一个节点
  • end(node): 第二个节点

返回值:

  • (list): 将第一个节点和第二个节点d分隔的最小节点集

例:

>>> dag = DAG([('A', 'B'), ('B', 'C')])
>>> dag.minimal_dseparator(start='A', end='C')
{'B'}
2.1.15 端正化

将DAG图端正化为无向图,其中所有的汇连结构x->z<-y都增加x与y之间的无向边。

moralize()

返回值:

  • (pgmpy.base.UndirectedGraph): 端正化后的无向图

例:

>>> from pgmpy.base import DAG
>>> G = DAG(ebunch=[('diff', 'grade'), ('intel', 'grade')])
>>> moral_graph = G.moralize()
>>> moral_graph.edges()
EdgeView([('intel', 'grade'), ('intel', 'diff'), ('grade', 'diff')])
2.1.16 绘图

pgmpy支持将DAG图导出为daft.PGM对象(https://docs.daft-pgm.org/en/latest/),该对象可调用show()函数绘制出高质量的图形。

to_daft(node_pos=‘circular’, latex=True, pgm_params={}, edge_params={}, node_params={})

输入参数:

  • node_pos(str or dict): 若是字符串,则只能是如下几种: circular, kamada_kawai, planar, random, shell, sprint, spectral, spiral. 其含义可参考networkx绘图工具的文档https://networkx.org/documentation/stable//reference/drawing.html#module-networkx.drawing.layout。若为字典,则可枚举各节点的位置,格式为{node1:(x轴坐标, y轴坐标), …}
  • latex(bool): 是否使用latex渲染节点名
  • pgm_params(dict): 传递给daft.PGM对象初始化函数的参数,格式为{param_name: param_value, …}
  • edge_params(dict): 传递给daft.add_edge方法的参数,格式为{(u1,v1):{param_name: param_value, …}, …}
  • node_params(dict): 传递给daft.add_node方法的参数,格式为{node1:{param_name: param_value, …}, …}

返回值:

  • (daft.PGM object): 可用于绘制DAG图的Daft对象

例:

>>> from pgmpy.base import DAG
>>> dag = DAG([('a', 'b'), ('b', 'c'), ('d', 'c')])
>>> dag.to_daft(node_pos={'a': (0, 0), 'b': (1, 0), 'c': (2, 0), 'd': (1, 1)})

>>> dag.to_daft(node_pos="circular")

>>> dag.to_daft(node_pos="circular", pgm_params={'observed_style': 'inner'})

>>> dag.to_daft(node_pos="circular",
...             edge_params={('a', 'b'): {'label': 2}},
...             node_params={'a': {'shape': 'rectangle'}})

2.1.17 转换为PDAG

若DAG图中存在两个节点有双向边,则将这两条有向边合并为一条无向边。处理以后得到的图则为部分有向无回路图(PDAG)。

to_pdag()

返回值:

  • (pgmpy.base.PDAG): 返回对应的PDGA图
2.2 部分有向无回路图(Partial Directed Acyclic Graph, PDAG)

class pgmpy.base.PDAG(directed_ebunch=[], undirected_ebunch=[], latents=[])

该类是部分有向无回路图模型的基类。参数ebunch是边集合。PDAG可同时包含有向边和无向边,其中无向边表示双向边,如边X-Y表示X->Y和X<-Y.

2.2.1 复制副本

copy()

返回值:

  • (pgmpy.base.PDAG): 返回一个副本
2.2.2 转换为DAG

to_dag(required_edges=[])

输入参数:

  • required_edges(list, array-like of 2-tuples): 需要在DAG图中包含的边集

返回值:

  • (pgmpy.base.DAG): 转换得到的DAG图

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/727515.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存