-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8d2fdfe
commit 00ac45a
Showing
11 changed files
with
361 additions
and
0 deletions.
There are no files selected for viewing
Binary file added
BIN
+1.39 KB
ml_algorithms/src/introduction_to_computation/dice/__pycache__/biased_die.cpython-39.pyc
Binary file not shown.
Binary file added
BIN
+2.77 KB
...gorithms/src/introduction_to_computation/dice/__pycache__/dishonest_casino.cpython-39.pyc
Binary file not shown.
Binary file added
BIN
+1.48 KB
ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_casino.cpython-39.pyc
Binary file not shown.
Binary file added
BIN
+1.3 KB
ml_algorithms/src/introduction_to_computation/dice/__pycache__/fair_die.cpython-39.pyc
Binary file not shown.
Binary file added
BIN
+1.65 KB
ml_algorithms/src/introduction_to_computation/dice/__pycache__/loaded_die.cpython-39.pyc
Binary file not shown.
114 changes: 114 additions & 0 deletions
114
ml_algorithms/src/introduction_to_computation/dice/dishonest_casino.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)) |
46 changes: 46 additions & 0 deletions
46
ml_algorithms/src/introduction_to_computation/dice/fair_casino.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
34 changes: 34 additions & 0 deletions
34
ml_algorithms/src/introduction_to_computation/dice/fair_die.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
49 changes: 49 additions & 0 deletions
49
ml_algorithms/src/introduction_to_computation/dice/loaded_die.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
48 changes: 48 additions & 0 deletions
48
ml_algorithms/src/introduction_to_computation/dice/simulation_results.txt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
||
|
||
|
||
|
||
|
||
----------------------------------------------------------------------------- | ||
|
70 changes: 70 additions & 0 deletions
70
ml_algorithms/src/introduction_to_computation/dice/simulations.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |