python - import pbnt (bayes net module) and getting AttributeError

1k views Asked by At

I am using a library for a Bayesian network and am trying to create a Bayes Net Disease Predictor using a module called pbnt (https://github.com/thejinxters/pbnt). I am getting an attribute error when trying to execute the code.

import sys
from numpy import *
import ExampleModels as EX
sys.path.append('../lib')
from pbnt.Graph import *
from pbnt.Distribution import *
from pbnt.Node import *
from pbnt.Inference import *

#bayes network using pbnt library

def create_disease_net():

    number_of_nodes = 5
    pollution = 0
    smoker = 1
    cancer = 2
    xray = 3
    dyspnoea = 4
    #events are pollution(high or low), smoker(true or false)
    #   cancer(true or false), xray(positive or negative), dyspnoea(true or false)
    pollution_node = Node.BayesNode(0,1, name="pollution")
    smoker_node = Node.BayesNode(1,1, name="smoker") 
    cancer_node = Node.BayesNode(2,4, name="cancer")
    xray_node = Node.BayesNode(3,1, name="xray")
    dyspnoea_node = Node.BayesNode(4,1, name="dyspnoea")  

    #pollution and smoker are parents of cancer node
    #pollution and smoker are independent
    pollution_node.add_child(cancer_node)
    smoker_node.add_child(cancer_node)

    cancer_node.add_parent(pollution_node)
    cancer_node.add_parent(smoker_node) 

    #cancer node is parent of xray and dyspnoea nodes
    cancer_node.add_child(xray_node)
    cancer_node.add_child(dyspnoea_node)

    #are xray and dyspnoea independent??????
    xray_node.add_parent(cancer_node)
    dyspnoea_node.add_parent(cancer_node)

    nodes = [pollution_node, smoker_node, cancer_node, xray_node, dyspnoea_node]

    #create distributions
    #pollution distribution
    pollution_distribution = DiscreteDistribution(pollution_node)
    index = pollution_distribution.generate_index([],[])
    pollution_distribution[index] = 0.9 #pollution = low
    pollution_node.set_dist(pollution_distribution)

    #smoker distribution
    smoker_distribution = DiscreteDistribution(smoker_node)
    index = smoker_distribution.generate_index([],[])
    smoker_distribution[index] = 0.3 #smoker = true
    smoker_node.set_dist(smoker_distribution)    

    #cancer conditional distribution (cancer given pollution and smoker)
    dist = zeros([pollution_node.size(),smoker_node.size(),cancer_node.size()],    dtype=float32)
    dist[0,1,] = [0.05,0.95]
    dist[0,0,] = [0.02,0.98]
    dist[1,1,] = [0.03,0.97]
    dist[1,0,] = [0.001,0.999]
    cancer_distribution = ConditionalDiscreteDistribution(nodes=[pollution_node,  smoker_node, cancer_node], table=dist)
    cancer_node.set_dist(cancer_distribution)

    #xray conditional distribution (xray given cancer)  
    dist = zeros([cancer_node.size(), xray_node.size()], dtype=float32)
    dist[0,] = [0.2,0.8]
    dist[1,] = [0.9,0.1]
    xray_distribution = ConditionalDiscreteDistribution(nodes=[cancer_node, xray_node], table=dist)
    xray_node.set_dist(xray_distribution) 

    #dyspnoea conditional distribution (dyspnoea given cancer)  
    dist = zeros([cancer_node.size(), dyspnoea_node.size()], dtype=float32)
    dist[0,] = [0.2,0.8]
    dist[1,] = [0.9,0.1]
    dyspnoea_distribution = ConditionalDiscreteDistribution(nodes=[cancer_node, dyspnoea_node], table=dist)
    dyspnoea_node.set_dist(dyspnoea_distribution)


    #create bayes net
    bnet = BayesNet(nodes)  
    return bnet

def disease_inference():
""" This is an example of how to perform inference on a network using the Junction Tree Engine.  The exact same method could be used with any implemented inference engine by simply replaceing the line JunctionTreeEngine(water) with the appropriate constructor.
"""

    #define disease network
    disease_net = EX.create_disease_net()

    #define variable indexes
    for node in disease_net.nodes:
        if node.id == 0:
        pollution = node
        if node.id == 1:
            smoker = node
        if node.id == 2:
            cancer = node
        if node.id == 3:
            xray = node
        if node.id == 4:
            dyspnoea = node
    #Create the inference engine object
    engine = JunctionTreeEngine(disease_net)

    test0 = 1
    #Compute the marginal probability of sprinkler given no evidence
    Q = engine.marginal(cancer)[0]
    #Q is a DiscreteDistribution, and so to index into it, we have to use the class' method to create an index
    index = Q.generate_index([False], range(Q.nDims))
    print "The marginal probability of cancer=false:", Q[index]

    #Set cloudy and rain to False and True in the evidence
    engine.evidence[pollution] = False
    engine.evidence[smoker] = True
    #Compute the marginal probability given the evidence pollution=False, cancer=true
    Q = engine.marginal(cancer)[0]
    index = Q.generate_index([False],range(Q.nDims))
    print "The marginal probability of cancer=false | pollution=False, smoker=True:", Q[index]

Run the inference example

And I am getting the following:

Traceback (most recent call last): File "assign4.py", line 133, in main(sys.argv[1:]) File "assign4.py", line 130, in main disease_inference()
File "assign4.py", line 94, in disease_inference disease_net = EX.create_disease_net() AttributeError: 'module' object has no attribute 'create_disease_net'

I am a beginner programmer but am trying to get better. Any insight is greatly appreciated.

1

There are 1 answers

0
Steve Barnes On BEST ANSWER

The line:

import ExampleModels as EX

will make the whole of ExampleModels have the name EX so as the error message suggests unless ExampleModels actually has a top level method create_disease_net you will get this error. Since you are defining create_disease_net in your namespace rather than that of EX you just need to remove EX. from your call.