├── 1_monty_hall ├── 1_monty_hall_game.py ├── 2_monty_hall_monte_carlo_simulation.py ├── 3_monty_hall_bayes_1.py ├── 4_monty_hall_bayes_2.py ├── 5_monty_hall_bayes_3.py └── 6_monty_hall_bayes_4.py ├── 2_probability_basics ├── 01_basic_percentage.py ├── 02_coin_flip_simulation.py ├── 03_odds_ratio.py ├── 04_odds_to_probability.py ├── 05_joint_probability.py ├── 06_joint_probability_permutations.py ├── 07_joint_probability_multiple.py ├── 08_logarithmic_addition.py ├── 09_mutually_exclusive_union.py ├── 10_non_mutually_exclusive_union_bad.py ├── 11_non_mutually_exclusive_union_permutations.py └── 12_non_mutually_exclusive_union.py ├── 3_bayes_theorem ├── 01_likelihood_homicidal.py ├── 02_bayes_theorem.py ├── 03_population_example.py ├── 04_bayes_theorem_population.py ├── 05_bayes_theorem_population_expanded.py └── 06_bayes_theorem_population_remove_n.py ├── 4_binomial_beta_distribution ├── 01_factorial.py ├── 02_binomial_coefficient.py ├── 03_binomial_distribution.py ├── 04_binomial_distribution_range.py ├── 05_approximate_integral.py └── 06_beta_distribution.py ├── 5_normal_distribution ├── 01_golden_retriever_weights.py ├── 02_normal_pdf.py ├── 03_normal_approximate_integral.py ├── 04_normal_cdf.py └── 05_normal_inverse_cdf.py ├── Probability From Scratch.pdf └── Probability From Scratch.pptx /1_monty_hall/1_monty_hall_game.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | number_doors = 3 4 | door_with_prize = random.randint(1,3) 5 | 6 | chosen_door = int(input("There are 3 doors, one with a prize. Choose a door 1, 2, 3:\n")) 7 | opened_door = random.choice([i for i in range(1, 4) if i != chosen_door and i != door_with_prize]) 8 | 9 | switch = input("You chose door {0}, but door {1} was opened. Do you want to switch? y/n\n".format(chosen_door, opened_door)) 10 | 11 | if switch == "y": 12 | opened_door = random.choice([i for i in range(1, 4) if i != chosen_door and i != door_with_prize]) 13 | 14 | if chosen_door == door_with_prize: 15 | print("You win a prize!") 16 | else: 17 | print("Sorry, no prize") 18 | -------------------------------------------------------------------------------- /1_monty_hall/2_monty_hall_monte_carlo_simulation.py: -------------------------------------------------------------------------------- 1 | from random import randint, choice 2 | 3 | 4 | def random_door(): 5 | return randint(1, 3) 6 | 7 | 8 | trial_count = 10000 9 | 10 | stay_wins = 0 11 | switch_wins = 0 12 | 13 | for i in range(0, trial_count): 14 | prize_door = random_door() 15 | selected_door = random_door() 16 | opened_door = choice([d for d in range(1, 4) if d != selected_door and d != prize_door]) 17 | switch_door = choice([d for d in range(1, 4) if d != selected_door and d != opened_door]) 18 | 19 | if selected_door == prize_door: 20 | stay_wins += 1 21 | 22 | if switch_door == prize_door: 23 | switch_wins += 1 24 | 25 | print("STAY WINS: {}, SWITCH WINS: {}".format(stay_wins, switch_wins)) 26 | 27 | print("STAY WIN RATE: {}, SWITCH WIN RATE: {}".format(float(stay_wins)/float(trial_count), float(switch_wins)/float(trial_count))) 28 | -------------------------------------------------------------------------------- /1_monty_hall/3_monty_hall_bayes_1.py: -------------------------------------------------------------------------------- 1 | p_prize2 = 1.0 / 3.0 # probability of prize in door 2 2 | p_left2_prize2 = 1.0 # probability of door 2 left given prize in door 2 3 | p_left2 = .5 # probability of door 2 being left 4 | 5 | # probability of prize in door 2 given door 2 is left 6 | p_prize2_left2 = p_left2_prize2 * p_prize2 / p_left2 7 | 8 | print(p_prize2_left2) 9 | -------------------------------------------------------------------------------- /1_monty_hall/4_monty_hall_bayes_2.py: -------------------------------------------------------------------------------- 1 | p_prize1 = 1.0 / 3.0 # probability of prize in door 1 2 | p_left2_prize1 = .5 # probability of door 2 left given prize in door 1 3 | p_left2 = .5 # probability of door 2 being left 4 | 5 | # probability of prize in door 1 given door 2 is left 6 | p_prize1_left2 = p_left2_prize1 * p_prize1 / p_left2 7 | 8 | print(p_prize1_left2) 9 | -------------------------------------------------------------------------------- /1_monty_hall/5_monty_hall_bayes_3.py: -------------------------------------------------------------------------------- 1 | p_prize19 = 1.0 / 1000.0 # probability of prize in door 19 2 | p_left77_prize19 = 1.0 / 999.0 # probability of door 77 left given prize in door 19 3 | p_left77 = 1.0 / 999.0 # probability of door 77 being left 4 | 5 | # probability of prize in door 19 given door 77 is left 6 | p_prize19_left77 = p_left77_prize19 * p_prize19 / p_left77 7 | 8 | print(p_prize19_left77) 9 | -------------------------------------------------------------------------------- /1_monty_hall/6_monty_hall_bayes_4.py: -------------------------------------------------------------------------------- 1 | 2 | p_prize77 = 1.0 / 1000.0 # probability of prize in door 77 3 | p_left77_prize77 = 1.0 # probability of door 77 left given prize in door 77 4 | p_left77 = 1.0 / 999.0 # probability of door 77 being left 5 | 6 | # probability of prize in door 1 given door 2 is left 7 | p_prize77_left77 = p_left77_prize77 * p_prize77 / p_left77 8 | 9 | print(p_prize77_left77) 10 | -------------------------------------------------------------------------------- /2_probability_basics/01_basic_percentage.py: -------------------------------------------------------------------------------- 1 | defective_count = 60.0 2 | total_count = 100.0 3 | 4 | defective_probability = defective_count / total_count 5 | print(defective_probability) 6 | -------------------------------------------------------------------------------- /2_probability_basics/02_coin_flip_simulation.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | heads = 0 4 | 5 | for i in range(0,100): 6 | if random.uniform(0,1) <= .6: 7 | heads += 1 8 | 9 | print("# HEADS: {}/100".format(heads)) 10 | -------------------------------------------------------------------------------- /2_probability_basics/03_odds_ratio.py: -------------------------------------------------------------------------------- 1 | defective_product_count = 6.0 2 | non_defective_product_count = 4.0 3 | defective_odds = defective_product_count / non_defective_product_count 4 | print(defective_odds) 5 | -------------------------------------------------------------------------------- /2_probability_basics/04_odds_to_probability.py: -------------------------------------------------------------------------------- 1 | def odds_to_prob(odds): 2 | return odds / (1.0 + odds) 3 | 4 | defective_odds = 1.5 5 | defective_probability = odds_to_prob(defective_odds) 6 | print(defective_probability) 7 | -------------------------------------------------------------------------------- /2_probability_basics/05_joint_probability.py: -------------------------------------------------------------------------------- 1 | prob_heads = 1.0 / 2.0 # probabilty of heads 2 | prob_six = 1.0 / 6.0 # probability of six 3 | 4 | prob_heads_and_6 = prob_heads * prob_six 5 | print(prob_heads_and_6) 6 | -------------------------------------------------------------------------------- /2_probability_basics/06_joint_probability_permutations.py: -------------------------------------------------------------------------------- 1 | 2 | # Declare possible outcomes for coin and die 3 | coin_outcomes = ["H", "T"] 4 | die_outcomes = [1, 2, 3, 4, 5, 6] 5 | 6 | # Combine each outcome between coin and die 7 | all_combinations = [(c,d) for c in coin_outcomes for d in die_outcomes] 8 | 9 | # Find only outcomes for Heads and 6 (should only be one) 10 | head_and_6 = [t for t in all_combinations if t[0] == "H" and t[1] == 6] 11 | 12 | # 1/12 = .083333 13 | print(float(len(head_and_6)) / float(len(all_combinations))) 14 | -------------------------------------------------------------------------------- /2_probability_basics/07_joint_probability_multiple.py: -------------------------------------------------------------------------------- 1 | prob_failure = .10 2 | 3 | three_fails_prob = 1.0 4 | 5 | for i in range(0,3): 6 | three_fails_prob = three_fails_prob * prob_failure 7 | 8 | print("Probability of 3 consecutive failures: {}".format(three_fails_prob)) 9 | -------------------------------------------------------------------------------- /2_probability_basics/08_logarithmic_addition.py: -------------------------------------------------------------------------------- 1 | from math import log, exp 2 | 3 | prob_failure = .10 4 | three_fails_prob = 0.0 5 | 6 | for i in range(0,3): 7 | # Perform logarithmic addition instead of multiplication 8 | three_fails_prob = three_fails_prob + log(prob_failure) 9 | 10 | # Use exp() to convert back! 11 | three_fails_prob = exp(three_fails_prob) 12 | 13 | print("Probability of 3 consecutive failures: {}".format(three_fails_prob)) 14 | -------------------------------------------------------------------------------- /2_probability_basics/09_mutually_exclusive_union.py: -------------------------------------------------------------------------------- 1 | prob_1 = 1.0 / 6.0 2 | prob_6 = 1.0 / 6.0 3 | 4 | prob_1_or_6 = prob_1 + prob_6 5 | print(prob_1_or_6) 6 | -------------------------------------------------------------------------------- /2_probability_basics/10_non_mutually_exclusive_union_bad.py: -------------------------------------------------------------------------------- 1 | prob_roll_1_1to4 = 4.0 / 6.0 2 | prob_roll_2_1to4 = 4.0 / 6.0 3 | 4 | prob_1to4_either = prob_roll_1_1to4 + prob_roll_2_1to4 5 | print(prob_1to4_either) 6 | -------------------------------------------------------------------------------- /2_probability_basics/11_non_mutually_exclusive_union_permutations.py: -------------------------------------------------------------------------------- 1 | # Declare possible outcomes for coin and die 2 | first_roll_outcomes = [1, 2, 3, 4, 5, 6] 3 | second_roll_outcomes = [1, 2, 3, 4, 5, 6] 4 | 5 | # Combine each outcome between both dice 6 | all_combinations = [(c,d) for c in second_roll_outcomes for d in first_roll_outcomes] 7 | 8 | # Find outcomes where first die is 1-4: 9 | first_is_1_thru_4 = [t for t in all_combinations if t[0] in range(1,5)] 10 | 11 | # Find outcomes where second die is 1-4: 12 | second_is_1_thru_4 = [t for t in all_combinations if t[1] in range(1,5)] 13 | 14 | # Overlap between both die outcomes: 15 | overlap = set(first_is_1_thru_4).intersection(set(second_is_1_thru_4)) 16 | print("OVERLAP: {}".format(overlap)) 17 | 18 | # Calculate correct probability 19 | correct_probability_either_1_thru_4 = \ 20 | float(len(first_is_1_thru_4) + len(second_is_1_thru_4) - len(overlap)) / len(all_combinations) 21 | 22 | print("CORRECT PROBABILITY OF EITHER DIE BEING 1-4: {}".format(correct_probability_either_1_thru_4)) 23 | -------------------------------------------------------------------------------- /2_probability_basics/12_non_mutually_exclusive_union.py: -------------------------------------------------------------------------------- 1 | prob_roll_1_1to4 = 4.0 / 6.0 2 | prob_roll_2_1to4 = 4.0 / 6.0 3 | 4 | prob_1to4_either = prob_roll_1_1to4 + prob_roll_2_1to4 - 5 | (prob_roll_1_1to4 * prob_roll_2_1to4) 6 | 7 | print(prob_1to4_either) 8 | -------------------------------------------------------------------------------- /3_bayes_theorem/01_likelihood_homicidal.py: -------------------------------------------------------------------------------- 1 | p_gamer_given_homicidal = .85 2 | p_homicidal = 17251.0 / 324000000.0 3 | 4 | print(p_homicidal) 5 | -------------------------------------------------------------------------------- /3_bayes_theorem/02_bayes_theorem.py: -------------------------------------------------------------------------------- 1 | p_gamer_given_homicidal = .85 2 | p_gamer = .19 3 | p_homicidal = .00005 4 | 5 | p_homicidal_given_gamer = p_gamer_given_homicidal * p_homicidal / p_gamer 6 | 7 | print("Probability of homicidal given gamer: {}".format(p_homicidal_given_gamer)) 8 | -------------------------------------------------------------------------------- /3_bayes_theorem/03_population_example.py: -------------------------------------------------------------------------------- 1 | population = 100000.0 2 | 3 | p_gamer_given_homicidal = .85 4 | p_gamer = .19 5 | p_homicidal = .00005 6 | 7 | gamers_ct = population * p_gamer 8 | homicidal_criminals_ct = population * p_homicidal 9 | gamers_and_homicidal_ct = homicidal_criminals_ct * p_gamer_given_homicidal 10 | 11 | print("#Gamers: {}".format(gamers_ct)) 12 | print("#Homicidal Criminals: {}".format(homicidal_criminals_ct)) 13 | print("#Gamers who are homicidal criminals: {}".format(gamers_and_homicidal_ct)) 14 | -------------------------------------------------------------------------------- /3_bayes_theorem/04_bayes_theorem_population.py: -------------------------------------------------------------------------------- 1 | population = 100000.0 2 | 3 | p_gamer_given_homicidal = .85 4 | p_gamer = .19 5 | p_homicidal = .00005 6 | 7 | gamers_ct = population * p_gamer 8 | homicidal_criminals_ct = population * p_homicidal 9 | gamers_and_homicidal_ct = homicidal_criminals_ct * p_gamer_given_homicidal 10 | 11 | p_homicidal_given_gamer = gamers_and_homicidal_ct / gamers_ct 12 | 13 | print("Probability of homicidal given gamer: {}".format(p_homicidal_given_gamer)) 14 | -------------------------------------------------------------------------------- /3_bayes_theorem/05_bayes_theorem_population_expanded.py: -------------------------------------------------------------------------------- 1 | population = 100000.0 2 | 3 | p_gamer_given_homicidal = .85 4 | p_gamer = .19 5 | p_homicidal = .00005 6 | 7 | gamers_ct = population * p_gamer 8 | homicidal_criminals_ct = population * p_homicidal 9 | 10 | # gamers_and_homicidal_ct = homicidal_criminals_ct * p_gamer_given_homicidal 11 | gamers_and_homicidal_ct = population * p_homicidal * p_gamer_given_homicidal 12 | 13 | # p_homicidal_given_gamer = gamers_and_homicidal_ct / gamers_ct 14 | p_homicidal_given_gamer = (population * p_homicidal * p_gamer_given_homicidal) / (population * p_gamer) 15 | 16 | print("Probability of homicidal given gamer: {}".format(p_homicidal_given_gamer)) 17 | -------------------------------------------------------------------------------- /3_bayes_theorem/06_bayes_theorem_population_remove_n.py: -------------------------------------------------------------------------------- 1 | p_gamer_given_homicidal = .85 2 | p_gamer = .19 3 | p_homicidal = .00005 4 | 5 | p_homicidal_given_gamer = p_homicidal * p_gamer_given_homicidal / p_gamer 6 | 7 | print("Probability of homicidal given gamer: {}".format(p_homicidal_given_gamer)) 8 | -------------------------------------------------------------------------------- /4_binomial_beta_distribution/01_factorial.py: -------------------------------------------------------------------------------- 1 | # Factorials multiply consecutive descending integers down to 1 2 | # EXAMPLE: 5! = 5 * 4 * 3 * 2 * 1 3 | def factorial(n: int): 4 | f = 1 5 | for i in range(n): 6 | f *= (i + 1) 7 | return f 8 | -------------------------------------------------------------------------------- /4_binomial_beta_distribution/02_binomial_coefficient.py: -------------------------------------------------------------------------------- 1 | # Factorials multiply consecutive descending integers down to 1 2 | # EXAMPLE: 5! = 5 * 4 * 3 * 2 * 1 3 | def factorial(n: int): 4 | f = 1 5 | for i in range(n): 6 | f *= (i + 1) 7 | return f 8 | 9 | # Generates the coefficient needed for the binomial distribution 10 | def binomial_coefficient(n: int, k: int): 11 | return factorial(n) / (factorial(k) * factorial(n - k)) 12 | 13 | print("FACTORIAL of 3: {}".format(factorial(3))) 14 | print("BINOMIAL COEFFICIENT n=3, k=2: {}".format(binomial_coefficient(3,2))) 15 | -------------------------------------------------------------------------------- /4_binomial_beta_distribution/03_binomial_distribution.py: -------------------------------------------------------------------------------- 1 | # Factorials multiply consecutive descending integers down to 1 2 | # EXAMPLE: 5! = 5 * 4 * 3 * 2 * 1 3 | def factorial(n: int): 4 | f = 1 5 | for i in range(n): 6 | f *= (i + 1) 7 | return f 8 | 9 | # Generates the coefficient needed for the binomial distribution 10 | def binomial_coefficient(n: int, k: int): 11 | return factorial(n) / (factorial(k) * factorial(n - k)) 12 | 13 | 14 | # Binomial distribution calculates the probability of k events out of n trials 15 | # given the p probability of k occurring 16 | def binomial_distribution(n: int, k: int, p: float): 17 | return binomial_coefficient(n, k) * (p ** k) * (1.0 - p) ** (n - k) 18 | 19 | p = .9 20 | n = 10 21 | k = 8 22 | 23 | p_eight_successes = binomial_distribution(n, k, p) 24 | 25 | print("PROB 8 SUCCESSES: {}".format(p_eight_successes)) 26 | # PROB 8 SUCCESSES: 0.19371024449999993 -------------------------------------------------------------------------------- /4_binomial_beta_distribution/04_binomial_distribution_range.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Factorials multiply consecutive descending integers down to 1 4 | # EXAMPLE: 5! = 5 * 4 * 3 * 2 * 1 5 | def factorial(n: int): 6 | f = 1 7 | for i in range(n): 8 | f *= (i + 1) 9 | return f 10 | 11 | # Generates the coefficient needed for the binomial distribution 12 | def binomial_coefficient(n: int, k: int): 13 | return factorial(n) / (factorial(k) * factorial(n - k)) 14 | 15 | 16 | # Binomial distribution calculates the probability of k events out of n trials 17 | # given the p probability of k occurring 18 | def binomial_distribution(n: int, k: int, p: float): 19 | return binomial_coefficient(n, k) * (p ** k) * (1.0 - p) ** (n - k) 20 | 21 | p = .9 22 | n = 10 23 | 24 | prob_eight_or_less_successes = 0.0 25 | 26 | for k in range(0,9): 27 | prob_of_k_successes = binomial_distribution(n, k, p) 28 | print("PROB {} SUCCESSES: {}".format(k, prob_of_k_successes)) 29 | prob_eight_or_less_successes += prob_of_k_successes 30 | 31 | print("PROB 8 OR LESS SUCCESSES: {}".format(prob_eight_or_less_successes)) 32 | # PROB 8 OR LESS SUCCESSES: 0.2639010708999999 -------------------------------------------------------------------------------- /4_binomial_beta_distribution/05_approximate_integral.py: -------------------------------------------------------------------------------- 1 | def approximate_integral(a, b, n, f): 2 | delta_x = (b - a) / n 3 | total_sum = 0 4 | 5 | for i in range(1, n + 1): 6 | midpoint = 0.5 * (2 * a + delta_x * (2 * i - 1)) 7 | total_sum += f(midpoint) 8 | 9 | return total_sum * delta_x 10 | 11 | 12 | def my_function(x): 13 | return 2 * x**2 14 | 15 | 16 | area = approximate_integral(a=0, b=1, n=500, f=my_function) 17 | 18 | print(area) # 0.6666660000000002 19 | -------------------------------------------------------------------------------- /4_binomial_beta_distribution/06_beta_distribution.py: -------------------------------------------------------------------------------- 1 | def approximate_integral(a, b, n, f): 2 | delta_x = (b - a) / n 3 | total_sum = 0 4 | 5 | for i in range(1, n + 1): 6 | midpoint = 0.5 * (2 * a + delta_x * (2 * i - 1)) 7 | total_sum += f(midpoint) 8 | 9 | return total_sum * delta_x 10 | 11 | # Factorials multiply consecutive descending integers down to 1 12 | # EXAMPLE: 5! = 5 * 4 * 3 * 2 * 1 13 | def factorial(n: int): 14 | f = 1 15 | for i in range(n): 16 | f *= (i + 1) 17 | return f 18 | 19 | 20 | def beta_distribution(x: float, alpha: float, beta: float) -> float: 21 | if x < 0.0 or x > 1.0: 22 | raise ValueError("x must be between 0.0 and 1.0") 23 | 24 | numerator = x ** (alpha - 1.0) * (1.0 - x) ** (beta - 1.0) 25 | denominator = (1.0 * factorial(alpha - 1) * factorial(beta - 1)) / (1.0 * factorial(alpha + beta - 1)) 26 | 27 | return numerator / denominator 28 | 29 | 30 | greater_than_90 = approximate_integral(a=.90,b=1.0, n=1000, f=lambda x: beta_distribution(x, 8, 2)) 31 | less_than_90 = 1.0 - greater_than_90 32 | 33 | print("GREATER THAN 90%: {}, LESS THAN 90%: {}".format(greater_than_90, less_than_90)) 34 | # GREATER THAN 90%: 0.22515904881135335, LESS THAN 90%: 0.7748409511886467 -------------------------------------------------------------------------------- /5_normal_distribution/01_golden_retriever_weights.py: -------------------------------------------------------------------------------- 1 | from urllib.request import urlopen 2 | 3 | # Retrieve golden retriever weights 4 | weights = [float(w) for w in urlopen("https://bit.ly/3cXuufY") \ 5 | .read().decode('utf-8').split("\n") if w] 6 | 7 | for w in weights: 8 | print(w) 9 | 10 | -------------------------------------------------------------------------------- /5_normal_distribution/02_normal_pdf.py: -------------------------------------------------------------------------------- 1 | import math, random 2 | 3 | # normal distribution, returns likelihood 4 | def normal_pdf(x: float, mean: float, std_dev: float) -> float: 5 | return (1.0 / (2.0 * math.pi * std_dev ** 2) ** 0.5) * \ 6 | math.exp(-1.0 * ((x - mean) ** 2 / (2.0 * std_dev ** 2))) 7 | 8 | mean = 50.0 9 | std_dev = 15.0 10 | 11 | for x in range(0,100): 12 | likelihood_of_x = normal_pdf(x, mean, std_dev) 13 | print("{},{}".format(x, likelihood_of_x)) 14 | 15 | -------------------------------------------------------------------------------- /5_normal_distribution/03_normal_approximate_integral.py: -------------------------------------------------------------------------------- 1 | import math, random 2 | 3 | # normal distribution, returns likelihood 4 | def normal_pdf(x: float, mean: float, std_dev: float) -> float: 5 | return (1.0 / (2.0 * math.pi * std_dev ** 2) ** 0.5) * \ 6 | math.exp(-1.0 * ((x - mean) ** 2 / (2.0 * std_dev ** 2))) 7 | 8 | def approximate_integral(a, b, n, f): 9 | delta_x = (b - a) / n 10 | total_sum = 0 11 | 12 | for i in range(1, n + 1): 13 | midpoint = 0.5 * (2 * a + delta_x * (2 * i - 1)) 14 | total_sum += f(midpoint) 15 | 16 | return total_sum * delta_x 17 | 18 | def dog_weight_distribution(x): 19 | mean = 64.43 20 | std_dev = 2.99 21 | return normal_pdf(x, mean, std_dev) 22 | 23 | prob_between_62_and_66 = approximate_integral(a=62, b=66, n=1000, f=dog_weight_distribution) 24 | 25 | print("PROB BETWEEN 62 and 66: {}".format(prob_between_62_and_66)) 26 | # PROB BETWEEN 62 and 66: 0.4920450456930307 -------------------------------------------------------------------------------- /5_normal_distribution/04_normal_cdf.py: -------------------------------------------------------------------------------- 1 | import math, random 2 | 3 | # cumulative density function, returns area/probability up to x 4 | def normal_cdf(x: float, mean: float, std_dev: float) -> float: 5 | return (1 + math.erf((x - mean) / math.sqrt(2) / std_dev)) / 2 6 | 7 | 8 | mean = 64.43 9 | std_dev = 2.99 10 | 11 | prob_between_62_and_66 = normal_cdf(66.0, mean, std_dev) - normal_cdf(62.0, mean, std_dev) 12 | 13 | print("PROB BETWEEN 62_and_66: {}".format(prob_between_62_and_66)) 14 | # PROB BETWEEN 62_and_66: 0.49204501470628936 -------------------------------------------------------------------------------- /5_normal_distribution/05_normal_inverse_cdf.py: -------------------------------------------------------------------------------- 1 | import random 2 | from scipy.special import erfinv 3 | 4 | # the quantile function, also known as inverse CDF 5 | def inv_normal_cdf(p: float, mean: float, std_dev: float): 6 | return mean + (std_dev * (2.0 ** 0.5) * erfinv((2.0 * p) - 1.0)) 7 | 8 | mean = 64.43 9 | std_dev = 2.99 10 | 11 | # generate 10 random values following 12 | # normal distribution 13 | for i in range(0,10): 14 | random_p = random.uniform(0.0, 1.0) 15 | print(inv_normal_cdf(random_p, mean, std_dev)) 16 | -------------------------------------------------------------------------------- /Probability From Scratch.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasnield/oreilly-probability-from-scratch/16d331315e20c81b8a5918e1afdf61b7ede9a36a/Probability From Scratch.pdf -------------------------------------------------------------------------------- /Probability From Scratch.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasnield/oreilly-probability-from-scratch/16d331315e20c81b8a5918e1afdf61b7ede9a36a/Probability From Scratch.pptx --------------------------------------------------------------------------------