Gamma-Gamma模型
前面已经提到过,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
模型认为:
- z i z_i zi 服从 g a m m a ( p , v ) gamma(p,v) gamma(p,v)分布,根据Gamma分布的可加性,在 x x x 个交易的总价值的分布服从 g a m m a ( p x , v ) gamma(px,v) gamma(px,v) ; 而根据gamma分布的尺度特性, z ˉ \bar{z} zˉ 服从 g a m m a ( p x , v x ) gamma(px,vx) gamma(px,vx)
- v v v 服从 g a m m a ( q , γ ) gamma(q,\gamma) gamma(q,γ)
模型的条件期望为:
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是观测的交易价值均值
可采用最大似然估计来估算参数
采用lifetimes包中包含经济价值的数据来拟合模型
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())
上面的monetary_value就是价值均值
returning_customers_summary[['monetary_value', 'frequency']].corr()
检查价值均值和交易频率的皮尔森相关系数:相关性接近0
from lifetimes import GammaGammaFitter
ggf = GammaGammaFitter(penalizer_coef = 0)
ggf.fit(returning_customers_summary['frequency'],
returning_customers_summary['monetary_value'])
print(ggf)
<lifetimes.GammaGammaFitter: fitted with 946 subjects, p: 6.25, q: 3.74, v: 15.45>
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'])
<lifetimes.BetaGeoFitter: fitted with 2357 subjects, a: 0.79, alpha: 4.41, b: 2.43, r: 0.24>
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))
采用DCF(Discount Cash Flow)计算CLV