【问题标题】:Create Bayesian Network and learn parameters with Python3.x [closed]使用 Python3.x 创建贝叶斯网络并学习参数 [关闭]
【发布时间】:2015-04-10 11:11:33
【问题描述】:

我正在为 Windows 上的 python3.x 寻找最合适的工具来创建贝叶斯网络,从数据中学习其参数并执行推理。

我要自己定义的网络结构如下:

取自this论文。

除了“Size”和“GraspPose”之外,所有变量都是离散的(只能采用两种可能的状态),它们是连续的,应该建模为高斯混合。

作者使用期望最大化算法来学习条件概率表的参数,并使用连接树算法来计算准确的推理。

据我所知,所有这些都是在 MatLab 中使用 Murphy 的 Bayes Net Toolbox 实现的。

我尝试在 python 中搜索类似的东西,这是我的结果:

  1. Python 贝叶斯网络工具箱http://sourceforge.net/projects/pbnt.berlios/ (http://pbnt.berlios.de/)。网站不工作,项目似乎不被支持。
  2. 贝叶斯派https://github.com/bayespy/bayespy 我认为这是我真正需要的,但是我没有找到一些与我的案例相似的例子,以了解如何处理网络结构的构建。
  3. PyMC 似乎是一个强大的模块,但我在 Windows 64、python 3.3 上导入它时遇到问题。安装开发版时出现错误

    警告(theano.configdefaults):未检测到 g++! Theano 将无法执行优化的 C 实现(针对 CPU 和 GPU),并将默认使用 Python 实现。性能会严重下降。要删除此警告,请将 Theano flags cxx 设置为空字符串。

更新:

  1. libpgm (http://pythonhosted.org/libpgm/)。正是我需要的,不幸的是 python 3.x 不支持
  2. 非常有趣的积极开发库:PGMPY。不幸的是,还不支持连续变量和从数据中学习。 https://github.com/pgmpy/pgmpy/

我们将不胜感激任何建议和具体示例。

【问题讨论】:

标签: python-3.x machine-learning scikit-learn probability bayesian-networks


【解决方案1】:

看起来pomegranate 最近更新为包含贝叶斯网络。我自己没有尝试过,但界面看起来不错,而且 sklearn-ish。

【讨论】:

  • 是的,看起来很有希望,谢谢。我会试一试。期待何时也支持连续变量。
  • @Spu 你试过了吗?你的经历是什么?
【解决方案2】:

对于 pymc 的 g++ 问题,我强烈建议完成 g++ 安装,这将极大地促进采样过程,否则您将不得不忍受这个警告并坐在那里 1 小时进行 2000 个采样过程。

修复警告的方法是: 1. 安装g++,下载cywing,安装g++,可以google一下。要检查这一点,只需转到“cmd”并输入“g++”,如果它显示“需要输入文件”,很好,你已经安装了 g++。 2.安装python包:mingw、libpython 3.安装python包:theano

这应该可以解决这个问题。

我目前正在和你一起解决同样的问题,祝你好运!

【讨论】:

    【解决方案3】:

    和往常一样迟到了,但我已经使用 JPype 完成了 BayesServer Java API;它可能没有您需要的所有功能,但您可以使用以下方式创建上述网络:

    from bayesianpy.network import Builder as builder
    import bayesianpy.network
    
    nt = bayesianpy.network.create_network()
    
    # where df is your dataframe
    task = builder.create_discrete_variable(nt, df, 'task')
    
    size = builder.create_continuous_variable(nt, 'size')
    grasp_pose = builder.create_continuous_variable(nt, 'GraspPose')
    
    builder.create_link(nt, size, grasp_pose)
    builder.create_link(nt, task, grasp_pose)
    
    for v in ['fill level', 'object shape', 'side graspable']:
        va = builder.create_discrete_variable(nt, df, v)
        builder.create_link(nt, va, grasp_pose)
        builder.create_link(nt, task, va)
    
    # write df to data store
    with bayesianpy.data.DataSet(df, bayesianpy.utils.get_path_to_parent_dir(__file__), logger) as dataset:
        model = bayesianpy.model.NetworkModel(nt, logger)
        model.train(dataset)
    
        # to query model multi-threaded
        results = model.batch_query(dataset, [bayesianpy.model.QueryModelStatistics()], append_to_df=False)
    

    我不隶属于 Bayes Server - Python 包装器不是“官方的”(您可以直接通过 Python 使用 Java API)。我的包装器做了一些假设并对我不经常使用的函数进行了限制。仓库在这里:github.com/morganics/bayesianpy

    【讨论】:

      【解决方案4】:

      我正在寻找一个类似的库,我发现pomegranate 是一个不错的库。谢谢James Atwood

      这是一个如何使用它的示例。

      from pomegranate import *
      import numpy as np
      
      mydb=np.array([[1,2,3],[1,2,4],[1,2,5],[1,2,6],[1,3,8],[2,3,8],[1,2,4]])
      
      bnet = BayesianNetwork.from_samples(mydb)
      
      print(bnet.node_count())
      
      print(bnet.probability([[1,2,3]]))
      print (bnet.probability([[1,2,8]]))
      

      【讨论】:

        【解决方案5】:

        试试 bnlearn 库,它包含许多从数据中学习参数并执行推理的函数。

        pip install bnlearn
        

        你的用例应该是这样的:

        # Import the library
        import bnlearn
        
        # Define the network structure
        edges = [('task', 'size'),
                 ('lat var', 'size'),
                 ('task', 'fill level'),
                 ('task', 'object shape'),
                 ('task', 'side graspable'),
                 ('size', 'GrasPose'),
                 ('task', 'GrasPose'),
                 ('fill level', 'GrasPose'),
                 ('object shape', 'GrasPose'),
                 ('side graspable', 'GrasPose'),
                 ('GrasPose', 'latvar'),
        ]
        
        # Make the actual Bayesian DAG
        DAG = bnlearn.make_DAG(edges)
        
        # DAG is stored in adjacency matrix
        print(DAG['adjmat'])
        
        # target           task   size  lat var  ...  side graspable  GrasPose  latvar
        # source                                 ...                                  
        # task            False   True    False  ...            True      True   False
        # size            False  False    False  ...           False      True   False
        # lat var         False   True    False  ...           False     False   False
        # fill level      False  False    False  ...           False      True   False
        # object shape    False  False    False  ...           False      True   False
        # side graspable  False  False    False  ...           False      True   False
        # GrasPose        False  False    False  ...           False     False    True
        # latvar          False  False    False  ...           False     False   False
        # 
        # [8 rows x 8 columns]
        
        # No CPDs are in the DAG. Lets see what happens if we print it.
        bnlearn.print_CPD(DAG)
        # >[BNLEARN.print_CPD] No CPDs to print. Use bnlearn.plot(DAG) to make a plot.
        
        # Plot DAG. Note that it can be differently orientated if you re-make the plot.
        bnlearn.plot(DAG)
        

        现在我们需要数据来学习它的参数。假设这些存储在您的 df 中。数据文件中的变量名称必须存在于 DAG 中。

        # Read data
        df = pd.read_csv('path_to_your_data.csv')
        
        # Learn the parameters and store CPDs in the DAG. Use the methodtype your desire. Options are maximumlikelihood or bayes.
        DAG = bnlearn.parameter_learning.fit(DAG, df, methodtype='maximumlikelihood')
        # CPDs are present in the DAG at this point.
        bnlearn.print_CPD(DAG)
        
        # Start making inferences now. As an example:
        q1 = bnlearn.inference.fit(DAG, variables=['lat var'], evidence={'fill level':1, 'size':0, 'task':1})
        

        下面是一个带有演示数据集(sprinkler)的工作示例。你可以玩这个。

        # Import example dataset
        df = bnlearn.import_example('sprinkler')
        print(df)
        #      Cloudy  Sprinkler  Rain  Wet_Grass
        # 0         0          0     0          0
        # 1         1          0     1          1
        # 2         0          1     0          1
        # 3         1          1     1          1
        # 4         1          1     1          1
        # ..      ...        ...   ...        ...
        # 995       1          0     1          1
        # 996       1          0     1          1
        # 997       1          0     1          1
        # 998       0          0     0          0
        # 999       0          1     1          1
        
        # [1000 rows x 4 columns]
        
        
        # Define the network structure
        edges = [('Cloudy', 'Sprinkler'),
                 ('Cloudy', 'Rain'),
                 ('Sprinkler', 'Wet_Grass'),
                 ('Rain', 'Wet_Grass')]
        
        # Make the actual Bayesian DAG
        DAG = bnlearn.make_DAG(edges)
        # Print the CPDs
        bnlearn.print_CPD(DAG)
        # [BNLEARN.print_CPD] No CPDs to print. Use bnlearn.plot(DAG) to make a plot.
        # Plot the DAG
        bnlearn.plot(DAG)
        

        # Parameter learning on the user-defined DAG and input data
        DAG = bnlearn.parameter_learning.fit(DAG, df)
        
        # Print the learned CPDs
        bnlearn.print_CPD(DAG)
        
        # [BNLEARN.print_CPD] Independencies:
        # (Cloudy _|_ Wet_Grass | Rain, Sprinkler)
        # (Sprinkler _|_ Rain | Cloudy)
        # (Rain _|_ Sprinkler | Cloudy)
        # (Wet_Grass _|_ Cloudy | Rain, Sprinkler)
        # [BNLEARN.print_CPD] Nodes: ['Cloudy', 'Sprinkler', 'Rain', 'Wet_Grass']
        # [BNLEARN.print_CPD] Edges: [('Cloudy', 'Sprinkler'), ('Cloudy', 'Rain'), ('Sprinkler', 'Wet_Grass'), ('Rain', 'Wet_Grass')]
        # CPD of Cloudy:
        # +-----------+-------+
        # | Cloudy(0) | 0.494 |
        # +-----------+-------+
        # | Cloudy(1) | 0.506 |
        # +-----------+-------+
        # CPD of Sprinkler:
        # +--------------+--------------------+--------------------+
        # | Cloudy       | Cloudy(0)          | Cloudy(1)          |
        # +--------------+--------------------+--------------------+
        # | Sprinkler(0) | 0.4807692307692308 | 0.7075098814229249 |
        # +--------------+--------------------+--------------------+
        # | Sprinkler(1) | 0.5192307692307693 | 0.2924901185770751 |
        # +--------------+--------------------+--------------------+
        # CPD of Rain:
        # +---------+--------------------+---------------------+
        # | Cloudy  | Cloudy(0)          | Cloudy(1)           |
        # +---------+--------------------+---------------------+
        # | Rain(0) | 0.6518218623481782 | 0.33695652173913043 |
        # +---------+--------------------+---------------------+
        # | Rain(1) | 0.3481781376518219 | 0.6630434782608695  |
        # +---------+--------------------+---------------------+
        # CPD of Wet_Grass:
        # +--------------+--------------------+---------------------+---------------------+---------------------+
        # | Rain         | Rain(0)            | Rain(0)             | Rain(1)             | Rain(1)             |
        # +--------------+--------------------+---------------------+---------------------+---------------------+
        # | Sprinkler    | Sprinkler(0)       | Sprinkler(1)        | Sprinkler(0)        | Sprinkler(1)        |
        # +--------------+--------------------+---------------------+---------------------+---------------------+
        # | Wet_Grass(0) | 0.7553816046966731 | 0.33755274261603374 | 0.25588235294117645 | 0.37910447761194027 |
        # +--------------+--------------------+---------------------+---------------------+---------------------+
        # | Wet_Grass(1) | 0.2446183953033268 | 0.6624472573839663  | 0.7441176470588236  | 0.6208955223880597  |
        # +--------------+--------------------+---------------------+---------------------+---------------------+
        
        # Make inference
        q1 = bnlearn.inference.fit(DAG, variables=['Wet_Grass'], evidence={'Rain':1, 'Sprinkler':0, 'Cloudy':1})
        
        # +--------------+------------------+
        # | Wet_Grass    |   phi(Wet_Grass) |
        # +==============+==================+
        # | Wet_Grass(0) |           0.2559 |
        # +--------------+------------------+
        # | Wet_Grass(1) |           0.7441 |
        # +--------------+------------------+
        
        print(q1.values)
        # array([0.25588235, 0.74411765])
        

        更多示例可以在bnlearnread the blog 的页面上找到。

        【讨论】:

        • 这很好!谢谢
        猜你喜欢
        • 2015-06-07
        • 1970-01-01
        • 2020-04-15
        • 1970-01-01
        • 2012-02-25
        • 2013-04-08
        • 2016-05-01
        • 2013-09-11
        相关资源
        最近更新 更多