In [ ]:
################### FLIPPING UTILS ###################
import numpy as np

_q = [0.1, 0.2, 0.4, 0.1, 0.19, 0.01]

def roll(q):
    #assumes \sum_j q_j = 1
    #returns j w.p q_j
    return 1 + np.random.choice(6, p=q)

def sequence(n, q):
    #returns a sequence of n dice rolls
    #rolls j w.p q_j
    return np.array([roll(q) for _ in range(n)])
In [46]:
################### MLE ###################
from functools import partial as curry

def mle_uniform(X):
    #returns MLE on X with uniform prior
    counts = np.zeros(7)
    for j in range(len(X)):
        counts[X[j]] = counts[X[j]] + 1
    return np.array(counts[1:])/len(X)

print(mle_uniform(sequence(100, _q)))
[0.1  0.28 0.44 0.06 0.12 0.  ]
In [47]:
################### ERROR ###################
def ell_1_loss(q, q_hat):
    #returns \sum |q_j -q_hat_j|
    diff = np.array(q)-np.array(q_hat)
    return np.absolute(diff).sum()



def check_error(n, q, trials):
    #sample a sequence with bias q
    #use mle_estimator to estimate q
    #returns the average ell_1_loss incurred in all trials
    loss = 0.0
    for _ in range(int(trials)):
        X = sequence(int(n), q)
        q_hat = mle_uniform(X)
        loss = loss + ell_1_loss(q, q_hat)
    return loss/trials
    
In [48]:
################### PLOT ###################
import matplotlib.pyplot as plt

def plot(x, y):
    plt.xlabel('Number of Coin Tosses')
    plt.ylabel('Error')
    plt.plot(x, y)
    plt.show()  
In [49]:
n_list = np.linspace(1000, 4000, 10)
loss_list = [check_error(n, _q, 100) for n in n_list]
plot(n_list, loss_list)