<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Naive Bayes Hidden Markov Coin Toss
author
Step1:  Let's start by creating our hmm's. Since this is a simple example, we will only have 2 states, rigged and unrigged, with discrete distributions.
Step2:  Now let's create our non-cheater and dumb cheater since their hmm's consist of a single state.
Step3:  We can now add our starting states to our models.
Step4:  We can also add the transitions to our non-cheater and dumb cheater.
Step5:  Now we bake our models to finalize the structure.
Step6:  Now we can create our smart cheater.
Step7:  The structure of our smart cheater hmm should look like the following.
Let's add in our starting transitions. Smart cheaters start out half the time with an unrigged coin, half the time without.
Step8:  Then we can add our transition matrix.
Step9:  Finally we can bake the model to finalize its structure.
Step10:  We can view the structures of all our hmm's in the images below.
Step11:  Now we can finally create our Naive Bayes classifier. We'll let 0 stand for a non-cheater, 1 stand for a smart cheater, and 2 stand for a dumb cheater.
Step12:  Now let's create a sequence of coin tosses to test our classifier on.
Step13:  We can now check the log probability of each string of data occurring under each model.
Step14:  Finally we can classify whether a non-cheater (0), smart cheater (1), or dumb cheater (2) created the string of data.
Step15:  We can also train our hmm's through Naive Bayes. Let's used the following data, all marked as known games for smart cheaters.
Step16:  Now let's fit our NaiveBayes classifier to our data.
<ASSISTANT_TASK:>
Python Code:
from pomegranate import *
import numpy as np
%pylab inline
Explanation: Naive Bayes Hidden Markov Coin Toss
author: Nicholas Farn [<a href="sendto:nicholasfarn@gmail.com">nicholasfarn@gmail.com</a>]
In this example we will be using a simple Hidden Markov Model to demonstrate how it can be used in a Naive Bayes classifier. In this particular example we have a couple friends who enjoy playing a game of chance. Someone tosses a coin and whenever it lands on heads, the tosser gains \$1, otherwise he pays \$1. However some of our friends are prone to using rigged coins in order to come out ahead in the long run.
Players fall into 3 categories, non-cheaters, smart cheaters, and dumb cheaters. Non-cheaters, as the name implies, do not use rigged coins. Smart cheaters make sure to switch between rigged and unrigged coins in order to keep the deception going. Dumb cheaters only use rigged coins.
End of explanation
rigged = State( DiscreteDistribution({'H': 0.8, 'T': 0.2}), name="rigged" )
unrigged = State( DiscreteDistribution({'H': 0.5, 'T': 0.5}), name="unrigged" )
Explanation: Let's start by creating our hmm's. Since this is a simple example, we will only have 2 states, rigged and unrigged, with discrete distributions.
End of explanation
non_cheater = HiddenMarkovModel( name="non-cheater" )
non_cheater.add_state( unrigged )
dumb_cheater = HiddenMarkovModel( name="dumb-cheater" )
dumb_cheater.add_state( rigged )
Explanation: Now let's create our non-cheater and dumb cheater since their hmm's consist of a single state.
End of explanation
non_cheater.start = unrigged
dumb_cheater.start = rigged
Explanation: We can now add our starting states to our models.
End of explanation
non_cheater.add_transition( unrigged, unrigged, 1 )
dumb_cheater.add_transition( rigged, rigged, 1 )
Explanation: We can also add the transitions to our non-cheater and dumb cheater.
End of explanation
non_cheater.bake()
dumb_cheater.bake()
Explanation: Now we bake our models to finalize the structure.
End of explanation
smart_cheater = HiddenMarkovModel( name="smart-cheater" )
Explanation: Now we can create our smart cheater.
End of explanation
smart_cheater.add_transition( smart_cheater.start, unrigged, 0.5 )
smart_cheater.add_transition( smart_cheater.start, rigged, 0.5 )
Explanation: The structure of our smart cheater hmm should look like the following.
Let's add in our starting transitions. Smart cheaters start out half the time with an unrigged coin, half the time without.
End of explanation
smart_cheater.add_transition( rigged, rigged, 0.5 )
smart_cheater.add_transition( rigged, unrigged, 0.5 )
smart_cheater.add_transition( unrigged, rigged, 0.5 )
smart_cheater.add_transition( unrigged, unrigged, 0.5 )
Explanation: Then we can add our transition matrix.
End of explanation
smart_cheater.bake()
Explanation: Finally we can bake the model to finalize its structure.
End of explanation
plt.title("smart cheater hmm")
smart_cheater.plot()
plt.title("dumb cheater hmm")
dumb_cheater.plot()
plt.title("non-cheater hmm")
non_cheater.plot()
Explanation: We can view the structures of all our hmm's in the images below.
End of explanation
players = NaiveBayes([ non_cheater, smart_cheater, dumb_cheater ])
Explanation: Now we can finally create our Naive Bayes classifier. We'll let 0 stand for a non-cheater, 1 stand for a smart cheater, and 2 stand for a dumb cheater.
End of explanation
data = np.array([list( 'HHHHHTHTHTTTTHHHTHHTTHHHHHTH' ),
                 list( 'HHHHHHHTHHHHTTHHHHHHHTTHHHHH' ),
                 list( 'THTHTHTHTHTHTTHHTHHHHTTHHHTT' )])
Explanation: Now let's create a sequence of coin tosses to test our classifier on.
End of explanation
probs = players.predict_proba( data )
for i in range(len(probs)):
    print("For sequence {}, {:.3}% non-cheater, {:.3}% smart cheater, {:.3}% dumb cheater.".format( i+1, 100*probs[i][0], 100*probs[i][1], 100*probs[i][2]))
Explanation: We can now check the log probability of each string of data occurring under each model.
End of explanation
output = players.predict( data )
for i in range(len(output)):
    print("Sequence {} is a {}".format( i+1, "non-cheater" if output[i] == 0 else "smart cheater" if output[i] == 1 else "dumb cheater"))
Explanation: Finally we can classify whether a non-cheater (0), smart cheater (1), or dumb cheater (2) created the string of data.
End of explanation
X = np.array([list( 'HHHHHTHTHTTTTH' ),
              list( 'HHTHHTTHHHHHTH' )])
y = np.array([ 1, 1 ])
Explanation: We can also train our hmm's through Naive Bayes. Let's used the following data, all marked as known games for smart cheaters.
End of explanation
players.fit( X, y )
Explanation: Now let's fit our NaiveBayes classifier to our data.
End of explanation
<END_TASK>