流失客户预测

从事了多年文员的工作,终于晋升为大妈级文员了。一边尖着耳朵听着会议室里乙方虐客户,一边盯着一大堆需要复制粘贴的材料。真恨不得冲进去拿着白板笔写写画画讲起来。然而那是不可能的,于是只有压抑住内心的汹涌澎湃,一面面无表情的平静无辜滴看着毫无意义的材料。

算了,就来给客户科普下数据分析项目吧。

首先肯定是确定业务需求,业务需求都没搞清楚,难怪要被虐。偷听到貌似业务需求是要有一大堆合约到期了,那么不续约,就流失了,续约,就留住了。然而资源有限,到底要把资源用来保住哪些客户呢?所以目前业务需求有2个:1、哪些客户是高风险不续约的,把这群人找出来重点保留,其中优质客户特别要重点保留。2、流失客户的特征是什么?把那些容易流失的客户的特征找出来。提一个傻白甜又没有工作量的解决方案。用过去的数据建立模型,对目前合约要结束的客户是否续约进行预测,如果预测为流失,则再分级,对于优质的重点保留,贡献小的流失就流失了吧。再使用EDA的方法以及建模的方法,对过去的数据进行分析,看哪些业务没做的好,导致客户流失。

于是到了第二阶段:数据采样。到底采用哪些样本,才能体现目前业务主要客户群体,并且没有异常状况,数据比较稳定,能代表大众,然后把涉及到客观原因流失的数据剔除

采样之后,就到了特征阶段。先从业务层面上理解选取哪些特征,1、客户的静态数据(比如年龄啊,工作啊,学历啊,收入啊),2、客户的行为数据(比如投诉啊,平均每个月消费啊.....),3、产品数据(比如套餐啊,价格啊.....),4、脑子里面想出来的其他数据,反正就是想流失的影响因素是么子。

然后就进入EDA以及建模阶段了,就不啰嗦了,很多博客都讲烂了,而大妈级文员的博客,必须与众不同。

好了,举了个栗子说明。

这是USA的运营商客户流失预测的真实数据,AUC算出来0.92,高吧,就不啰嗦了,直接上代码!

import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
import seaborn as sns
os.chdir('F:/预测与分析数据集/Data sets')
data=pd.read_csv('churn.txt')
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']

#对数据集进行简单的处理
data.head()
data.rename({'Churn?':'Churn'},axis=1,inplace=True)
data['Churn']=data['Churn'].map(lambda x:0 if x=='False.' else 1)
data['Churn'].value_counts()
data.drop(['Area Code','Phone'],axis=1,inplace=True)
data.isnull().sum()
data.describe()
data.describe(include=[np.object])

#EDA过程
#数值型变量举例:VMail Message举例
_,bins,_=plt.hist(data['VMail Message'])
plt.xlabel('VMail Message')
plt.ylabel('Number')
plt.title('语音条数分布直方图')
len(data.loc[(data['VMail Message']==0)&(data['Churn']==1),:])/len(data.loc[(data['VMail Message']==0),:])
len(data.loc[(data['VMail Message']>0)&(data['Churn']==1),:])/len(data.loc[(data['VMail Message']>0),:])
plt.hist(data.loc[data['Churn']==0,'VMail Message'],color='blue',alpha=0.5,label='未流失客户')
plt.hist(data.loc[data['Churn']==1,'VMail Message'],color='red',alpha=0.5,label='流失客户')
plt.legend()
bins=list(bins)
V_G=pd.cut(data['VMail Message'],bins=bins)
data['V_G']=V_G
V_G_data=data.groupby(['V_G','Churn'])['State'].count().unstack(level=1).reset_index().rename({'V_G':'VMessage',0:'未流失',1:'流失'},axis=1)
V_G_data['比例']=V_G_data['流失']/(V_G_data['流失']+V_G_data['未流失'])
import pylab as pl
pl.xticks(rotation=90)
sns.barplot(x='VMessage',y='比例',data=V_G_data)
#名义变量举例:Int'l Plan举例
data['Int\'l Plan'].value_counts()
#列联表分析
IntPlan_data=data.groupby(['Int\'l Plan','Churn'])['State'].count().unstack(level=1).reset_index().rename({0:'未流失',1:'流失'},axis=1).drop(['Churn'],axis=1)
IntPlan_data['比例']=IntPlan_data['流失']/(IntPlan_data['流失']+IntPlan_data['未流失'])
#卡方检验
from scipy.stats import chi2_contingency
_,p,_,_=chi2_contingency([[2664,346],[186,137]])


# ligthGBM建立模型
data_new=data.drop(['State','Account Length','V_G'],axis=1)
data_new=pd.get_dummies(data_new,columns=['Int\'l Plan','VMail Plan'],drop_first=True)
import lightgbm as gbm
from sklearn.model_selection import KFold
from sklearn.metrics import roc_auc_score
folds=KFold(n_splits=8,shuffle=True,random_state=42)
oof=np.zeros(len(data_new))
X=data_new.drop('Churn',axis=1).values
y=data_new['Churn'].values
importance=pd.DataFrame({})
params={'learning_rate':0.01,'num_leaves':10,'max_depth':20,'bagging_fraction':0.8,'bagging_freq':10,'feature_fraction':1,
        'lambda_l1':0.001,'lambda_l2':0.001,'metric':'auc','objective': 'binary'}
for _,(trn,val) in enumerate(folds.split(X,y)):
    trn_data=gbm.Dataset(X[trn],y[trn])
    val_data=gbm.Dataset(X[val],y[val])
    gbm_train=gbm.train(params=params,train_set=trn_data,num_boost_round=20000,valid_sets=[trn_data,val_data],
                        early_stopping_rounds=200)
    oof[val]=oof[val]=gbm_train.predict(X[val],num_iteration=gbm_train.best_iteration)
    f_importance=pd.DataFrame({'Name':gbm_train.feature_name(),'importance':gbm_train.feature_importance()})
    importance=pd.concat([importance,f_importance],axis=0)
    
importance=importance.groupby('Name')['importance'].mean().reset_index()
oof_r=np.where(oof>0.5,1,0)
roc_auc_score(oof_r,y)

 

 

你可能感兴趣的:(流失客户预测)