From 00ac45a5726dfe6395386796f98318c16038a395 Mon Sep 17 00:00:00 2001 From: carmelgafa Date: Wed, 14 Feb 2024 09:38:14 +0100 Subject: [PATCH] added work carried out on dice --- .../__pycache__/biased_die.cpython-39.pyc | Bin 0 -> 1420 bytes .../dishonest_casino.cpython-39.pyc | Bin 0 -> 2834 bytes .../__pycache__/fair_casino.cpython-39.pyc | Bin 0 -> 1512 bytes .../dice/__pycache__/fair_die.cpython-39.pyc | Bin 0 -> 1332 bytes .../__pycache__/loaded_die.cpython-39.pyc | Bin 0 -> 1687 bytes .../dice/dishonest_casino.py | 114 ++++++++++++++++++ .../dice/fair_casino.py | 46 +++++++ .../dice/fair_die.py | 34 ++++++ .../dice/loaded_die.py | 49 ++++++++ .../dice/simulation_results.txt | 48 ++++++++ .../dice/simulations.py | 70 +++++++++++ 11 files changed, 361 insertions(+) create mode 100644 ml_algorithms/src/introduction_to_computation/dice/__pycache__/biased_die.cpython-39.pyc create mode 100644 ml_algorithms/src/introduction_to_computation/dice/__pycache__/dishonest_casino.cpython-39.pyc create mode 100644 ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_casino.cpython-39.pyc create mode 100644 ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_die.cpython-39.pyc create mode 100644 ml_algorithms/src/introduction_to_computation/dice/__pycache__/loaded_die.cpython-39.pyc create mode 100644 ml_algorithms/src/introduction_to_computation/dice/dishonest_casino.py create mode 100644 ml_algorithms/src/introduction_to_computation/dice/fair_casino.py create mode 100644 ml_algorithms/src/introduction_to_computation/dice/fair_die.py create mode 100644 ml_algorithms/src/introduction_to_computation/dice/loaded_die.py create mode 100644 ml_algorithms/src/introduction_to_computation/dice/simulation_results.txt create mode 100644 ml_algorithms/src/introduction_to_computation/dice/simulations.py diff --git a/ml_algorithms/src/introduction_to_computation/dice/__pycache__/biased_die.cpython-39.pyc b/ml_algorithms/src/introduction_to_computation/dice/__pycache__/biased_die.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..544e755f653cb7f6198d6323ebc5db3495ae96f4 GIT binary patch literal 1420 zcmZ{k&5j#I5P-XSddB08y)hd^R!YQy+i=JUafl)kg_V#v_`+>uG#XF0y}dhs>FHtd z%06ulx$poW4mO;401i9@Z_p}wVuEOCs;gYp-PK=JI~|XY7>=KR|24Z1 zjQvT*;qcIShF^1rLNW6fO|ERAA^Z^ee#CNquYRgG4U~uzK+S4s7TlVaiN;7;U3#@`&zq!2W-QU zkGJNhY~xw6_1B){mtu|jMX>X>gB{z5wUFXIvGb>UDy<>zd%EJDv?#>lq@}D1H=tRU z*7=LPO05YgnzC{J)wwdtdAeMKjy+Yy-#(`)18= z;Ea8JvO#8B?4>Q=u^j+=F~JyNy)E{y^mZI$PBBJc3=lo+H2$EE{KN(qgSU}HQTn(l z_zvHg4YpzTj)?1Es$bnhQg<BKy5RpdE8tMbaYp^{70tNxXi_B_>K&ERYo>5R)iMRx2SPU^irv2q_FGn*%BhYPDT8Gddt_v*d+ zy-K#WIt=X}zx~_z4_l1=n+E5bz~BLT`9~1N6wla%ONSHhWbQ;rVR<+6CcgA7FS1|~ z%Fyy2_((>U=UGQ~>>gd&eU~X;1s^jN=)ZcwnrJ5->kkf1@pyL_G+`X)$wbF-(~09rp=KHJ zy*NIeCE0pK=zKP5L^7+2M!fUp&);wS_kQ{2&f7bmG1JE%TJoQtJ^9hzjwz<2;-kIC zg?Y3$E{xtA>8jk@pPigM$%=z?9NQHI3-(l69u~PSt9YE0XvmIDp!e*5mF7;mG{)KArjKZIIv?1kdUGFROczDz+e=etASkV+HoBlxjOwV_>_&L~Yvt!Scgr|}y^?&9x7sk41^1tR7uk<$p6 zf!!sJ(>$%>cpIZK1YtPGko)}P)&*x?+lUUGW*Z?MX%iRwaaEM1F3mM)j>)i1>w)pm zt#5w^bHL_K#g6#gt(>Jj`;{{nwNUOOVP3?Fm}7SCq5G9rBjI=0Z+<-wYL~QdEe>l> zIX`4`@0@;Ehc!F$vBM|r4#)Ru-%9zHqyk9YYb}5jI|`Rk?XCDc0^b4egYQ(`I$Chh z&Vt`$wO9K$*=;uO*4>BfGqGzpJb6as3v{%9-XHdC+8J^fQBHDIOqyVpr~8GO7~l(Q zJbMq#4e;hBk?SCG%M@7_Pi9$_PBU$uBT2WMO|aoD5_+B{0;5YvlueZDk1BiG&0uPZ zQM{iT+y**+dBx@evGKT=<&`$_T4n*ku5TtAo;H1}d%BnGo~r6nZkDxfbVfoXZ`hhyyx6a zga0RcPP684?w!jTXXzut!7^O26+rY{UidYwM97Ojt+VIVx|QzyPw6hCUtMPrq#rVK z8|Ix)0`qN5m=}mp^vxX*VDWUSbJa#(P~_Wmps3rN7zSriH{YSz?-F^D$V)`NN8~~T zLOQs($kb1;Xb}Waa5hn(2yCw-u>O9{wcc!jg2Ah=1c88sy1l}L9yMFCn&X-{6|bEI zRU>{fc$gxGlS<$Dg{}?@HFV7PA!`VBhi>Z><%b-UtzcT@F=f^zXV&Zb14vs;XK>&$ z4sFDSyhRP`Q#f(;pw%RxPc&77liW+etc}0bC zPBq!SLkK?T*SD|%zz_n-djrsMhhGK^QiabHYC|zM5lG|h1HdZt4dPw$o=j>4d1;0u z^$L-DM9yrn92G-DHIPOnMI&^shTAV~-|YK#o}NCFB+cXa;PZF?b#ndlFYh0G`e$l? zy`L_B$Jy|jyfR6uX;xHOI>PgWIO(@vbC>of)VIZ3cGf_`+$@&f=~|4`+{RkuG10nq;i2)&Ze literal 0 HcmV?d00001 diff --git a/ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_casino.cpython-39.pyc b/ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_casino.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da29c47a79471237f6c94dc1038ad95f9cf742c3 GIT binary patch literal 1512 zcmZ`(JCEEp5GE<=vClilNMJaR&H>c;2N;QSh!073jXPljMk{jHvh_NO@?{UYYOhEU z|AQ2}rT;+s{0&wCQr%xjl^M#H+e;8GIQqny+4(pRrL)-YILrZuN$4;w{3QCGNM8omLg`CCIhTo;RKFt+CUaGW$XOQZ&TB{6A4j0fKD4qaNB%zWd zOj5~yrP7o9nkSx|DJ}ze4`p=iC%zoX@ij?;4^|U71*_0enA&iNQLlul+g7!ib3#X0h_S~1+@vS3$&U7P5B1O?Xy7gpJnT%@MIp+rFnLob zI7I?_jsovBhzVNqrbsuKm0Nm82lP;Pj{!!<5;_Kt0T{^Sz+g+Sm|;EJQc8Mu%g58` zqK`pXztMSRV$YGW)Fcr$i_oh5H>s%2fqQBc`n3TFLgzHPpSxR|d&R~i;C2Lm0k9@l zR3bGP0U*at$q!##c}RLst~e0pK-}-?&g=a>P(S|&JOab98>PSX!2S`~2cV}rzxVdE zXP**h`K<~10IzGp*U_CvAIJcD*O$>dA9cHt8yRS}cyyNk{1DQCEqQ}t4I9?ulMmpJ zZ!BF~zAQQwd)CkDqSkh#ButWn{zWd$t9WdEH(oBUF2gWzO`|HQu{!A3RYpHR>@|h4 z-ZIsex3B7pI2_VHN#Cw9_0S@%J-TZs51S}GyzSctNgU4eKi#Cew% zgGOVcS`WHtxH;sK=qD)dy4oRZZS8}=UTAS7A~yGqdE~oOj8&$2B}6>456aXuMQw_F z2{Vhx2E$W-4vsc*Lk%B?;WObwuA0rz)-KtsYTTddFVQ*}rvHCg+32g`ZqKp)EjIX+ M4nLsyB%%TR8=-4hqW}N^ literal 0 HcmV?d00001 diff --git a/ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_die.cpython-39.pyc b/ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_die.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f41f7e8c9c4d6a68085ccf4c67556c5bf4ca4753 GIT binary patch literal 1332 zcmZuwJ#Q0D5ZuC68AfeS$F1zh&@VP6U7uiCyJl3*w=v)ADDTe{WB7WI$RBux26>0-;l`Pz`w{i zMY+AMay547^z>KZwimk~h13-Mq6x%0j7^xY6TO=GSYlCoI&>Xc|FSHY> z&hm&G#Og+6TTHc))lAx|X>{Z0r@w*jA|6?^xy|Za??PBN976Z$;?_3iE1y3)hqYtD zUFSZ6GAE}1904!c89gL#Z=CWamP4=*m0;1F+kOK)p6u?9gf4QwP{u8 zCf@F~$&ws;odHF31D$RDZhB~SW09}dAysn&1fhZnI;10zBYK5aDwqW>?KV9L)n1SI?{0uuBGsh%;<3Dr9?nkB6eOVy+^| zN+~zk)M%$?ng^V!Px>BRFA`hlmCds$JUrB#-|yxggmk|#4?%MrYBe2_{{i8`r+q2U T@R>D8=#YkV$oB4r)TciIR{t@- literal 0 HcmV?d00001 diff --git a/ml_algorithms/src/introduction_to_computation/dice/__pycache__/loaded_die.cpython-39.pyc b/ml_algorithms/src/introduction_to_computation/dice/__pycache__/loaded_die.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d6d609eef0a01357e7b1a6aacbb5805bcecfdf8 GIT binary patch literal 1687 zcmZux&2HpG5bkdOPBIBYHX@O-T#%3$AuUL|;((&vm54w>XfE8WL6*neGwH;CX}32! zBhM)j;=%)fILvV45jgT1eL~`Z<`ph3gRHg|B6JR=!tN( z#l1DXq7-U;ONRai>XA{3_Wp7pcnMei9E>0lY-#`C^>-QH5%RDec&#>+!T%Eaq7` zlWA;sxJ<=3vv^}J#gl4o!Z?NG(vs@NKPxWxCS1FOoT9!rB z@9K=2d?HlT&y%VWJhl`^JF3hwhzh%D8SczB7IATR2fP~lBGjdi=@vbti`_STVM@wy z`(`1SJN~sZMvODl@1G;mn49p}^ zFo~z-<*mfRve9Xo1HbnfS2D?faS5^&HSk+Mq(0Q5);Nzx@V$Bu3!xp7$YCpP)er-!mw1g}TK_ zvWFkCU4J(S1N#)el_#=*-@)p8N`~8=;yln+HSbt@H&1kxl{%9X__d&C{O+zkx-G6g l1ut>{t??>_UD<~Irxz0*cZi;&%xi=Z(vbGq?uQ}u>Az;fm9PK+ literal 0 HcmV?d00001 diff --git a/ml_algorithms/src/introduction_to_computation/dice/dishonest_casino.py b/ml_algorithms/src/introduction_to_computation/dice/dishonest_casino.py new file mode 100644 index 0000000..db21fb8 --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/dishonest_casino.py @@ -0,0 +1,114 @@ +import matplotlib.pyplot as plt +from fair_die import FairDie +from loaded_die import LoadedDie +from numpy import mean +from numpy import arange +import random +import enum + + + +class DiceThrow(enum.Enum): + FAIR = enum.auto() + LOADED = enum.auto() +class DishonestCasino(): + + def __init__(self, p1:float, p2:float) -> None: + self.fair_die = FairDie() + self.biased_die = LoadedDie() + self.p_1 = p1 + self.p_2 = p2 + + + + def play(self, number_of_tosses:int)->float: + + results = [] + next_toss = DiceThrow.FAIR + prob_first_toss = random.uniform(0,1) + if prob_first_toss > 0.5: + next_toss = DiceThrow.LOADED + + fair_toss_counter = 0 + loaded_toss_counter = 0 + + + for i in range(number_of_tosses): + + if next_toss == DiceThrow.FAIR: + fair_toss_counter += 1 + prob_next_toss = random.uniform(0,1) + if prob_next_toss > self.p_1: + next_toss = DiceThrow.LOADED + else: + loaded_toss_counter += 1 + prob_next_toss = random.uniform(0,1) + if prob_next_toss > self.p_2: + next_toss = DiceThrow.FAIR + + # print(fair_toss_counter) + # print(loaded_toss_counter) + + fair_tosses = self.fair_die.roll_multiple(fair_toss_counter) + loaded_tosses = self.biased_die.roll_multiple(loaded_toss_counter) + + mean_all_tosses = (sum(fair_tosses)+sum(loaded_tosses))/(fair_toss_counter+loaded_toss_counter) + + return mean_all_tosses + + + + def play_old(self, number_of_tosses:int)->list: + + results = [] + + next_toss = DiceThrow.FAIR + prob_first_toss = random.uniform(0,1) + if prob_first_toss > 0.5: + next_toss = DiceThrow.LOADED + + for i in range(number_of_tosses): + + if next_toss == DiceThrow.FAIR: + results.append(self.fair_die.roll()) + prob_next_toss = random.uniform(0,1) + if prob_next_toss > self.p_1: + next_toss = DiceThrow.LOADED + else: + results.append(self.biased_die.roll()) + prob_next_toss = random.uniform(0,1) + if prob_next_toss > self.p_2: + next_toss = DiceThrow.FAIR + return results + + def simulate(self, t:int): + '''Simulate Method''' + simulation_mean = self.play(t) + return mean(simulation_mean) + + + def test(self)->None: + + avg_results = [] + number_tosses_per_play = 100 + number_of_plays = 10 + for i in range(0, number_of_plays): + # append the average opf the tosses + play = self.play(number_tosses_per_play) + mean_play = mean(play) + print(mean_play) + avg_results.append(mean_play) + + # possible averages from 1 to 6 in steps of 0.5 + # ie 11 possible outcomes + avg_frequencies = [] + for i in arange(1,6.5, 0.5): + avg_frequencies.append(avg_results.count(i) / number_of_plays) + + print(avg_frequencies) + plt.bar(arange(1,6.5, 0.5).tolist(), avg_frequencies, color='g', edgecolor='blue', width=0.5) + plt.show() + +if __name__=='__main__': + casino = DishonestCasino(0.99, 0.1) + print(casino.play(100000)) \ No newline at end of file diff --git a/ml_algorithms/src/introduction_to_computation/dice/fair_casino.py b/ml_algorithms/src/introduction_to_computation/dice/fair_casino.py new file mode 100644 index 0000000..10891da --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/fair_casino.py @@ -0,0 +1,46 @@ +import matplotlib.pyplot as plt +from fair_die import FairDie +from numpy import mean +from numpy import arange +import numpy as np + +class FairCasino(): + + def __init__(self) -> None: + self.die = FairDie() + + def play(self, number_of_tosses:int=2): + return self.die.roll_multiple(number_of_tosses) + + + def simulate(self, t): + mean_res = mean(self.play(t)) + print(mean_res) + return mean_res + + def test(self)->None: + + avg_results = [] + + number_of_plays = 5000 + for i in range(0, number_of_plays): + # append the average opf the tosses + play = self.play() + mean_play = mean(play) + avg_results.append(mean_play) + + # possible averages from 1 to 6 in steps of 0.5 + # ie 11 possible outcomes + avg_frequencies = [] + for i in arange(1,6.5, 0.5): + avg_frequencies.append(avg_results.count(i) / number_of_plays) + + print(avg_frequencies) + + plt.bar(arange(1,6.5, 0.5), avg_frequencies, color='g', edgecolor='blue', width=0.5) + plt.show() + + +if __name__=='__main__': + casino = FairCasino() + casino.test() diff --git a/ml_algorithms/src/introduction_to_computation/dice/fair_die.py b/ml_algorithms/src/introduction_to_computation/dice/fair_die.py new file mode 100644 index 0000000..0007b3f --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/fair_die.py @@ -0,0 +1,34 @@ +import random +import numpy as np +import matplotlib.pyplot as plt + +class FairDice: + + def __init__(self) -> None: + ... + + def roll(self)->int: + return random.randint(1,6) + + def roll_multiple(self, number_of_tosses): + x = np.random.random((number_of_tosses, 1)).squeeze() + return np.ceil(x*6) + + def test_die(self)->None: + outcomes = [] + + number_of_trials = 5000 + for i in range(number_of_trials): + outcomes.append(self.roll()) + + results = [] + for i in np.arange(1,7): + results.append(outcomes.count(i) / number_of_trials) + + plt.bar(np.arange(1,7), results, color='g', edgecolor='blue', width=1) + plt.show() + + +if __name__ == '__main__': + die = FairDice() + die.roll_multiple(10) diff --git a/ml_algorithms/src/introduction_to_computation/dice/loaded_die.py b/ml_algorithms/src/introduction_to_computation/dice/loaded_die.py new file mode 100644 index 0000000..1ff2eae --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/loaded_die.py @@ -0,0 +1,49 @@ +'''Loaded dice implementation''' + +import random +import numpy as np +import matplotlib.pyplot as plt + +class LoadedDice: + '''A loaded dice. probabilities for each number defined in __init_''' + + def __init__(self) -> None: + '''Initializes new dice''' + self.probabilities = np.array([0.5, 0.1, 0.1, 0.1, 0.1, 0.1]) + self.cumul_array = np.cumsum(self.probabilities) + + def roll(self)->int: + '''rolls dice''' + precision = 3 + random_number = random.randint(0, 10 ** precision) / float(10 ** precision) + mapped_cumul = self.cumul_array - random_number + rolled_number = np.where(mapped_cumul > 0, mapped_cumul, np.inf).argmin() + return rolled_number + 1 + + def roll_multiple(self, number_of_tosses): + '''rolls dice multiple times''' + x = np.random.random((number_of_tosses, 1)).squeeze() + x = np.ceil(x*10)-4 + x[x<=0] = 1 + return x + + + def test_die(self)->None: + '''executes a test for the dice''' + outcomes = [] + + number_of_trials = 5000 + for i in range(number_of_trials): + outcomes.append(self.roll()) + + results = [] + for i in np.arange(1,7): + results.append(outcomes.count(i) / number_of_trials) + + plt.bar(np.arange(1,7), results, color='g', edgecolor='blue', width=1) + plt.show() + +if __name__ == '__main__': + die = LoadedDice() + print(die.roll_multiple(100000)) + die.test_die() diff --git a/ml_algorithms/src/introduction_to_computation/dice/simulation_results.txt b/ml_algorithms/src/introduction_to_computation/dice/simulation_results.txt new file mode 100644 index 0000000..c92ce05 --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/simulation_results.txt @@ -0,0 +1,48 @@ +Mean for dishonest casino with p1:0.99 and p2:0.05 is 3.489619392000011 +Mean for dishonest casino with p1:0.95 and p2:0.1 is 3.4474341769999897 +Mean for dishonest casino with p1:0.9 and p2:0.2 is 3.388901595000009 + +----------------------------------------------------------------------------- + +Task 3 +------ + +Dishonest simulation with p1 = 0.9 and p2 = 0.2 +mean: 3.388901595, variance:3.096003910988601e-05, standard deviation:0.005564174611735869 + +Fair Simulation +mean: 3.4999125920000007, variance:2.8043537135249523e-05, standard deviation:0.005295614896803725 + +Note for next Calculation +------------------------- + +To use the estimated variance to find the sample size required to obtain a RMSE error of 0.001, +we use the following formula: + +n = ( (z * sigma / e)^2 ) + +Where: + +n is the sample size +z is the standard normal deviate (e.g. for a 95% confidence level, z = 1.96) +sigma is the estimated population standard deviation +e is the desired margin of error (e.g. e = 0.001) + +This formula states that the sample size required to achieve a certain level of +precision (e) is proportional to the square of the ratio of the standard deviation +to the margin of error. + +It's important to note that this formula assumes that your estimator has a normal +distribution and that the true variance is known or has been estimated from a sample. + +Also, it's important to know that this is only a rough estimation, +and the sample size required for a specific problem may be influenced +by other factors like the distribution of the data, the model assumptions, +the desired confidence level, etc. + + + + + +----------------------------------------------------------------------------- + diff --git a/ml_algorithms/src/introduction_to_computation/dice/simulations.py b/ml_algorithms/src/introduction_to_computation/dice/simulations.py new file mode 100644 index 0000000..cea2aa3 --- /dev/null +++ b/ml_algorithms/src/introduction_to_computation/dice/simulations.py @@ -0,0 +1,70 @@ +from dishonest_casino import DishonestCasino +from fair_casino import FairCasino +import csv +import numpy as np + +def fair_casino_simulation(): + casino = FairCasino() + + mean_results = [] + + for _ in range(10000): + mean_results.append(casino.simulate(100000)) + + with open('fair_results.csv', 'w') as f: + write = csv.writer(f) + write.writerow(mean_results) + + mean = sum(mean_results)/len(mean_results) + print('Mean for fair casino: ', mean) + + +def dishonest_casino_simulation_run(p1:float, p2:float): + + mean_results = [] + + casino = DishonestCasino(p1, p2) + + for _ in range(10000): + mean_results.append(casino.simulate(100000)) + + with open(f'dishonest_results-{p1}-{p2}.csv', 'w', encoding='UTF-8') as f: + write = csv.writer(f) + write.writerow(mean_results) + + simulations_mean = sum(mean_results)/len(mean_results) + print(f'Mean for dishonest casino with p1:{p1} and p2:{p2} is {simulations_mean}') + + +def dishonest_casino_simulation(): + + dishonest_casino_simulation_run(0.99, 0.05) + dishonest_casino_simulation_run(0.95, 0.1) + dishonest_casino_simulation_run(0.9, 0.2) + + +def calculate_variance(simulation_data:np.array):#type:ignore + simulation_mean = np.mean(simulation_data) + + variance = np.sum(np.square(simulation_data - simulation_mean))/(np.size(simulation_data)-1) + standard_deviation = np.sqrt(variance) + + print(f'mean: {simulation_mean}, variance:{variance}, standard deviation:{standard_deviation}') + + +def dishonest_trial_variance_calculation(): + print('Dishonest simulation with p1 = 0.9 and p2 = 0.2') + simulation_data = np.genfromtxt('dishonest_results-0.9-0.2.csv', delimiter=',') + calculate_variance(simulation_data) + + +def fair_trial_variance_calculation(): + print('Fair Simulation') + simulation_data = np.genfromtxt('fair_results.csv', delimiter=',') + calculate_variance(simulation_data) + +if __name__ == '__main__': + # fair_casino_simulation() + # dishonest_casino_simulation() + dishonest_trial_variance_calculation() + fair_trial_variance_calculation()