Skip to content

Commit 815f123

Browse files
author
Jacob Schreiber
committed
v0.0.2 push
examples, more comments, cleaned up code
1 parent 70e589f commit 815f123

File tree

14 files changed

+1305
-161
lines changed

14 files changed

+1305
-161
lines changed

examples/asia_bayes_net.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Asia Bayes Net
2+
# Contact: Jacob Schreiber
3+
4+
5+
'''
6+
The Asia Bayesian Network. See a description here:
7+
http://www.norsys.com/tutorials/netica/secA/tut_A1.htm
8+
'''
9+
10+
from pomegranate import *
11+
12+
# Create the distributions
13+
asia = DiscreteDistribution({ 'True' : 0.5, 'False' : 0.5 })
14+
tuberculosis = ConditionalDiscreteDistribution({
15+
'True' : DiscreteDistribution({ 'True' : 0.2, 'False' : 0.80 }),
16+
'False' : DiscreteDistribution({ 'True' : 0.01, 'False' : 0.99 })
17+
}, [asia])
18+
19+
smoking = DiscreteDistribution({ 'True' : 0.5, 'False' : 0.5 })
20+
lung = ConditionalDiscreteDistribution({
21+
'True' : DiscreteDistribution({ 'True' : 0.75, 'False' : 0.25 }),
22+
'False' : DiscreteDistribution({ 'True' : 0.02, 'False' : 0.98 })
23+
}, [smoking] )
24+
bronchitis = ConditionalDiscreteDistribution({
25+
'True' : DiscreteDistribution({ 'True' : 0.92, 'False' : 0.08 }),
26+
'False' : DiscreteDistribution({ 'True' : 0.03, 'False' : 0.97})
27+
}, [smoking] )
28+
29+
tuberculosis_or_cancer = ConditionalDiscreteDistribution({
30+
'True' : { 'True' : DiscreteDistribution({ 'True' : 1.0, 'False' : 0.0 }),
31+
'False' : DiscreteDistribution({ 'True' : 1.0, 'False' : 0.0 }),
32+
},
33+
'False' : { 'True' : DiscreteDistribution({ 'True' : 1.0, 'False' : 0.0 }),
34+
'False' : DiscreteDistribution({ 'True' : 0.0, 'False' : 1.0 })
35+
}
36+
}, [tuberculosis, lung] )
37+
38+
xray = ConditionalDiscreteDistribution({
39+
'True' : DiscreteDistribution({ 'True' : .885, 'False' : .115 }),
40+
'False' : DiscreteDistribution({ 'True' : 0.04, 'False' : 0.96 })
41+
}, [tuberculosis_or_cancer] )
42+
43+
dyspnea = ConditionalDiscreteDistribution({
44+
'True' : { 'True' : DiscreteDistribution({ 'True' : 0.96, 'False' : 0.04 }),
45+
'False' : DiscreteDistribution({ 'True' : 0.89, 'False' : 0.11 })
46+
},
47+
'False' : { 'True' : DiscreteDistribution({ 'True' : 0.82, 'False' : 0.18 }),
48+
'False' : DiscreteDistribution({ 'True' : 0.4, 'False' : 0.6 })
49+
}
50+
}, [tuberculosis_or_cancer, bronchitis])
51+
52+
# Make the states. Note the name can be different than the name of the state
53+
# can be different than the name of the distribution
54+
s0 = State( asia, name="asia" )
55+
s1 = State( tuberculosis, name="tuberculosis" )
56+
s2 = State( smoking, name="smoker" )
57+
s3 = State( lung, name="cancer" )
58+
s4 = State( bronchitis, name="bronchitis" )
59+
s5 = State( tuberculosis_or_cancer, name="TvC" )
60+
s6 = State( xray, name="xray" )
61+
s7 = State( dyspnea, name='dyspnea' )
62+
63+
# Create the Bayesian network
64+
network = BayesianNetwork( "asia" )
65+
network.add_states([ s0, s1, s2, s3, s4, s5, s6, s7 ])
66+
network.add_transition( s0, s1 )
67+
network.add_transition( s1, s5 )
68+
network.add_transition( s2, s3 )
69+
network.add_transition( s2, s4 )
70+
network.add_transition( s3, s5 )
71+
network.add_transition( s5, s6 )
72+
network.add_transition( s5, s7 )
73+
network.add_transition( s4, s7 )
74+
network.bake()
75+
76+
print "Has tuberculosis, is not a smoker, 80-20 chance he has bronchitis"
77+
observations = { 'tuberculosis' : 'True', 'smoker' : 'False',
78+
'bronchitis' : DiscreteDistribution({ 'True' : 0.8, 'False' : 0.2 }) }
79+
beliefs = map( str, network.forward_backward( observations ) )
80+
print "\n".join( "{}\t\t{}".format( state.name, belief ) for state, belief in zip( network.states, beliefs ) )

examples/fsm_test.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# FSM test
2+
# Contact: Jacob Schreiber
3+
4+
5+
from pomegranate import *
6+
7+
# Create the states in the same way as you would an HMM
8+
a = State( NormalDistribution( 5, 1 ), "a" )
9+
b = State( NormalDistribution( 23, 1 ), "b" )
10+
c = State( NormalDistribution( 100, 1 ), "c" )
11+
12+
# Create a FiniteStateMachine object
13+
model = FiniteStateMachine( "test" )
14+
15+
# Add the states in the same way
16+
model.add_states( [a, b, c] )
17+
18+
# Add the transitions in the same manner
19+
model.add_transition( model.start, a, 1.0 )
20+
model.add_transition( a, a, 0.33 )
21+
model.add_transition( a, b, 0.33 )
22+
model.add_transition( b, b, 0.5 )
23+
model.add_transition( b, a, 0.5 )
24+
model.add_transition( a, c, 0.33 )
25+
model.add_transition( c, a, 0.5 )
26+
model.add_transition( c, c, 0.5 )
27+
28+
# Bake the model in the same way
29+
model.bake( verbose=True )
30+
31+
# Take a sequence of observations
32+
seq = [ 5, 5, 5, 5, 23, 23, 5, 23, 23, 100, 23, 23, 23, 23, 5, 5, 100, 5, 23 ]
33+
34+
# Print out the model
35+
print "\n".join( state.name for state in model.states )
36+
37+
# Print out where you start in the model
38+
print model.current_state.name
39+
40+
# Print out where the model is for each step
41+
for symbol in seq:
42+
model.step( symbol )
43+
print symbol, model.current_state.name

examples/hmm_example.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python2.7
2+
# example.py: Yet Another Hidden Markov Model library
3+
# Contact: Jacob Schreiber ( [email protected] )
4+
5+
"""
6+
A simple example highlighting how to build a model using states, add
7+
transitions, and then run the algorithms, including showing how training
8+
on a sequence improves the probability of the sequence.
9+
"""
10+
11+
import random
12+
from pomegranate import *
13+
from pomegranate import HiddenMarkovModel as Model
14+
15+
random.seed(0)
16+
model = Model(name="ExampleModel")
17+
distribution = UniformDistribution(0.0, 1.0)
18+
state = State(distribution, name="uniform")
19+
state2 = State(NormalDistribution(0, 2), name="normal")
20+
silent = State(None, name="silent")
21+
model.add_state(state)
22+
model.add_state(state2)
23+
24+
model.add_transition(state, state, 0.4)
25+
model.add_transition(state, state2, 0.4)
26+
model.add_transition(state2, state2, 0.4)
27+
model.add_transition(state2, state, 0.4)
28+
29+
model.add_transition(model.start, state, 0.5)
30+
model.add_transition(model.start, state2, 0.5)
31+
model.add_transition(state, model.end, 0.2)
32+
model.add_transition(state2, model.end, 0.2)
33+
34+
model.bake()
35+
sequence = model.sample()
36+
print sequence
37+
print
38+
print model.forward(sequence)[ len(sequence), model.end_index ]
39+
print model.backward(sequence)[0,model.start_index]
40+
print
41+
trans, ems = model.forward_backward(sequence)
42+
print trans
43+
print ems
44+
print
45+
model.train( [ sequence ] )
46+
47+
print
48+
print model.forward(sequence)[ len(sequence), model.end_index ]
49+
print model.backward(sequence)[0,model.start_index]
50+
print
51+
trans, ems = model.forward_backward(sequence)
52+
print trans
53+
print ems
54+
print

examples/infinite_hmm.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# infinite_hmm_sampling.py
2+
# Contact: Jacob Schreiber
3+
4+
5+
'''
6+
This example shows how to use yahmm to sample from an infinite HMM. The premise
7+
is that you have an HMM which does not have transitions to the end state, and
8+
so can continue on forever. This is done by not adding transitions to the end
9+
state. If you bake a model with no transitions to the end state, you get an
10+
infinite model, with no extra work! This change is passed on to all the
11+
algorithms.
12+
'''
13+
14+
from pomegranate import *
15+
from pomegranate import HiddenMarkovModel as Model
16+
import itertools as it
17+
import numpy as np
18+
19+
# Define the states
20+
s1 = State( NormalDistribution( 5, 2 ), name="S1" )
21+
s2 = State( NormalDistribution( 15, 2 ), name="S2" )
22+
s3 = State( NormalDistribution( 25, 2 ), name="S3 ")
23+
24+
# Define the transitions
25+
model = Model( "infinite" )
26+
model.add_transition( model.start, s1, 0.7 )
27+
model.add_transition( model.start, s2, 0.2 )
28+
model.add_transition( model.start, s3, 0.1 )
29+
model.add_transition( s1, s1, 0.6 )
30+
model.add_transition( s1, s2, 0.1 )
31+
model.add_transition( s1, s3, 0.3 )
32+
model.add_transition( s2, s1, 0.4 )
33+
model.add_transition( s2, s2, 0.4 )
34+
model.add_transition( s2, s3, 0.2 )
35+
model.add_transition( s3, s1, 0.05 )
36+
model.add_transition( s3, s2, 0.15 )
37+
model.add_transition( s3, s3, 0.8 )
38+
model.bake()
39+
40+
sequence = [ 4.8, 5.6, 24.1, 25.8, 14.3, 26.5, 15.9, 5.5, 5.1 ]
41+
42+
43+
print model.is_infinite()
44+
45+
print "Algorithms On Infinite Model"
46+
sequence = [ 4.8, 5.6, 24.1, 25.8, 14.3, 26.5, 15.9, 5.5, 5.1 ]
47+
print "Forward"
48+
print model.forward( sequence )
49+
50+
print "\n".join( state.name for state in model.states )
51+
print "Backward"
52+
print model.backward( sequence )
53+
54+
print "Forward-Backward"
55+
trans, emissions = model.forward_backward( sequence )
56+
print trans
57+
print emissions
58+
59+
print "Viterbi"
60+
prob, states = model.viterbi( sequence )
61+
print "Prob: {}".format( prob )
62+
print "\n".join( state[1].name for state in states )
63+
print
64+
print "MAP"
65+
prob, states = model.maximum_a_posteriori( sequence )
66+
print "Prob: {}".format( prob )
67+
print "\n".join( state[1].name for state in states )
68+
69+
print "Showing that sampling can reproduce the original transition probs."
70+
print "Should produce a matrix close to the following: "
71+
print " [ [ 0.60, 0.10, 0.30 ] "
72+
print " [ 0.40, 0.40, 0.20 ] "
73+
print " [ 0.05, 0.15, 0.80 ] ] "
74+
print
75+
print "Tranition Matrix From 100000 Samples:"
76+
sample, path = model.sample( 100000, path=True )
77+
trans = np.zeros((3,3))
78+
79+
for state, n_state in it.izip( path[1:-2], path[2:-1] ):
80+
state_name = float( state.name[1:] )-1
81+
n_state_name = float( n_state.name[1:] )-1
82+
trans[ state_name, n_state_name ] += 1
83+
84+
trans = (trans.T / trans.sum( axis=1 )).T
85+
print trans

0 commit comments

Comments
 (0)