机器学习:怎样用模型预测用户的生命周期价值?

语言: CN / TW / HK

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

定义问题

预测下用户在未来能带来的收益。

LTV

这个被称为用户的生命周期价值(CLV:Customer Lifetime Value)或称为LTV(Lifetime Value),指的是每个用户(购买者、会员、使用者)在未来可能为该服务带来的收益总和。

image.png

适用领域

对以广告、销售等动态现金流入的服务(例如App服务、会员网站、电子商务)是相当重要的营运参考数据。 1. 了解产品用户实际价值。 2. 基于大数据的CLV管理方法,最大化有价值用户的利润,对有潜力的用户提升销售,甚至挖掘其他“有价值的用户”。 3. 给予行销人员广告投放方向。例如:取得一个用户的成本不可高于CLV。

数据预处理

预测收益当然需要用户的交易数据,所以继续继续使用《机器学习:从数据中找到用户的RFM值》中的数据。

``` import pandas as pd # 导入Pandas

df_sales=pd.read_csv('/Users/wanghaifeng/Documents/零基础实战机器学习/geektime-main/获客关05/易速鲜花订单记录.csv') df_sales.head() ```

image.png

跟着课程中使用头三个月的R、F、M这三个数值作为特征,一年的总消费额作为标签,做一个回归模型预测出LTV。(这个是课程作者选的,至于为啥以后再研究

数据清洗

``` df_sales.drop_duplicates() #删除重复的数据行

df_sales=df_sales.loc[df_sales['数量']>0] # 清洗掉数量小于等于0的数据

df_sales.describe()

``` 这里说下问题:课程里的没有清洗数量小于0的脏数据,下面使用模型预测出来的值比较好看,但是清洗掉就不好了,这个先搁置,笔者学这个课程也是先对机器学习有个感觉,太纠结就走不下去了。

加上总价

df_sales['总价'] = df_sales['数量'] * df_sales['单价'] # 计算每单的总价

整理数据集记录的时间范围

import numpy as np # 导入NumPy print('日期范围: %s ~ %s' % (df_sales['消费日期'].min(), df_sales['消费日期'].max())) df_sales['消费日期'] = pd.to_datetime(df_sales['消费日期']) #转换日期格式 print('日期范围: %s ~ %s' % (df_sales['消费日期'].min(), df_sales['消费日期'].max())) 输出: 日期范围: 1/1/2021 10:11 ~ 9/9/2020 9:20 日期范围: 2020-06-01 09:09:00 ~ 2021-06-09 12:31:00 数据集中的时间跨度是2020-06-01到2021-06-09,我们想要的是一年的消费总额,所以剔除: df_sales=df_sales.loc[df_sales['消费日期'] < '2021-06-01'] print('日期范围: %s ~ %s' % (df_sales['消费日期'].min(), df_sales['消费日期'].max())) 输出: 日期范围: 2020-06-01 09:09:00 ~ 2021-05-31 17:37:00

构建特征和标签

构建特征

特征只需要前三个月的数据: df_sales_3m=df_sales[(df_sales.消费日期 > '2020-06-01')&(df_sales.消费日期 <= '2020-08-30')] df_sales_3m.reset_index(drop=True) 特征提取: df_user_LTV = pd.DataFrame(df_sales['用户码'].unique()) #生成以用户码为主键的结构 df_user_LTV.columns=['用户码'] #设定字段名 df_user_LTV.head() df_R_value=df_sales_3m.groupby('用户码').消费日期.max().reset_index() #找到每个用户的最近消费日期,构建df_R_value对象 df_R_value.columns=['用户码','最近购买日期'] df_R_value['R值']=(df_R_value['最近购买日期'].max()-df_R_value['最近购买日期']).dt.days #计算最近日期与上次消费日期的天数 df_user_LTV=pd.merge(df_user_LTV,df_R_value[['用户码','R值']],on='用户码') #把上次消费距最新日期的天数(R值)合并至df_user_LTV df_F_value=df_sales_3m.groupby('用户码').消费日期.count().reset_index() df_F_value.columns=['用户码','F值'] df_user_LTV=pd.merge(df_user_LTV,df_F_value[['用户码','F值']],on='用户码') df_M_value=df_sales_3m.groupby('用户码').总价.sum().reset_index() df_M_value.columns=['用户码','M值'] df_user_LTV = pd.merge(df_user_LTV, df_M_value, on='用户码') #把消费总额整合至df_user结构 df_user_LTV #显示用户表结构

image.png

构建标签

df_user_ly=df_sales.groupby('用户码')['总价'].sum().reset_index() #计算每个用户整年消费总额,构建df_user_ly df_user_ly.columns=['用户码','年度LTV'] df_user_ly.head() df_LTV=pd.merge(df_user_LTV,df_user_ly,how='left') df_LTV

image.png

创建特征集和标签集

创建特征集

X=df_LTV.drop(['用户码','年度LTV'],axis=1) #特征集 X.head() image.png

创建标签集

y=df_LTV['年度LTV'] y.head()

image.png

拆分训练集、验证集和测试集

``` from sklearn.model_selection import train_test_split

先拆分训练集和其它集

X_train,X_rem,y_train,y_rem=train_test_split(X,y,train_size=0.7,random_state=36)

再把其它集拆分成验证集和测试集

X_valid,X_test,y_valid,y_test=train_test_split(X_rem,y_rem,test_size=0.5,random_state=36) ```

选择算法创建模型

image.png

课程中使用最基本的线性回归模型、决策树模型和随机森林模型。

  • 线性回归:通过梯度下降找到最优的权重和模型偏置的最基本的回归算法。里,我会用它作为一个基准模型,把其它模型的结果与其相比较,来确定优劣。
  • 决策树算法:简单地说是从样本数据的特征属性中,通过学习简单的决策规则,也就是我们耳熟能详的IF ELSE规则,来预测目标变量的值。这个算法的核心是划分点的选择和输出值的确定。

image.png 可以看到,这种算法是根据两个特征x1和x2的值,以及标签y的取值,对二维平面上的区域进行精准分割,以确定从特征到标签的映射规则。根据树的深度和分叉时所选择的特征的不同,我们可以训练出很多颗不一样的树来。

  • 随机森林:就是由多棵决策树构成的集成学习算法。它既能用于分类问题,也能用于回归问题。而且无论是哪类问题,它都是相对优秀的算法。在训练模型的过程中,随机森林会构建多个决策树,如果解决的是分类问题,那么它的输出类别是由个别树输出的类别的众数而定;如果解决的是回归问题,那么它会对多棵树的预测结果进行平均。随机森林纠正了决策树过度拟合其训练集的问题,在很多情况下它都能有不错的表现。这里的“过拟合”,其实就是说模型对训练集的模拟过头了,反而不太适合验证集和测试集。

from sklearn.linear_model import LinearRegression #导入线性回归模型 from sklearn.tree import DecisionTreeRegressor #导入决策树回归模型 from sklearn.ensemble import RandomForestRegressor #导入随机森林回归模型 model_lr=LinearRegression() #创建线性回归模型 model_dtr=DecisionTreeRegressor() # 创建决策树回归模型 model_rfr=RandomForestRegressor() #创建随机森林回归模型

训练模型

model_lr.fit(X_train,y_train) # 拟合线性回归模型 model_dtr.fit(X_train,y_train) # 拟合决策树模型 model_rfr.fit(X_train,y_train) # 拟合随机森林模型

评估模型

X_valid.iloc[2] # 随便选择一个数据 输出: R值 1.00 F值 154.00 M值 1427.73 Name: 163, dtype: float64

print('真值:', y_valid.iloc[2]) #线性回归模型预测值 print('线性回归预测值:', y_valid_preds_lr[2]) #线性回归模型预测值 print('决策树预测值:', y_valid_preds_dtr[2]) #决策树模型预测值 print('随机森林预测值:', y_valid_preds_rfr[2]) #随机森林模型预测值 输出: 真值: 4432.43 线性回归预测值: 7474.4181424883545 决策树预测值: 4074.57 随机森林预测值: 4282.643300000004 我们还要用$R2$、MSE等评估指标在验证集上做整体评估,选使用$R2$: from sklearn.metrics import r2_score,mean_absolute_error print('验证集上的R平方-线性回归:%0.4f' % r2_score(y_valid,model_lr.predict(X_valid))) print('验证集上的R平方分数-决策树: %0.4f' % r2_score(y_valid, model_dtr.predict(X_valid))) print('验证集上的R平方分数-随机森林: %0.4f' % r2_score(y_valid, model_rfr.predict(X_valid))) 输出: 验证集上的R平方-线性回归:0.4410 验证集上的R平方分数-决策树: 0.1209 验证集上的R平方分数-随机森林: 0.4538 可以看出随机森林树预测能力好点。

但是0.4几说明拟合的其实不咋样。 import matplotlib.pyplot as plt #导入Matplotlib的pyplot模块 y_test_preds_rfr = model_rfr.predict(X_test) #用模型预随机森林模型预测验证集 plt.scatter(y_test, y_test_preds_rfr) #预测值和实际值的散点图 plt.plot([0, max(y_test)], [0, max(y_test_preds_rfr)], color='gray', lw=1, linestyle='--') #绘图 plt.xlabel('实际值') #X轴 plt.ylabel('预测值') #Y轴 plt.title('实际值 vs. 预测值') #标题

image.png

参考/来源

客户生命周期价值

07|回归分析:怎样用模型预测用户的生命周期价值?