clvkit.MBGNBD#
- class MBGNBD[source]#
Bases:
objectThe MBG/NBD transaction-flow model — BG/NBD’s never-returner variant.
The same three verbs as BGNBD, so it drops into the same places:
model = MBGNBD().fit(cb) model.predict(t=12).to_pandas() # expected purchases in the next 12 time units model.probability_alive().to_pandas()
Reach for it over BGNBD when a large share of the base never repeated: BG/NBD calls every one of those customers alive with probability 1, while this model lets them have died right after their first purchase.
Fitting is maximum likelihood — no sampler, no priors, no convergence diagnostics to read.
- fit(cb)[source]#
Estimate
(r, alpha, a, b)by maximum likelihood oncb.The optimiser works on
logparameters so the search is unconstrained while the parameters stay strictly positive, which is what the gamma and beta priors of section 3 require.- Parameters:
cb (CustomerBase)
- Return type:
- predict(t, cb=None)[source]#
Expected purchases in the next
ttime units, per customer.tis in the fitted base’s owntime_unit. Passcbto score a different customer base than the one fitted on — it must carry the sametime_unit, or the answer would silently be in the wrong units.- Parameters:
t (float)
cb (CustomerBase | None)
- Return type:
Prediction
- probability_alive(cb=None)[source]#
P(each customer is still active) at the base’s observation period end.
- Parameters:
cb (CustomerBase | None)
- Return type:
Prediction
- parameter_uncertainty(*, n=200, seed=None, confidence=0.95)[source]#
Bootstrap standard errors and intervals for
(r, alpha, a, b).A parametric bootstrap:
nsynthetic customer bases are drawn from the fitted parameters — each customer keeping their observed tenure, some dying at time zero — the model refit on each, and the spread reported per parameter. Expect wide intervals onaandbeven on a large base; that weak identification is the honest result, not a bug. Reproducible fromseed; costsnrefits, run serially.- Parameters:
- Return type: