From 8cff7e1c5a4cece69c5b1ed0a90db666cf7c08ab Mon Sep 17 00:00:00 2001 From: Daniel Heras Quesada Date: Tue, 18 Nov 2025 13:09:24 +0100 Subject: [PATCH] feat: beta distribution --- src/modules/probability.py | 75 ++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/src/modules/probability.py b/src/modules/probability.py index d3e2ea9..08f0142 100644 --- a/src/modules/probability.py +++ b/src/modules/probability.py @@ -1,8 +1,8 @@ ## This module represents the second chapter of the book ## "Essential Math for Data Science" - Thomas Nield -## Chaper 2 - Probability +## Chapter 2 - Probability -from scipy.stats import binom +from scipy.stats import binom, beta from math import factorial # 2.0 odds means than an events has twice the probabilities to happen than not @@ -12,31 +12,58 @@ def p_odds_to_probability(o): def p_probability_to_odds(p): return (p / (1 - p)) -## Binomial distribution -def p_binomial_distribution_example(): - n = 10 - p = 0.9 +class BinomialDistribution: + @staticmethod + def example(): + n = 10 + p = 0.9 - for k in range(n + 1): - probability = binom.pmf(k, n, p) - print("{0} >> {1}".format(k, probability)) + for k in range(n + 1): + probability = binom.pmf(k, n, p) + print("{0} >> {1}".format(k, probability)) -def binomial_coeficient(pool, count): - return factorial(pool) / (factorial(count) * factorial(pool - count)) + @staticmethod + def binomial_coeficient(pool, count): + return factorial(pool) / (factorial(count) * factorial(pool - count)) + + @staticmethod + def from_scratch(p, n): + # For each number calc the probability of that exact number of outcomes (no order) + for k in range(n + 1): + # 1. Simple combinatory with the binomial coeficient (combinations of k elements out of a pool of n without repetition without order) + combinatory = BinomialDistribution.binomial_coeficient(n, k) + # 2. Probability of success, the probability of making it k times + probability_of_success = p ** k + # 3. Probability of failure, inverse of the success + probability_of_failure = (1 - p) ** (n - k) + k_binomital_distribution_probability = combinatory * probability_of_success * probability_of_failure + print("[{0}]: {1}".format(k, k_binomital_distribution_probability)) + +# Study probability of probabilities +# > Given X success rate, get the likelihood of that success rate +# > Returns a continuous function, so the final probability of X or better must be calculated using integrals (the area under the curve) +class BetaDistribution: + @staticmethod + def calc(probability, success_count, failure_count): + # Only calcs the rpbability to the left + return beta.cdf(probability, success_count, failure_count) + + @staticmethod + def calc_right(probability, success_count, failure_count): + return 1.0 - BetaDistribution.calc(probability, success_count, failure_count) + + @staticmethod + def calc_region(init_probability, end_probability, success_count, failure_count): + return BetaDistribution.calc(end_probability, success_count, failure_count) - BetaDistribution.calc(init_probability, success_count, failure_count) + +class Exercises: -def p_binomial_distribution_scratch(p, n): - # For each number calc the probability of that exact number of outcomes (no order) - for k in range(n + 1): - # 1. Simple combinatory with the binomial coeficient (combinations of k elements out of a pool of n without repetition without order) - combinatory = binomial_coeficient(n, k) - # 2. Probability of success, the probability of making it k times - probability_of_success = p ** k # p * p, k times - # 3. Probability of failure, inverse of the success - probability_of_failure = (1 - p) ** (n - k) # inverse of probability the rest of the times - k_binomital_distribution_probability = combinatory * probability_of_success * probability_of_failure - print("[{0}]: {1}".format(k, k_binomital_distribution_probability)) def test_probability_module(): - p_binomial_distribution_example() - p_binomial_distribution_scratch(0.9, 10) + print(">> Binomial distribution") + BinomialDistribution.example() + BinomialDistribution.from_scratch(0.9, 10) + print(">> Beta distribution") + print(BetaDistribution.calc(0.9,8,2)) + print(BetaDistribution.calc_region(0.8, 0.9, 8, 2))