Created
May 26, 2022 12:34
-
-
Save caiofcm/3b87d09969f71c34115a5db1bca6a0ce to your computer and use it in GitHub Desktop.
Monty Hall problem solved with numpy simulation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Evaluating Monty Hall problem with numpy" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"A vector will represent a sample of the game with the following definition:\n", | |
"\n", | |
"- 0 if goat\n", | |
"- 1 if car\n", | |
"\n", | |
"Lets also consider that the player always chose the door A.\n", | |
"\n", | |
"In the next sample door A and B has goat and door C has car:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"array([0, 0, 1])" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"answer = np.array([0, 0, 1])\n", | |
"answer" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Now, lets define $n$ samples of the game using the numpy permutation function:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"array([[1, 0, 0],\n", | |
" [1, 0, 0],\n", | |
" [0, 1, 0],\n", | |
" ...,\n", | |
" [0, 1, 0],\n", | |
" [0, 1, 0],\n", | |
" [0, 1, 0]])" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"n = 1000\n", | |
"MH = np.array([\n", | |
" np.random.permutation(answer)\n", | |
" for i in range(n)\n", | |
"])\n", | |
"MH" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets define the indexes names, alternatively one could create a pandas DataFrame or numpy record, but let keep it simple" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"iA, iB, iC = range(3)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"First, lets calculate the probability of winning keeping with the door A:\n", | |
"\n", | |
"Probability of winning keeping with A = (number of times in A) / (total number of games)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Num times in A 325\n", | |
"Probability of winning keeping with A: 0.325\n" | |
] | |
} | |
], | |
"source": [ | |
"num_times_in_A = np.sum(MH[:,iA] == 1)\n", | |
"P_win_keep_A = num_times_in_A / n \n", | |
"print(f'Num times in A {num_times_in_A}')\n", | |
"print(f'Probability of winning keeping with A: {P_win_keep_A}')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Now, lets compute the probability of winning changing to other door.\n", | |
"\n", | |
"One should realize that the probability of the car being in B or C is: 2/3.\n", | |
"\n", | |
"The player will win after changing in two scenarios:\n", | |
"\n", | |
"1. Monty Hall opens B and the car is in C\n", | |
"2. Monty Hall opens C and the car is in B\n", | |
"\n", | |
"Therefore, the probability of winning changing doors is:\n", | |
"\n", | |
"Probability of winning changing doors = [(num of times in B when not in C) + (num of times in C when not in B)] / (total number of games)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets compute the first case: \"1. Monty Hall opens B and the car is in C\"" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Num times not in B 664\n", | |
"Num times in C not in B 339\n" | |
] | |
} | |
], | |
"source": [ | |
"I_not_in_B = (MH[:,iB] == 0)\n", | |
"num_times_not_in_B = np.sum(I_not_in_B)\n", | |
"print(f'Num times not in B {num_times_not_in_B}')\n", | |
"games_with_goat_in_B = MH[I_not_in_B, :]\n", | |
"\n", | |
"num_times_in_C_not_in_B = np.sum(games_with_goat_in_B[:, iC] == 1)\n", | |
"print(f'Num times in C not in B {num_times_in_C_not_in_B}')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Similarly, lets compute the second case: \"2. Monty Hall opens C and the car is in B\"" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Num times not in C 661\n", | |
"Num times in B not in C 336\n" | |
] | |
} | |
], | |
"source": [ | |
"I_not_in_C = (MH[:,iC] == 0)\n", | |
"num_times_not_in_C = np.sum(I_not_in_C)\n", | |
"print(f'Num times not in C {num_times_not_in_C}')\n", | |
"games_with_goat_in_C = MH[I_not_in_C, :]\n", | |
"\n", | |
"num_times_in_B_not_in_C = np.sum(games_with_goat_in_C[:, iB] == 1)\n", | |
"print(f'Num times in B not in C {num_times_in_B_not_in_C}')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Finally, lets compute the probability of winning after changing doors:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Probability of winning changing: 0.675\n" | |
] | |
} | |
], | |
"source": [ | |
"P_win_changing = (num_times_in_C_not_in_B + num_times_in_B_not_in_C) / n\n", | |
"print(f'Probability of winning changing: {P_win_changing}')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"interpreter": { | |
"hash": "a63e9d019f050d63fd3110e0caf3e4da1ca9a2f49303a7129aeb5a0bb00a8161" | |
}, | |
"kernelspec": { | |
"display_name": "Python 3.9.13 64-bit (windows store)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.9.13" | |
}, | |
"orig_nbformat": 4 | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment