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)
| door | decision | out |
---|
4863 | 0 | stay | 0.0 |
---|
5656 | 1 | stay | 1.0 |
---|
1356 | 0 | switch | 1.0 |
---|
4509 | 0 | stay | 0.0 |
---|
1125 | 0 | stay | 0.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
| door | decision | out |
---|
0 | 0 | stay | 0.337 |
---|
1 | 0 | switch | 0.662 |
---|
2 | 1 | stay | 0.361 |
---|
3 | 1 | switch | 0.648 |
---|
4 | 2 | stay | 0.328 |
---|
5 | 2 | switch | 0.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>

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

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>
