clvkit.CustomerBase#
- class CustomerBase(data, *, time_unit, observation_period_end, has_monetary, on_negative, collapse=None, events=None, customer_id_col='customer_id', amount_col='amount', engine='pandas')[source]#
Bases:
objectA self-describing RFM summary built from a raw transaction log.
frequency is the BTYD repeat purchase count (total purchases minus one), not the raw transaction count — the #1 gotcha for anyone new to the BTYD/probability-model tradition.
- Parameters:
- classmethod from_transactions(transactions, customer_id_col='customer_id', datetime_col='date', amount_col='amount', *, time_unit='D', collapse=None, observation_period_end=None, datetime_format=None, on_negative='net', engine='pandas')[source]#
Summarise a raw transaction log into RFM plus provenance.
time_unit is the ruler: the unit recency and T are reported in. collapse is the event grain: transactions falling in the same collapse period become one purchase, because the counting process the BTYD models assume wants separated events.
They default to the same thing, which is what makes time_unit=”W” alone a trap — it does not merely re-scale the ruler, it deletes every second purchase inside a week, and it deletes most from your heaviest buyers. Pass both to reproduce the published CDNOW fit, which collapses at the data’s daily resolution and reports time in weeks:
CustomerBase.from_transactions(log, time_unit="W", collapse="D")
engine="dask"takes adask.dataframe.DataFrameinstead of a pandas one and never holds the whole log in memory. The summary it returns is an ordinary pandas-backedCustomerBase— per-customer and small — but it does not retain the event frame, so.split()refuses on it. It needs the optionaldaskextra.The two engines agree on every value. They differ in exactly two ways, both cosmetic and both tested: rows come back in shuffle order rather than first-appearance order, and the customer id keeps whatever dtype the input frame carried — which Dask itself may have rewritten to
string[pyarrow]on the way in.- Parameters:
- Return type:
- split(*, calibration_period_end, observation_period_end=None)[source]#
Split into a calibration CustomerBase and a holdout frame.
Calibration RFM is computed against
calibration_period_endexactly asfrom_transactionswould; the holdout frame carriesfrequency_holdout(repeat purchases in the holdout window),monetary_value_holdout(mean holdout spend, only when monetary), andduration_holdout(holdout length intime_unit). Customers whose first purchase falls in the holdout window have no calibration history and are excluded from both outputs.