通过客户流失预测案例感悟数据分析设计方法思考——数据驱动、AI驱动

国际著名的咨询公司Gartner在2013年总结出了一套数据分析的框架,数据分析的四个层次:描述性分析、诊断性分析、预测性分析、处方性分析。

Gartner于2020年中给出预测,到2024年底,75%的企业机构将从AI试点转为AI运营。同期,Gartner发布了数据与分析领域的十大技术趋势,首先映入眼帘的是:更智能、更高速、更负责的AI,也指出了仪表板的衰落,更青睐上层次和实用化的决策智能。

1. 前言

我们在设计数据分析产品和数据可视化的时候,依据是什么?怎样设计数据分析产品才能给用户更多的业务支撑?我们做趋势预测、精准识别目的是什么?

最近,我有些感悟分享与读者探讨、研究。

对于设计数据分析产品和数据可视化,我们首先想到的是需求,然后是业务机理。但是,在大数据、新一代人工智能高速发展的今天,对比Gartner给出数据分析咨询意见,我们不应拘泥于当前的业务场景,业务创新也可以通过新技术引领。

我们回到数据分析产品和数据可视化设计,除了需求和业务机理以外,我们不妨以金字塔思维模型来构建这样的场景。

一、目的
我们的目的是实现经济发展和利润,解决未来或当下的问题。比如新零售业务核心是围绕客户展开,解决客户发展和流速问题,是企业发展和利润的基石。

二、分析需求和识别待解决问题
分析需求是深入业务机理,重塑业务模型,以发展的眼光识别问题,解决问题。仍以新零售客户发展为例,客户流失是难以解决的问题,要解决客户流失问题,需要我们重塑客户全生命周期管理模型,识别问题机理和影响因素。

三、以预设或假设结论先行
我们以需求和待解决问题为基准,经过理论联系实际,设定解决问题目标。如果仍以客户流失问题为基准,并按公司现状和发展,我们设定客户流失率控制目标是20%,挽回率为70%,预测准确度为80%等。

为此,我们先借鉴国际Kaggle大赛电信客户流失题目为例,其数据为“WA_Fn-UseC_-Telco-Customer-Churn”,参照推演结论。

四、以上统下,逐层展开
我们有了结论目标,接着就是落地证明结论,分层分类展开。比如仍以客户流失问题为例,先通观全局,我们已经能做到预测客户流失,预测客户流失为26.54%,预测模型准确率达到80%。我们据此分类展开模型的影响因素分析,这也是数据分析、数据可视化内容。例如根据模型重要影响因素和相关性,给出个人特征、行为特征、服务特征三大类。

分层子观点如下:
1、以动态规划优化策略,通过优惠券方式降低流失客户的客户单价,实现减少流失客户;
2、以客户生命周期的时间序列预测客户流失预警;
3、流失客户的月消费金额(客单价)、在网时长等因素对客户流失影响较大。


五、给出解决措施,逐层分解,体现数据分析更智能。

2. 电信客户流失案例

2.1. 背景

电信行业关于用户留存有这样一个观点[2],如果将用户流失率降低5%,公司利润将提升25%-85%。如今,高居不下的获客成本让电信运营商遭遇“天花板”,甚至陷入获客难的窘境。随着市场饱和度上升,电信运营商亟待解决增加用户黏性,延长用户生命周期的问题。因此,电信用户流失分析与预测至关重要。因此做好“用户流失预测分析”可以:

1、降低营销成本。业界通用经验,“新客户开发成本”是“老客户维护成本”的5倍。
2、获得更好的用户体验。并不是所有的增值服务都可以有效留住客户。
3、获得更高的销售回报。可以识别价格敏感型客户和非价格敏感性客户。

2.2. 客户数据集及其流失预测分析

2.2.1. 数据集

字段名称 说明 数据解释
customerID 用户ID
gender 性别 Female & Male
SeniorCitizen 老年人 1表示是,0表示不是
Partner 是否有配偶 Yes or No
Dependents 是否经济独立 Yes or No
tenure 客户已使用月份数 0-72月,0为新开户
PhoneService 是否开通电话服务业务 Yes or No
MultipleLines 是否开通了多线业务 Yes 、No or No phoneservice
InternetService 是否开通互联网服务 No, DSL数字网络,fiber optic光纤网络
OnlineSecurity 是否开通网络安全服务 Yes,No,No internetserive
OnlineBackup 是否开通在线备份业务 Yes,No,No internetserive
DeviceProtection 是否开通了设备保护业务 Yes,No,No internetserive
TechSupport 是否开通了技术支持服务 Yes,No,No internetserive
StreamingTV 是否开通网络电视 Yes,No,No internetserive
StreamingMovies 是否开通网络电影 Yes,No,No internetserive
Contract 签订合同方式 按月,一年,两年
PaperlessBilling 是否开通电子账单 Yes or No
PaymentMethod 付款方式 bank transfer,credit card,electronic check,mailed check
MonthlyCharges 月费用
TotalCharges 总费用
Churn 该用户是否流失 Yes or No

2.2.2. 数据预处理与特征提取

1、数据缺失处理

经过观察,发现这11个用户‘tenure’(入网时长)为0个月,推测是当月新入网用户。根据一般经验,用户即使在注册的当月流失,也需缴纳当月费用。因此将这11个用户入网时长改为1,将总消费额填充为月消费额,符合实际情况。

        #'TotalCharges'存在缺失值,强制转换为数字,不可转换的变为NaN
        self.CData['TotalCharges']=pd.to_numeric(self.CData['TotalCharges'], errors='coerce') #astype('float64')
        #将总消费额填充为月消费额
        self.CData['TotalCharges'] = self.CData[['TotalCharges']].apply(lambda x: x.fillna(self.CData['MonthlyCharges']),axis=0)
        #查看是否替换成功
        print(self.CData[self.CData['tenure']==0][['tenure','MonthlyCharges','TotalCharges']])

2、特征编码与特征增维

观察数据类型,除了“tenure”、“MonthlyCharges”、“TotalCharges”是连续特征外,其它都是离散特征。

  • 对于连续特征,采用标准化方式处理;
  • 对于离散特征,特征之间没有大小关系,采用one-hot编码;
  • 对于离散特征,特征之间有大小关联,则采用数值映射,例如这的Yes与No,隐含有和无,既0与1的关系。

Pandas技术方案:

  • pd.get_dummies()就是把离散字符或者其他类型编码变成一串数字向量(纵向转为横向的数据列),也就是所谓的one-hot编码,数据增维。
  • pd.factorize()就是把离散字符或者其他类型编码变成一列连续数字,通常转变为0、1,或者,连续有一定意义的。
        Cols = [c for c in self.CData.columns if self.CData[c].dtype == 'object' or c == 'SeniorCitizen']
        Cols.remove('Churn')      
        # 对于离散特征,特征之间没有大小关系,采用one-hot编码;特征之间有大小关联,则采用数值映射。
        for col in Cols:
            if self.CData[col].nunique() == 2:
                self.CData[col] = pd.factorize(self.CData[col])[0]
            else:
                self.CData = pd.get_dummies(self.CData, columns=[col])        
        
        self.CData['Churn']=self.CData['Churn'].map({
   
   'Yes':1,'No':0})

2.2.3. 影响流失特征重要程度排序

数据集原始特征为21个,在特征离散化及升维达到40个特征,通过随机森林算法拟合客户流失,找出特征排序,实现代码参考引用[3]详细说明。
在这里插入图片描述
对排序结果数值进行分析,获得重要前六项特征,以及考虑可以舍弃的特征,例如:PhoneService、StreamingTV等。
在这里插入图片描述


2.2.4. 与客户流失相关特征分析

数据集原始特征为21个,在特征离散化及升维达到40个特征,通过皮尔森相关系数方法,找出能帮助理解特征和响应变量之间关系的方法,该方法衡量的是变量之间的线性相关性(详细参加[3]说明)。
在这里插入图片描述
我们观察关系系数接近于0的特征,有的和前面特征重要程度存在一定的稳合,例如PhoneService、StreamingTV,与流失关系系数接近0。
在这里插入图片描述


2.2.5. 数据不平衡处理

由于预测识别客户流失属于二分类的问题,而且流失占比较少,形成分类样本不平衡问题,针对数据不平衡问题,采用欠采样的方式进行处理,使用机器学习库中的SMOTE。

pip install imblearn

        #from imblearn.over_sampling import SMOTE
        self.x_train,self.x_test, self.y_train, self.y_test = train_test_split(X,Y,test_size=0.3)        
        #利用SMOTE创造新的数据集 ,#初始化SMOTE 模型
        oversampler=SMOTE(random_state=0)
        #使用SMOTE模型,创造新的数据集
        os_features,os_labels=oversampler.fit_sample(self.x_train,self.y_train)
        #切分新生成的数据集
        os_features_train, os_features_test, os_labels_train, os_labels_test = train_test_split(os_features, os_labels, test_size=0.2) 
        self.x_train,self.x_test, self.y_train, self.y_test = os_features_train, os_features_test, os_labels_train, os_labels_test
        '''
        #看看新构造的oversample数据集中0,1分布情况
        #常用pandas的value_counts确认数据出现的频率
        os_count_classes = pd.value_counts(os_labels['Churn'], sort = True).sort_index()
        os_count_classes.plot(kind = 'bar')
        plt.title("Fraud class histogram")
        plt.xlabel("Class")
        plt.ylabel("Frequency")
        plt.show()
        '''

在这里插入图片描述
经过SMOTE欠采样处理后,样本数据集均衡。

基于均衡处理后的数据集进行预测,预测结果准确率由80%提升到87%(未做优化参数)。
在这里插入图片描述

如果,使用原分离出来的30%样本的做为测试集,则模型预测准确率没有得到明显提升,为什么?

2.2.6. 结论

根据以上分析,我们可以大致得到高流失率用户的特征:

  • 用户属性:老年,未婚、没有依赖关系;
  • 服务属性:开通光纤服务/光纤附加流媒体电视、电影服务;
  • 行为属性:在网时长小于一年,签订的合同期限较短,采用电子支票支付,使用电子账单,月消费金额约在70-110元之间;
  • 其它属性对用户流失影响较小。

2.3. 经验总结

2.3.1. 特征分类层次化

总结预测客户流失研究过程,我们将所有输入原始特征分成了三个类别:客户个人属性、客户行为属性,客户服务属性,如下图所示,分别对他们进行分析。
在这里插入图片描述

2.3.2. 特征离散化

离散化后的特征对异常数据有更强的鲁棒性,降低过拟合的风险,模型会更稳定,预测的效果也会更好。

例如“在网时长”特征,实际上的使用更多是表述时长的等级,我们参看如下数据分布直方图,可以几个级别,对比我们实际业务就是刚刚入网的客户,多年的老客户等等。
在这里插入图片描述

2.3.3. 离散特征 one-hot编码

我们经常遇到数据特征,是对某些特征进行归类管理,例如下图的“付款方式”,每种付款方式都是独立的,以是、否方式表示,而且有可能存在多种付款方式。对于这样的特征我们应该采用one-hot方式编码,相当于给数据集升维。
在这里插入图片描述
我们也经常遇到数据特征,是对数值数据使用的描述,而实际上是有数值大小意义的,例如图中“合同期限”,按月描述就是:按月对应1(个月)、按一年对应12(个月)、按两年对应24(个月),这样更适合表述特征含义。

2.3.4. 特征与指标

我们通过过程中的输出结果,逐步确立分析指标,设定参考标准。例如用户在网时长,根据前面的数据分布图,以及离散化策略,我们可以离散化出多个在网时长的区间,而且通常这样的分析方法效果更好,也方便对标。

对于one-hot类编码,往往是业务分类产生的,这也是产生指标的一个重要来源,而且可以根据重要程度而确立指标。

在这里插入图片描述

3. 根据预测结论设计数据分析产品

著名的咨询公司Gartner在2013年总结、提炼出了一套数据分析的框架,数据分析的四个层次:描述性分析、诊断性分析、预测性分析、处方性分析。

我们虽然凭经验直接给出处方分析是很难实现的,但是我们可以先从预测结论倒叙推理,自顶向下,根据预测结论及预测分析过程输出核心结果,形成以重要影响因素、经营管理考核指标(需求)、特征相关性为主的层次子结论,逐层分类展开数据分析产品设计。
在这里插入图片描述
数据分析研发过程原则:

  • 数据驱动、AI驱动,产品设计利用数据和AI技术
  • 产品设计界定研发边界
  • 研发边界和深度依赖资源并受资源限制
  • 提供模型可解释性
  • 研发过程遵循迭代循环

接下来,我们仍以客户流失为例,按上图,根据“探索性分析”的结果和结论,展开“产品设计”过程。下图是客户全生命周期,其中客户流失的拐点,流失预警期将是我们的重中之重。
在这里插入图片描述

3.1. 预测结论及分析(顶层)

我们所设计预测,是想提前知道未发生的事和预期结果对比。预测结果仍以数据描述方式表达,如果继续以客户流失预测为例,需要表达的内容如下:

1、客户流失率、流失数量、流失客户明细,预测流失与同期、上期、管理指标对标分析,包括同期比、环比。
在这里插入图片描述
客户流失造成月收入减少30.5%。

        plt.rcParams['figure.figsize']= 12,6 #6,6
        plt.subplot(1,2,1)
        plt.pie(self.df['Churn'].value_counts(),labels=self.df['Churn'].value_counts().index,autopct='%1.2f%%',explode=(0.1,0))
        plt.title('Churn(Yes/No) Ratio')
        plt.subplot(1,2,2)
        dd = self.df[['MonthlyCharges','TotalCharges','Churn']].groupby(['Churn'], as_index=False).sum()
        plt.pie(dd['MonthlyCharges'],labels=dd['Churn'],autopct='%1.2f%%',explode=(0.1,0))
        plt.title('Churn(Yes/No) MonthlyCharges')        
        plt.show()

2、流失客户带来的影响,流失客户所引起减少的(月)收入,需要打新多少新用户弥补及实现概率。

3、影响客户流失重要因素、相关因素,并给出优化措施建议。

我们依据客户流失集各个特征的重要程度,重点分析消费金额和在网时长。其实这些和我们实际经验比较接近,大多数客户最关心的就是钱,对价格比较敏感。

所以,我们的产品设计上,将倾向分析客户价格敏感情况,建立客户价格敏感画像,以及相关支撑服务。
在这里插入图片描述

3.2. 分析重要影响因素

我们依旧预测过程中重要因素、相关因素等输出,深入分析这些因素(为了简便说明,此处只是使用了XGBoost算法预测),例如:
在这里插入图片描述
如上图所示,位列三甲重要特征为月度消费金额、总消费金额、在网时长,与我们经验认知一致,流失很大原因就是差钱!

1、分类对比流失客户与未流失客户的月消费金额(客单价),分类对比流失客户与未流失客户的在网时长。

在这里插入图片描述

    def kdeAnalysis(self):
        plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
        plt.rcParams['axes.unicode_minus']=False 
        plt.figure(figsize=(18, 5))
        plt.subplot(1,3,1)
        kdeplot('MonthlyCharges','月度消费',self.df,'Churn')
        plt.subplot(1,3,2)
        kdeplot('TotalCharges','总消费额',self.df,'Churn')
        plt.subplot(1,3,3)
        kdeplot('tenure','在网时长',self.df,'Churn')
        plt.show()     
        
# Kernel density estimaton核密度估计
def kdeplot(feature,xlabel,data,tag='Churn'): 
    plt.title("KDE for {0}".format(feature))
    plt.yticks(fontsize=8)
    plt.xticks(fontsize=8)
    
    sns.set(font='SimHei') #, font_scale=0.8)        # 解决Seaborn中文显示问题
    sns.set_style({
   
   'font.sans-serif':['simhei', 'Arial']}) 
    ax0 = sns.kdeplot(data[data['Churn'] == 'No'][feature],  label= '未流失', shade='True',legend=True)
    ax1 = sns.kdeplot(data[data['Churn'] == 'Yes'][feature], label= '流失',shade='True',legend=True)
    plt.xlabel(xlabel)
    plt.rcParams.update({
   
   'font.size': 10})
    plt.legend(fontsize=10)

2、分析月消费金额、在网时长等重要特征的相关因素

在给定电信客户流失数据集中,各个特征独立性较强,如下图所示,没有必要深入分析其他特征的相关性。
在这里插入图片描述
3、选择影响重要因素分析

如下图所示,只分析重要影响因素,而对于类似“PhoneService”特征,影响靠后的可以略去,不予以分析。
在这里插入图片描述

    def serviceAnalysis(self):
        plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
        plt.rcParams['axes.unicode_minus']=False     
        sns.set(font='SimHei') #, font_scale=0.8)        # 解决Seaborn中文显示问题
        sns.set_style({
   
   'font.sans-serif':['simhei', 'Arial']}) 
        self.df['churn_rate'] = self.df['Churn'].replace("No", 0).replace("Yes", 1)
        items=['OnlineSecurity','OnlineBackup','DeviceProtection','TechSupport','InternetService', 'StreamingMovies']
        items_name=['安全服务','备份业务','保护业务','技术支持','互联网服务','网络电影']
        def get_order(items_index):
            if items_index == 4:
                return ['DSL','Fiber optic','No']
            else:
                return ['Yes','No','No internet service']
        fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(8,12))
        for i,item in enumerate(items):
            plt.subplot(2,3,(i+1))
            ax=sns.barplot(x=item,y='churn_rate',data=self.df,order=get_order(i))
            plt.rcParams.update({
   
   'font.size': 12})
            plt.xlabel(str(items_name[i]))
            plt.title(str(items_name[i])+'流失情况')
            i+=1        
        plt.show()    

3.2. 确立分析指标

如何确立分析指标呢?一般情况下,我们从两个方面考虑:一是业务原理和需求所规定的,属于刚需,也可能不合理,我们可以试探打破;二是数据驱动、AI驱动所逻辑推理给出的。

3.2.1. 基于业务机理提炼指标

例如客户指标:

  • 客单价:销售额/客户数,反映客户的质量、消费水平。
  • 件单价:销售额/销售量,反映客户的购买商品的平均单价;
  • 客单件:销售量/客户数,反映客户的购买力,购买多少商品的数量;
  • 连带率:销售量/成交单量,也叫作购物篮系数,连带率和人、场有关。
  • 新增会员数:新增会员数=期末会员数-期初会员总数
  • 会员增长率:会员增长率=某短时间新增会员数/期初有效会员数
  • 会员贡献率:会员贡献率=会员销售总额/总销售额
  • 有效会员占比: 有效会员占比=有效会员总数/累计会员总数
  • 会员流失率:会员流失率=某段时间内流失的会员数/期初有效会员总数
  • 会员活跃度: 会员活跃度=活跃会员数量/会员总量
  • 平均购买次数:平均购买次数=某个时间段内订单总数/会员总数
  • 会员平均年龄: 会员平均年龄=某个时间段店内会员年龄总和/有效会员总数

3.2.2. 数据驱动、AI驱动逻辑给出

1、数据增维,产生新的特征,例如新增“月平均消费”,月平均消费=总消费/在网时长,如下图所示,属于重要特征,我们可以建议设置为分析指标。
在这里插入图片描述
2、聚类,例如对流失客群分类,其实我们也不知道怎么分,那么可以先试探聚类算法看结果,初步来看是和平均消费额大小关系更为密切。
在这里插入图片描述


    def clusteringAnalysis(self):
        data = self.df[self.df['Churn']==1].reset_index(drop=True)#重设索引
        samples = data[['MonthlyCharges','TotalCharges','AverageChargs','tenure','Contract']]  
        #标准化
        scaler=StandardScaler()
        kmeans=MiniBatchKMeans(n_clusters=3,random_state=9,max_iter=100)
        pipeline=make_pipeline(scaler,kmeans)
        pipeline.fit(samples) #训练模型
        labels=pipeline.predict(samples)#预测 
        samples['labels'] = labels #合并数据集

强化学习构建聚类指标,通过奖励大,最终建立一个Q值表?

3、对现有特征数据项转化,例如one-hot编码所转换出来的,在预测模型中表现比较重要的离散数据项,也可能升格为分析指标。

3.3. 可视化

数据可视化,正如本文开始所说的,和数据分析的四个层次密切相关。数据可视化可以分为描述性分析、诊断性分析、预测性分析、处方性分析。

我们通常我看到的图表,主要是通俗化数学统计范畴的内容,大多数人都能看懂,其实,我们还需要专业化图表,为专业化服务。

4. 总结

通过客户流失预测案例感悟数据分析设计方法,正如Gartner于2020年给出数据分析领域的技术趋势,更智能、更高速、更负责的AI,凸显新技术引领业务,以站在高纬度上的预测结果为顶层设计,倒逼数据诊断分析、描述性分析,使业务数据分析线条更清晰,目的更明确。

对于数据分析工作岗位,其实可以分为两种:一种类似产品经理、一种偏向数据挖掘,类似产品经理向更加注重业务,对业务能力要求比较高;数据挖掘向更加注重技术,对算法代码能力要求比较高。

由于作者水平有限,欢迎交流讨论。

本文涉及代码详见:https://github.com/xiaoyw71/Feature-engineering-machine-learning

参考:

[1].《电信用户流失分析与预测》 知乎 ,南桥那人 ,2019年6月
[2].《Telco Customer Churn》 CSDN博客 , qqissweat ,2021年1月
[3].《大数据人工智能常用特征工程与数据预处理Python实践(2)》 CSDN博客 ,肖永威,2020年12月
[4].《oversample 过采样方法 SMOTE ——欠采样(undersampling)和过采样(oversampling)会对模型带来怎样的影响》 CSDN博客, Arthur-Ji ,2019年8月
[5].《数据分析的四个层次》 人人都是产品经理 , 大鹏 ,2020年7月
[6].《Gartner发布2020年数据与分析领域的十大技术趋势》 Gartner ,Laurence Goasduff ,2020.06
[7].《最全的零售行业指标体系详解!》 知乎 ,李启方 ,2020年10月





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章