BetaPERT Distribution
Beta-PERT is just the Beta distribution with the PERT heuristic to compute its $$\alpha$$ and $$\beta$$ parameters from three-point-estimates of A - the minimum, M - the most likely, and B - the maximum expected value. The normal distribution, due to its immutable symmetry around the mean and median, is not always the best model, when we know a little more about the distribution of values. Let's derive this useful tool.
beta
from fxy.s import *
from sympy.stats import Beta, density
# α, β
a = Symbol('α', positive=True)
b = Symbol('β', positive=True)
B = Beta('B', a, b)
Let's get its general distribution (pdf) formula, and print specific parametrization:
beta_pdf = density(B)(x)
my_beta_pdf = beta_pdf.subs({a: 2, b: 5})
plot(my_beta_pdf, xlim=[0, 1], ylim=[0,5]);
Continuation: https://github.com/mindey/plandf/blob/master/docs/beta-PERT.ipynb
PERT
PERT stands for Program Evaluation and Review Technique by Malcolm et al, 1959. It was initially known as the Program Evaluation and Review Task. The task to which this refers was assessing the uncertainty in the plans for the development schedule and cost for the Polaris weapon system [*]. However, over time, it had found its was into project planning in general.
It provides a kind of heuristic to compute parameters $$\alpha$$ and $$\beta$$ for the Beta distribution, based on 3 pieces of information for every asset:
A -- the min amount
M -- the most likely amount
B -- the max amount
Continuation: https://github.com/mindey/plandf/blob/master/docs/beta-PERT.ipynb
betaPERT
While PERT gives mean and variance to use with any distribution, if you would try the above with Beta distribution, you would get errors. To use PERT with Beta distribution for intervals other than $$[0, 1]$$, we should need to normalize and shift data to unitary interval before computing PERT.
from sympy.stats import Beta, density
from sympy import Symbol
def BetaPERT(A, M, B, normalize=True, info=False):
"""
A: beginning of interval
M: most likely value
B: end of interval
Returns a Beta distribution with PERT parameters.
"""
a = Symbol('α', positive=True)
b = Symbol('β', positive=True)
def PERT(A, M, B, normalize=False):
"""
Use normalize=True, if you want to go around [-1, 1] interval,
(if you want to look at the distribution shape without caring about its location.)
"""
if normalize:
try:
Max = max(A, M, B)
except:
import pdb; pdb.set_trace()
Min = min(A, M, B)
standardize = -(Min + Max) / 2.
normalize = Max - Min
A = (float(A) + standardize) / normalize + 0.5
M = (float(M) + standardize) / normalize + 0.5
B = (float(B) + standardize) / normalize + 0.5
if info:
print({'A': A, 'M': M, 'B': B})
# PERT Heuristics:
mean = (A + (4. * M) + B) / 6.
variance = ((A - B) / 6.)**2.
return {'mean': mean, 'variance': variance}
def beta_params(mean, variance):
miu = Symbol('μ')
sigma = Symbol('σ')
alpha = -b*miu / (miu - 1)
beta = (miu - 1 ) * (miu**2 - miu + sigma) / sigma
beta = beta.subs({miu: mean,sigma: variance})
alpha = alpha.subs({miu:mean, b:beta})
return {a:alpha, b:beta}
def pert_beta(A, M, B):
beta_cdf = Beta('B', a, b)
# x = Symbol('x')
# beta_pdf = density(B)(x)
return beta_cdf.subs(
beta_params(
**PERT(A, M, B, normalize)
)
)
return pert_beta(A, M, B)
Then use it:
from fxy.s import *
D = BetaPERT(10., 13.8, 15.)
p = density(D)(x)
plot(p, xlim=[0, 1], ylim=[0, 3])
# Try:
# plot(density(BetaPERT(0., 0.2, 1.))(x))
# plot(density(BetaPERT(0., 0.8, 1.))(x))
Last updated