# Python library for returning MLE for Beta Geometric and Beta Discrete Weibull models

There is an R package called foretell that is useful for projecting customer retention based on Beta Geometric and Beta Discrete Weibull models.

I am having trouble finding something similar for python, at least one as streamlined. Does anyone know of anything that comes to mind

The functions in the foretell package are fairly simple calls to the R optim function with some data management in between. So in R if you run library(foretell);BdW you can see the function definition.

In python, you would just rewrite the R optim call using scipy minimize. Here is a brief example of minimizing the same example in the foretell docs for the BdW model:

from scipy.optimize import minimize
from scipy.special import beta
import numpy as np

surv = np.array([100,86.9,74.3,65.3,59.3])
h = 6
t = len(surv)
die = np.diff(-surv)
i = np.arange(0,t)

def dbw_ll(x):
a,b,c = x
s = beta(a,b + i**c)/beta(a,b)
p = np.diff(-s)
ll_ = die * np.log(p)
ll = ll_.sum() + surv[-1]*np.log(s[-1])
return -ll

bnds = [(0.001,10000)]*3

res = minimize(dbw_ll, x0=[1,1,1],
method='L-BFGS-B',
bounds=bnds)

print(res.x)
# R results 0.2593549 1.7226948 1.5842688
# agrees for 3 decimals

# projecting out
a, b, c = res.x
k = np.arange(0,t+h)
dbw = (beta(a,b+k**c)/beta(a,b))*100
fitted = dbw[0:t]
projected = dbw[t:]


It is mostly the same exercise for the other functions (mapping R functions to python). You just need to do a days worth of work to wrap these up in nice functions in python to replicate the same functionality in the R foretell library. (Did this example while waiting for a few queries to finish!)

• Thank you very much for your response. I don't have access to R itself but found said documentation here: rdrr.io/cran/foretell/src/R/BdW.R I suppose I asked this question poorly as I was looking for the model's projection of what retention should be over a certain period. I Think I found that formula here : dbw <- (beta(a, b+(k^c)) / beta(a, b))*100 With the results we printed in your answer (res.x), how would I go about inputting that to predict retention at time = 6?
– Kbbm
Jun 9, 2021 at 21:56
• Ahhh, I figured it out. In this example it would go as: dbw = (sc.beta(0.2593549, 1.7226948 + (5**1.5842690)) / sc.beta(0.2593549, 1.7226948))*100,, which will return 54.66.
– Kbbm
Jun 9, 2021 at 22:17
• You got it @KyleMcComb, added a few more lines to show how to generate the projected values (again pretty similar between R/python, so not that much work to translate). Jun 10, 2021 at 11:30