python数据分析:使用lifetimes进行客户终身价值(CLV)探索

版权声明:本文为博主原创文章,如若转载请注明出处 https://blog.csdn.net/tonydz0523/article/details/86256803

客户终身价值(CLV)

客户终身价值(CLV)是从一个关键人物业务。它通常描述了客户在整个“客户生活”期间实现的贡献边际,折扣到分析时。因此,CLV可以理解为客户多年来对公司或未来的平均价值。因此,除历史收入外,未来预期收入也会被考虑(客户潜力)。在确定CLV时,必须将可能的客户价值与实际客户价值区分开来。可能的客户价值考虑了某个区域内客户的总支出,包括竞争对手的支出,而实际的CLV仅考虑了客户对其公司的支出。公司使用CLV更有效地为客户量身定制营销。例如,高CLV证明更高的预算用于照顾特定客户。

数据

下载链接在此。

数据集信息:

这是一个跨国数据集,其中包含2010年12月1日至2011年12月9日期间发生的所有在英国和注册的非商店在线零售业务的交易。该公司主要销售独特的全场礼品。该公司的许多客户都是批发商。

属性信息:

  • InvoiceNo:发票编号;标称值,为每个事务唯一分配的6位整数;如果此代码以字母’c’开头,则表示取消。
  • StockCode:产品(项目)代码。标称值,为每个不同的产品唯一分配的5位整数。
  • Description:产品(项目)名称。标称。
  • Quantity:每笔交易的每件产品(项目)的数量。数字。
  • InvoiceDate:Invice日期和时间。数字,生成每个事务的日期和时间。
  • UnitPrice:单价。数字,英镑单位产品价格。
  • CustomerID:客户编号。标称值,为每个客户唯一分配的5位整数。
  • Country:国家名称。Nominal,每个客户所在国家/地区的名称。

数据预处理

import pandas as pd
import numpy as np
import warnings
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
from lifetimes.plotting import *
from lifetimes.utils import *
from lifetimes.estimation import *

warnings.filterwarnings('ignore')

# 读取数据
df = pd.read_excel('Online Retail.xlsx')
df = df.copy()
df.head(2).T

在这里插入图片描述

df.describe()

在这里插入图片描述
可见有数量、价格小于0的情况,数量小于0应该是有退货现象,而且此代码以字母’C’开头,则表示取消

查看以‘C’开头的是否都是数量为负

(df[df.InvoiceNo.map(lambda x:str(x)[0] == 'C')].Quantity > 0).any()

False

说明的确以‘C’开头的是否都是数量为负

取消订单情况 取消单发票以‘C’开头,长度为7

df.InvoiceNo.map(lambda x:str(x)[0] == 'C').value_counts()

在这里插入图片描述

(df.Quantity < 0).value_counts()

在这里插入图片描述
由上可见除了以“C”开头的数据,还有其他数量小于0的数据

df[df.InvoiceNo.map(lambda x:str(x)[0] != 'C')].query('Quantity < 0')

由上可见除了以“C”开头的数据,还有其他数量小于0的数据,简单看了一下这些数据都是价格为0,没有用户ID,是什么数据无法推断,反正之后要弃去

### 筛选出数量价格
df.query('Quantity > 0 & UnitPrice >0', inplace=True)
# 检查缺失值
df.isna().sum()

# 弃去缺失值
df.dropna(inplace=True)

### 创建价格列(数量×单价)
df['Sales'] = df.Quantity*df.UnitPrice

这里我们需要的数据为订单号,消费者id,下单时间,价格(数量×单价)

df = df[['InvoiceNo', 'CustomerID', 'InvoiceDate', 'Sales']]

### 更改用户ID类型
df.CustomerID = df.CustomerID.astype('object')

df.nunique()

在这里插入图片描述

扫描二维码关注公众号,回复: 5001031 查看本文章

数据中包含共18532订单,4338个用户

CLV建模探索

data = summary_data_from_transaction_data(df, 'CustomerID', 'InvoiceDate',
                         monetary_value_col='Sales',
                         observation_period_end='2011-12-9')
data.sort_values('monetary_value').head()

在这里插入图片描述

频率为0说明只有一次购买。

频率分布情况

data['frequency'].plot(kind='hist', bins=50)

在这里插入图片描述
可见0居多,分布偏左

频率为0占比

# 说在周期内只消费过一次比例
(data.frequency == 0).value_counts().plot.bar()

在这里插入图片描述

sum(data['frequency'] == 0)/float(len(data))

结果为:0.35684647302904565
频率为0占总体35.7%

使用BG / NBD模型进行频率/新近度分析

from lifetimes import BetaGeoFitter
bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(data['frequency'], data['recency'], data['T'])
print(bgf)

结果如下:
<lifetimes.BetaGeoFitter: fitted with 4338 subjects, a: 0.00, alpha: 68.91, b: 6.75, r: 0.83>

可视化(频率/新进度)矩阵

from lifetimes.plotting import plot_frequency_recency_matrix
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(12,8))
plot_frequency_recency_matrix(bgf)

在这里插入图片描述

如图可见:

  • 右下角的数据120/350,该用户进行了120次购买,并且他最近购买时间大约是350天(她的第一笔交易和她最近的交易之间的时间间隔),那么她属于最有价值客户,依照其消费惯性,将来也会进行多笔交易
  • 右上角黑了的部分可能是已经失去的客户
  • 20/250这样的数据,代表客户不经常来,最近没有见过他,所以他可能再次购买
  • 最近购买的顾客应该还“活着”

预测哪些客户还在

from lifetimes.plotting import plot_probability_alive_matrix
fig = plt.figure(figsize=(12,8))
plot_probability_alive_matrix(bgf)

在这里插入图片描述
黄色部分为还在用户,深色部分为丢失用户

我们将客户从“下一期最高预期购买量”排名降至最低。模型公开了一种方法,该方法将使用其历史记录预测下一时期客户的预期购买:

t = 1
data['predicted_purchases'] = bgf.conditional_expected_number_of_purchases_up_to_time(t, 
                                  data['frequency'], data['recency'], data['T'])
data.sort_values(by='predicted_purchases', ascending=False).head()

在这里插入图片描述

上面列出的是我们的前五大客户,模型的predict_purchases列给出了购买的概率。

评估模型拟合

from lifetimes.plotting import plot_period_transactions
plot_period_transactions(bgf)

在这里插入图片描述
结果相近,看起来模型的预测还不错

分数据集进行预测

现在将数据集划分为校准周期数据集和保持数据集。这很重要,因为我们想要测试我们的模型如何对尚未看到的数据执行(就像机器学习实践中的交叉验证一样)

from lifetimes.utils import calibration_and_holdout_data
summary_cal_holdout = calibration_and_holdout_data(df, 'CustomerID', 'InvoiceDate',
                                        calibration_period_end='2011-06-08',
                                        observation_period_end='2011-12-9' )   
summary_cal_holdout.head()

在这里插入图片描述

预测结果

from lifetimes.plotting import plot_calibration_purchases_vs_holdout_purchases
bgf.fit(summary_cal_holdout['frequency_cal'], summary_cal_holdout['recency_cal'], summary_cal_holdout['T_cal'])
plot_calibration_purchases_vs_holdout_purchases(bgf, summary_cal_holdout)

在这里插入图片描述

样本期间从开始到2011-06-08; 验证期从2011-06-09到2011-12-09。该图通过重复购买次数(x轴)对校准期内的所有客户进行分组,然后在保持期(y轴)中对其重复购买进行平均。橙线和蓝线分别表示模型预测和y轴的实际结果。正如我们所看到的,我们的模型能够非常准确地预测出样本中客户群的行为,模型低估了4次购买和5次购买后。

客户交易预测

根据客户历史记录,我们现在可以预测个人未来的购买情况:

t = 10
individual = data.loc[12347]
bgf.predict(t, individual['frequency'], individual['recency'], individual['T'])

预测12347用户未来10天内购买商品为概率为0.157

客户概率历史

根据客户交易历史记录,我们可以根据我们训练的模型计算其存活的历史概率。例如,我们想看看我们最好的客户的交易历史,看看活着的可能性:
1.

from lifetimes.plotting import plot_history_alive
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(12,8))
id = 14606
days_since_birth = 365
sp_trans = df.loc[df['CustomerID'] == id]
plot_history_alive(bgf, days_since_birth, sp_trans, 'InvoiceDate')

在这里插入图片描述
我们最好的客户肯定还活着只是在2011年1月有中断情况

fig = plt.figure(figsize=(12,8))
id = 12347
days_since_birth = 365
sp_trans = df.query('CustomerID == @id')
plot_history_alive(bgf, days_since_birth, sp_trans, 'InvoiceDate')

在这里插入图片描述
这位顾客来的频率不是很高但是分布还算均匀,最近也有消费,是‘活着’的用户

gamma-gamma模型估算客户终生价值

我们仅估算至少有一次重复购买的客户。因此,我们估计有2,790位客户:

returning_customers_summary = data[data['frequency']>0]
returning_customers_summary.shape[0]

# 模型训练
from lifetimes import GammaGammaFitter
ggf = GammaGammaFitter(penalizer_coef = 0)
ggf.fit(returning_customers_summary['frequency'],
        returning_customers_summary['monetary_value'])

# 这样我们可以估算每个客户的平均交易价值
ggf.conditional_expected_average_profit(
        data['frequency'],
        data['monetary_value']
    ).head()

在这里插入图片描述
这样我们获取每个客户的估计平均交易价值

猜你喜欢

转载自blog.csdn.net/tonydz0523/article/details/86256803