前面已经提到过,Pareto/NBD和BG/NBD模型只对客户存续时间和交易次数进行建模,并不涉及客户未来交易所带来的现金价值。
Gamma-Gamma模型就是对这个问题的一个扩展解决方案。
Gamma-Gamma模型做了如下假设:
如果我们令 z 1 , z 2 , . . . , z x z_1,z_2,...,z_x z1,z2,...,zx 为客户历史上的每次交易的价值序列,所观测到的历史交易价值均值为 z ˉ = ∑ i = 1 x z i / x \bar{z}=\sum_{i=1}^{x}z_i/x zˉ=∑i=1xzi/x
模型认为:
模型的条件期望为:
E ( M ∣ p , q , γ , m x , x ) = ( γ + m x x ) p p x + q − 1 = ( q − 1 p x + q − 1 ) γ p q − 1 + ( p x p x + q − 1 ) m x E(M|p,q,\gamma,m_x,x)=\frac{(\gamma+m_xx)p}{px+q-1}=(\frac{q-1}{px+q-1})\frac{\gamma p}{q-1}+(\frac{px}{px+q-1})m_x E(M∣p,q,γ,mx,x)=px+q−1(γ+mxx)p=(px+q−1q−1)q−1γp+(px+q−1px)mx
m x m_x mx是观测的交易价值均值
可采用最大似然估计来估算参数
from lifetimes.datasets import load_cdnow_summary_data_with_monetary_value
summary_with_money_value = load_cdnow_summary_data_with_monetary_value()
summary_with_money_value.head()
returning_customers_summary = summary_with_money_value[summary_with_money_value['frequency']>0]
print(returning_customers_summary.head())
returning_customers_summary[['monetary_value', 'frequency']].corr()
from lifetimes import GammaGammaFitter
ggf = GammaGammaFitter(penalizer_coef = 0)
ggf.fit(returning_customers_summary['frequency'],
returning_customers_summary['monetary_value'])
print(ggf)
print(ggf.conditional_expected_average_profit(
summary_with_money_value['frequency'],
summary_with_money_value['monetary_value']
).head(10))
print("Expected conditional average profit: %s, Average profit: %s" % (
ggf.conditional_expected_average_profit(
summary_with_money_value['frequency'],
summary_with_money_value['monetary_value']
).mean(),
summary_with_money_value[summary_with_money_value['frequency']>0]['monetary_value'].mean()
))
训练Gamma-Gamma模型,并预测平均交易价值
from lifetimes.datasets import load_cdnow_summary
from lifetimes import BetaGeoFitter
data = load_cdnow_summary(index_col=[0])
bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(data['frequency'], data['recency'], data['T'])
bgf.fit(summary_with_money_value['frequency'], summary_with_money_value['recency'], summary_with_money_value['T'])
print(ggf.customer_lifetime_value(
bgf, #the model to use to predict the number of future transactions
summary_with_money_value['frequency'],
summary_with_money_value['recency'],
summary_with_money_value['T'],
summary_with_money_value['monetary_value'],
time=12, # months
discount_rate=0.01 # monthly discount rate ~ 12.7% annually
).head(10))