导读: 大家好,我是云朵君,最近有很多小伙伴留言说,想要我分享一些数据挖掘实战案例。今天就来给大家分享一个这么一个项目。本次数据挖掘主要目的是理清楚数据挖掘的一般过程与基本方法,并没有进行太过复杂的挖掘分析,或许会存在很多分析不够深入的情况,欢迎各位大佬交流讨论。文章较长,建议收藏转发阅读。
app客户流失及客户行为偏好分析(仅供参考) 20**年*月 - 20**年*月 分类信息app,通过数据挖掘分析影响用户流失的关键因素、深入了解用户行为偏好以此做出调整,提升客户留存率,增强客户黏性,并通过随机森林算法预测客户流失,通过特征创造使模型分数提高2个百分点。 项目内容:
使用工具: python、pandas、numpy、matplotlib、seaborn、sklearn库
在做一个数据挖掘项目前,需要预先拟好主要思路,比如目标是什么,先做什么,再做什么,有哪些注意事项等等。
本次案例内容,包括数据、代码均可在公众号「数据STUDIO」后台回复【210514】获取!
深入了解用户画像及行为偏好,挖掘出影响用户流失的关键因素,并通过算法预测客户访问的转化结果,从而更好地完善产品设计、提升用户体验!
此次数据是携程用户一周的访问数据,为保护客户隐私,已经将数据经过了脱敏,和实际商品的订单量、浏览量、转化率等有一些差距,不影响问题的可解性。
本次项目主要从三个方面来分析,客户流失、客户转化和客户价值。
目标变量label表示是否流失,是0-1二分类问题,目的是需要挖掘出关键因素,拟选用逻辑回归做模型训练及预测。
预测客户转化率,是连续型变量预测问题,拟选择集成数模型--随机森林回归。
为了更加细致的挖掘客户价值,选择RFM客户价值模型进行分析。
缺失值可视化两种思路,定性化和定量化两个思路。直接定性观察整体缺失情况,即用第三方模块missingno
绘制矩阵图,下图中白色部分为缺失值。
import missingno as msno
msno.matrix(data)
另一个是定量化分析,即计算每个字段的缺失值比例,通过核密度估计图绘制缺失值分布图。
右下图可见缺失值分布是双峰分布,第一高峰在0左右,表明大部分数据是完整的或仅存在少部分缺失。第二高峰在30%~40%左右,因此对于缺失值的处理,需要根据不同缺失情况定制不同的缺失值处理方案。
import seaborn as sns
sns.kdeplot(null['缺失比'],shade=True)
经过一系列探索分析,本次数据有以下特点:
数据清洗主要包括去除重复值、处理缺失值、处理异常值、⽣成衍生变量等操作。其中处理顺序根据实际处理过程涉及的问题而定,这里的顺序仅供参考。
对于一般模型影响不大,但对于回归模型⽽言,容易导致回归系数标准误降低,使得对应p值减⼩。重复值过多,样本随机误差降低,造成参数的贡献程度会被高估。本案例没有重复值,可以略过。
首先处理异常值,最低酒店定价有小于0的,有等于1的值,明显属于异常值。异常值处理方法较多,常见有直接删除,当缺失值处理等等,本例中,我们用盖帽法处理此异常值。
# 定义盖帽法函数
def block_lower(x):
# x是输⼊入的Series对象,替换1%分位数
ql = x.quantile(.01)
out = x.mask(x<ql,ql)
return(out)
def block_upper(x):
# x是输⼊入的Series对象,l替换99%分位数
qu = x.quantile(.99)
out = x.mask(x>qu,qu)
return(out)
lowestprice
: 当前酒店可定最低价lowestprice_pre
: 24小时内已访问次数最多酒店可订最低价
可以参见缺失值处理,本次案例缺失值填补方案。
众数填补
中值填补
中值填补
常数 -1 填充
单独做一类均值填补
直接删除
变量本次选用简单粗暴的方差过滤、F_检验、 以及嵌入法特征选择,利用树模型的特征重要性输出结合模型效果,选择对模型贡献最大的那个几个变量。事实证明,此方法效果明显,最后成功选择出8个特征。
方法 | 说明 |
---|---|
方差过滤 | 方差等于0 的直接过滤,结果无过滤特征 |
F_检验 | 过滤没有相关性的变量。pvalues_f < 0.01 直接过滤,过滤掉6个特征 |
嵌入法特征选择 | 经过选择,等到贡献最大的8个特征 |
利用随机森林特征重要性属性feature_importances_
定义阈值范围,以嵌入选择模型SelectFromModel
为基础,通过交叉验证cross_val_score
得到每个阈值下模型得分情况。
绘制得到学习曲线如下图所示,在阈值为0.0295956
时,模型精确度得分最高--
# 主要代码
X_embedded = SelectFromModel(RFC_clf,
threshold=i).fit_transform(Xtrain,Ytrain)
val = cross_val_score(RFC_clf,
X_embedded,
Ytrain,cv=5).mean()
score.append(val)
热图用于特征间的相关性分析,通过绘制热图,分析发现有以下两个高度相关的变量,最终删除特征cityuvs
。
cityuvs
:昨日访问当前城市同入住日期的app uv数cityorders
昨日提交当前城市同入住日期的app订单数
sns.heatmap(Xtrain_new.corr(),
annot=True,linewidths=1)
经过数据预处理及特征选择后,最终得到如下数据:
客户流失预测模型的实现方法属于分类算法,常用算法包括逻辑回归、支持向量机、随机森林等。这里总结了下模型选择的一些参考,见文末附录。
大部分情况下,流失客户的样本分类是少数类,需要注意处理样本不均衡问题。
经过数据预处理后,我们决定利用逻辑回归了解用户画像及行为偏好,挖掘出影响用户流失的关键因素,并辅以随机森林分类器进行预测客户流失。
需要知道关键因素,要求模型需要有很好的可解释性,因此选用逻辑回归模型。但从模型评价结果(ROC曲线面积)来看,逻辑回归并不是很理想。
若需要同时追求模型预测精确度,则选取集成模型或其他强学习模型。这里选用大家熟知的随机森林分类器。
在将数据用于模型训练之前,需要先对变量进行深入分析。分析变量间是否存在高度相关性,连续性变量是否需要离散化,离散变量是否需要编码等等。
ax = plt.figure(figsize=(8,15))
for i in range(len(train_data.columns[:-1])):
ax.add_subplot(8,1,i+1)
sns.kdeplot(train_data.iloc[:,i],shade=True)
plt.title(l_[i])
plt.tight_layout();
不难发现,除访问时间点外,特征均成右偏分布。因此将连续型、分类型变量做分箱处理,此处我们选用WEO分箱处理。
WOE(Weight of Evidence) 好样本比坏样本的比例的对数。 WOE编码: 追求组间差异大、组内差异小、必须要有好坏两种分类。
为什么要引⼊分箱
分箱的本质,其实就是离散化连续变量。
分箱的要求
分箱的个数: 5个以内,5-7个比较合适
分箱优缺点:
常⽤的分箱⽅法
我们总结出一个特征进行分箱的步骤:
这些步骤都完成后,我们可以对各个特征都进行分箱,然后观察每个特征的IV值,以此来挑选特征。下⾯我们就对每个x生成⼀个对象、记录IV值、生成WOE图。此处代码需要运⾏⾃定义函数所在⽂件,若有需要,可关注「数据STUDIO」并回复【210514】获取哦!每个x变量运行结果如下。
计算每个变量的IV值,并排序后绘制条形图。通过对比分析并去掉IV值最小,即对模型基本没有贡献的两个特征——sid
, lastpvgap
。
以计算用户转化率为例,进行WOE分箱并计算对应的IV值。通过分析得到如下结论。
用户转化率在小于1.14%
时用户留存较多。随着用户转化率增大时,流失用户流失增大,但注意在大于1.925%
往上,客户留存在变多。
一年内距上次下单时长在(2.5,1327)区间内转化结果最差,随着时间延长,流失风险降低,需要关注两次下单时间间隔较长的用户。
访问时间点在上午时,客户留存效果并不好,在晚上7点后访问的客户,流失率少,且随着时间点推移,留存在明显增大,在凌晨时仍存在留存客户优势。
昨日提交当前城市同入住app订单数在第5箱(2.25,2.294)区间内留存结果最好。
除第5箱外,客户留存结果随着订单数增加而逐渐降低,在大于0.37时,留存客户少于流失客户,客户流失风险较大。
年访问次数在61650前期有较小的浮动,在大于61650时出现高峰 。只有访问次数高到一定程度时(超过15000),该特征才能较明显的客户留存。
得到每个变量的WOE值,将所有特征值换成对应的WOE值。
特征工程完毕后建立逻辑回归模型,并利用召回率,假正率,ROC曲线评估模型。
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression().fit(X_train,Y_train)
并计算各特征系数与截距:
并计算在训练集和测试集分数分别如下:
LR.score(X_train,Y_train) | LR.score(X_test,Y_test) | |
---|---|---|
score | 0.728283 | 0.726898 |
core metrics
+-------+----------+-----------+--------+-------+
| auc | accuracy | precision | recall | f1 |
+-------+----------+-----------+--------+-------+
| 0.675 | 0.727 | 0.741 | 0.951 | 0.833 |
+-------+----------+-----------+--------+-------+
from sklearn.metrics import auc,accuracy_score,recall_score,f1_score
y_score = LR.predict_proba(X_test) # 随机森林
fpr, tpr, thresholds = roc_curve(Y_test, y_score[:, 1])
roc_auc = auc(fpr, tpr)
def drawRoc(roc_auc,fpr,tpr):
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
drawRoc(roc_auc, fpr, tpr)
我们发现逻辑回归ROC较低,我们试图从特征角度上来改进模型。
M = ordernum_oneyear * avgprice ordernum_oneyear 用户年订单数 avgprice 平均价格
我们将平均价格和年订单量相乘得到年消费,发现客户年消费越多,流失越多。
将生产的衍射变量进行WOE分箱。
d : 访问日期 arrival :入住日期
此时想到一开始我们之间将日期时间删除处理,现在将其处理后带入模型看看什么效果。
用入住日期减去访问日期得到间隔日期delta,发现客户在入住前很早就访问,留存率会很大。
将生产的衍射变量进行WOE分箱。
建立逻辑回归
并计算各特征系数与截距:
评估逻辑回归
计算在训练集和测试集分数分别如下:
LR.score(X_train,Y_train) | LR.score(X_test,Y_test) | |
---|---|---|
score | 0.732319 | 0.731017 |
core metrics
+--------+----------+-----------+--------+-------+
| auc | accuracy | precision | recall | f1 |
+--------+----------+-----------+--------+-------+
| 0.6895 | 0.731 | 0.745 | 0.949 | 0.835 |
+--------+----------+-----------+--------+-------+
经生成两个衍生变量后,逻辑回归模型ROC得分提高2个百分点。
随机森林分类器目的是辅助预测客户流失,因此利用清洗好的数据直接利用网格搜索进行调参数:
n_estimators = range(10, 201, 10) max_depth= range(3, 21,1) min_samples_split= range(2, 22, 1) min_samples_leaf = range(1, 12, 1) n_estimators = range(10, 201, 10)
得到最佳参数组合为
model = RFC(n_estimators=180
,max_depth=20
,min_samples_leaf=1
,min_samples_split=2
,random_state=0)
最后随机森林分类器在保证未出现过拟合的情况下,ROC曲线面积达到0.97
。
接下来,为了进一步挖掘客户价值,提升用户体验,我们运用了RFM客户价值模型。
根据客户价值模型,我们定义一年内距离上次下单时长为R
,年订单量为F
,平均价格为M
。
客户价值度用来评估用户的价值情况,是区分客户价值的重要模型和参考依据,也是衡量不同营销效果的关键指标之一。价值度模型一般基于交易行为产生,衡量的是有实体转化价值的行为。 RFM模型是根据客户最近一次购买时间R(Recency)、购买频率 F(Frequency)、购买金额M(Monetary)计算得出RFM得分,通过这 三个维度来评估客户的订单活跃价值,常用来做客户分群或价值区分。 RFM模型基于一个固定时间点来做模型分析,因此今天做的RFM得分跟7天前做的结果可能不一样,原因是每个客户在不同的时间节点所得到的数据不同。
得到 RFM 得分后的思路
在特征选择方面,我们在之前的特征基础上添加了一些我们认为与客户价值有关的变量。对特征进行缺失值分析得到:
同样对数据进行深入探索,因为本次价值模型无需划分测试集和训练集,又数据量足够多,因此我们直接将有缺失值的记录删除。
以客户转化率做目标变量,利用随机森林回归模型计算出各价值指标权重,然后分布计算出每个用户的RFM得分,分别以权重加和,及标签组合来表示价值得分。本次RFM模型构建方法仅供参考!
另外,为了体现流失客户及留存客户优势比,参照最优分箱公式,创造了一个类别,以-1表示。其计算方法是:
第一步:以RFM分群和标签聚合,分别对客户id
计数,以及RFM得分求和
groupby(['rfm\_group','label'])
第二步:对留存和流失客户求差。就是用不同类别的个数总和求差,乘以 RFM得分总和求差取对数
groupby(['rfm\_group','label'])
当然,这里是我参数优势比的原理创造的计算公式,其实用价值及是否合理,还需跟业务结合。这里仅作参考。
number(-1) = (number_0 -number_1)\*log(sum(rfm_score)_0/sum(rfm_score)_1)
标签 0 是留存用户,标签 1 是流失用户,标签 -1 是留存减流失乘以优势比。
# 显示图形
bar3d = Bar3D("", width=900, height=600)
range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf',
'#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
bar3d.add(
"rfm分组结果", "", "",
[d.tolist() for d in data_display.values],
is_visualmap=True,
visual_range=[0, data_display['number'].max()],
visual_range_color=range_color,
grid3d_width=200,
grid3d_height=80,
grid3d_depth=80
)
bar3d
我们可以看到在以R
就是一年内距离上次下单时长为轴,其两端留存和流失客户均很多,且 R
等于 1 就是距离时间越久,客户流失就越少,与我们用WOE分箱分析结果一致。
由上面分析报告可知,影响客户流失的两大因素:
因此我们以客户转化率为目标标签,进行进一步预测分析。
数据处理特征创造等类同于前面步骤,在这里就不赘述了。
在缺失值处理方面不同的是,我们直接将 cr
缺失的记录直接删除了,这样处理的原因是,一是剩余数据量较多,足够随机森林预测。二是随机森林以后实用袋外数据进行模型评估。
以连续特征 cr
客户转化率作为目标标签,利用随机森林回归器输出特征重要性来选择出使得模型分数最高的那几个特征。本次选择出了13个对模型贡献度较大特征。
我可以看到排名第一的仍然是一年内距离上次下单时间对用户转化率的影响最高。
相比对客户流失影响的特征,多了历史订单数,历史取消订单数及星级偏好,客户价值
等。
运用网格搜索方法对随机森林分类器进行调参,得到最佳参数:(这里注意调参时间较长,小伙伴们可以尝试运用贝叶斯优化调参方法)
model = RFR(n_estimators=180
,max_depth=25
,min_samples_leaf=1
,min_samples_split=2
,random_state=0
)
因此得到该模型,在测试集预测得分92.26%
。最后可以保存模型以供模型部署使用。
我们使用了逻辑回归模型和客户价值模型对客户流失进行深入挖掘,找出了影响客户流失的关键因素:
用户转化率
——用户转化率大时,流失用户占比反而在逐渐增大。
一年内距上次下单时长
——一年内距上次下单时长在(2.5,1327)区间内最容易流失,但时间越久的,约容易留存。
访问时间点
——白天访问转化率低,晚上7点后访问客户更易转化。
昨日提交当前城市同入住app 订单数
—— 订单数越大,客户流失风险越大, 但在(2.25,2.294)区间内转化结果最好。
创造的特征M,delta
M客户年花费
越大,流失风险越大。delta
随着访问日期与入住日期距离越近,客户更易流失,也就是没怎么访问就入住的酒店,相比而言,在入住之前就有关注酒店的客户,黏性就越大。我们总结出易流失人群和留存客户人群特征,对客户进行一个简单的画像。针对易流失人群,推荐具体业务可以从三个维度将本次分析结果落地。
易留存人群特征 一年内距上次下单时长在(1,1.075)区间 用户转化率在( 1,1.075 )区间 访问时间在晚上 订单数在2.294以下 年访问次数超过15003 年消费越小 入住日期与访问日期间隔越长
易流失人群特征 一年内距上次下单时长在(2.5,1327)区间 用户转化率在(1.505,1.925)区间 访问时间在上午 App订单数在2.61以上 年访问次数在小于15000 年消费越大 入住日期与访问日期间隔越短
本文分享自 Python数据分析实例 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!