STAT1013: Monty Hall Problem

The Monty Hall problem is a brain-teaser, in the form of a probability puzzle, loosely based on the American television game show Let’s Make a Deal and named after its original host, Monty Hall.

  • There are 3 doors, behind which are two goats and a car.
  • You pick a door (call it door A). You’re hoping for the car of course.
  • Monty Hall, the game show host, examines the other doors (B & C) and opens one with a goat. (If both doors have goats, he picks randomly.)
import numpy as np
import pandas as pd
import random

Define a Monty Hall game as a Python function

  • input: your initial choice [0, 1, 2]; and your decision [‘stay’, ‘switch’]
  • outcome: win or lose
def MHGame(door, d):
    print('You select door: %d' %door)
    ## initialize the setting
    out = np.zeros(3)
    ## generate a door with a car
    door0 = random.randint(0, 2)
    out[door0] = 1.
    ## Monty opens a door with a goat
    res_door = set([0,1,2]) - set([door0, door])    
    open_door = random.choice(list(res_door))
    print('Monty open the door: %d' %open_door)
    if d == 'stay':
        final_door = door
        print('You decide to stay...')
        final_out = out[door]
    elif d == 'switch':
        print('You decide to switch...')
        final_door = list(set([0,1,2]) - set([door, open_door]))[0]
        final_out = out[final_door]
    else:
        print('please input a correct decision: stay or switch')
    print('The true door is: %d; your final choice is: %d' %(door0, final_door))
    if final_out == 1:
        print('You win!')
    else:
        print('Sorry, You lose!')
    return final_out
## test your function
MHGame(door=1, d='stay')
You select door: 1
Monty open the door: 2
You decide to stay...
The true door is: 1; your final choice is: 1
You win!





1.0
## test your function
MHGame(door=2, d='switch')
You select door: 2
Monty open the door: 1
You decide to switch...
The true door is: 0; your final choice is: 0
You win!





1.0

Statistical simulation

  • Run MHGame() 1000 times with different decisions, to see which one is better
res = {'door': [], 'decision': [], 'out': []}
n_trial = 1000
for i in range(n_trial):
    for d in ['switch', 'stay']:
        for door in range(3):
            out_tmp = MHGame(door=2, d=d)
            res['door'].append(door)
            res['decision'].append(d)
            res['out'].append(out_tmp)            
res = pd.DataFrame(res)
res.sample(5)
doordecisionout
48630stay0.0
56561stay1.0
13560switch1.0
45090stay0.0
11250stay0.0

Analyze the result:

  • Compute the conditional probability
  • Visualize the results
for d in ['stay', 'switch']:
    freq_tmp = res[res['decision'] == d]['out'].mean()
    print('The freq of %s to win the game is: %.3f' %(d, freq_tmp))
The freq of stay to win the game is: 0.342
The freq of switch to win the game is: 0.656
sum_res = res.groupby(['door', 'decision']).mean().reset_index()
sum_res
doordecisionout
00stay0.337
10switch0.662
21stay0.361
31switch0.648
42stay0.328
52switch0.657

Histgram: decision matters?

import seaborn as sns
sns.set_theme(style="white", palette='pastel')
sns.displot(res, x="out", col="decision", hue='decision', stat="probability")
<seaborn.axisgrid.FacetGrid at 0x7f543ed42a10>

png

Histgram: initial door matters?

sns.displot(res, x="out", col="door", hue='door', stat="probability")
<seaborn.axisgrid.FacetGrid at 0x7f5492d630a0>

png

sns.catplot(data=sum_res, x="door", y="out", hue="decision", kind='bar')
# sns.catplot(data=df, x="age", y="class", kind="box")
<seaborn.axisgrid.FacetGrid at 0x7f540db6bfa0>

png