@@ -524,11 +524,76 @@ def markov_blanket_sample(X, e, bn):
524
524
525
525
# _________________________________________________________________________
526
526
527
+ """
528
+ umbrella_evidence = [T, T, F, T, T]
529
+ umbrella_prior = [0.5, 0.5]
530
+ umbrella_transition = [[0.7, 0.3], [0.3, 0.7]]
531
+ umbrella_sensor = [[0.9, 0.2], [0.1, 0.8]]
532
+ umbrellaHMM = HiddenMarkovModel(umbrella_transition, umbrella_sensor)
533
+
534
+ print(forward_backward(umbrellaHMM, umbrella_evidence, umbrella_prior))
535
+ """
536
+
537
+ class HiddenMarkovModel :
538
+
539
+ """ A Hidden markov model which takes Transition model and Sensor model as inputs"""
540
+
541
+ def __init__ (self , transition_model , sensor_model ):
542
+ self .transition_model = transition_model
543
+ self .sensor_model = sensor_model
544
+
545
+ def transition_model (self ):
546
+ return self .transition_model
547
+
548
+ def sensor_dist (self , ev ):
549
+ if ev is True :
550
+ return self .sensor_model [0 ]
551
+ else :
552
+ return self .sensor_model [1 ]
553
+
554
+
555
+ def forward (HMM , fv , ev ):
556
+ prediction = vector_add (scalar_vector_product (fv [0 ], HMM .transition_model [0 ]),
557
+ scalar_vector_product (fv [1 ], HMM .transition_model [1 ]))
558
+ sensor_dist = HMM .sensor_dist (ev )
527
559
528
- def forward_backward (ev , prior ):
560
+ return (normalize (dotproduct (sensor_dist , prediction )))
561
+
562
+ def backward (HMM , b , ev ):
563
+ sensor_dist = HMM .sensor_dist (ev )
564
+ prediction = dotproduct (sensor_dist , b )
565
+
566
+ return (normalize (vector_add (scalar_vector_product (prediction [0 ], HMM .transition_model [0 ]),
567
+ scalar_vector_product (prediction [1 ], HMM .transition_model [1 ]))))
568
+
569
+
570
+ def forward_backward (HMM , ev , prior ):
529
571
"""[Fig. 15.4]"""
530
- unimplemented ()
572
+ t = len (ev )
573
+ ev .insert (0 , None ) # to make the code look similar to pseudo code
574
+
575
+ fv = [[0.0 , 0.0 ] for i in range (len (ev ))]
576
+ b = [1.0 , 1.0 ]
577
+ bv = [b ] # we don't need bv; but we will have a list of all backward messages here
578
+ sv = [[0 , 0 ] for i in range (len (ev ))]
531
579
580
+ fv [0 ] = prior
581
+
582
+ for i in range (1 , t + 1 ):
583
+ fv [i ] = forward (HMM , fv [i - 1 ], ev [i ])
584
+ for i in range (t , - 1 , - 1 ):
585
+ sv [i - 1 ] = normalize (dotproduct (fv [i ], b ))
586
+ b = backward (HMM , b , ev [i ])
587
+ bv .append (b )
588
+
589
+ sv = sv [::- 1 ]
590
+ for i in range (len (sv )):
591
+ for j in range (len (sv [i ])):
592
+ sv [i ][j ] = float ("{0:.4f}" .format (sv [i ][j ]))
593
+
594
+ return (sv )
595
+
596
+ # _________________________________________________________________________
532
597
533
598
def fixed_lag_smoothing (e_t , hmm , d ):
534
599
"""[Fig. 15.6]"""
0 commit comments