电信运营商客户流失分析
客户流失预测分析的必要性
- 本项目数据来源于Kaggle上关于运营商客户流失预测分析项目
- 关于客户留存对公司的利润的影响一直有这样一个观点,如果将客户流失率降低 5%,公司利润将提升 25%-85%。研究表明,企业可以在一周内失去 100 个客户,而同时又得到另外一个客户,从表明上来看业绩没有受到任何影响,而实际上争取这些新客户所花费的宣传、促销等成本显然要比保持老客户昂贵的多,从企业投资回报程度的角度来看是非常不经济的。高居不下的获客成本让电信运营商遭遇“天花板”,甚至陷入获客难的窘境。伴随着获客难的窘境,客户的流失并未减少,从而导致流失率也居高不下。随着市场饱和度上升,电信运营商亟待解决增加客户黏性,延长客户生命周期的问题。因此,对电信客户流失分析相关的数据分析至关重要。
- 维护好老客户的重要性主要体现在以下四个方面: 首先留住老客户可使企业的竞争更长久;其次留住老客户还会使成本大幅度降低,因为引进新客户的成本随着市场日渐饱和而剧增;留住老客户,还会大大有利于发展新客户,由于客户口碑效应,如果一个满意的客户引发 8 笔潜在的生意,那么其中至少 1 笔成交,获取更多的客户份额;并且忠诚的客户会更愿意购买企业的产品,其支出也会比随意消费者大得多。
方法
-
本文提出四个问题,主要针对这四个方向做出对电信客户流失分析相关的数据分析与建议:
一是分析客户特征与流失的关系
二是从整体情况看,流失客户的普遍具有哪些特征
三是尝试找到合适的模型预测流失客户
四是针对性给出增加客户黏性、预防流失的建议
在解决了上述四个问题之后,我们便可以帮助运营商发现并改善客户体验,以及确定挽留目标客户并制定方案。 -
本项目Python 语言为基础,采用 pandas 进行数据整理和描述性统计分析,用 matplotlib、seaborn 进行可视化分析,scikit-learn 进行建模预测分析。
-
首先对数据进行清洗,使得数据完整可用,然后在清洗后的数据上按照客户属性、服务属性、合同属性三个方面作可视化分析,得到流失客户普遍具有的特征。接着尝试用多种预测方法对数据进行建模预测和测试,找到最优方法为随机森林法。并按照该方法的最优参数构建模型,用此模型对最后 10 位客户是否流失进行预测分析。最后针对性地给出增加客户粘性、预防客户流失的建议。
1 原始数据分析
本数据集描述了电信客户是否流失以及其相关信息,共包含 7044 条数据,共 20 个字段,介绍下各个字段:
1.1数据清洗
#导入工具包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv("data.csv")
#查看数据集中的列名
data.info()
#发现data['TotalCharges']中有 ' ' 数据,无法将其直接转化为浮点型,
#这里用到强制转化,不能转化的设为空值,再用0填充空值
data['TotalCharges'].dtypes
data['TotalCharges'].value_counts()
# 在筛选中发现,TotalCharges对应NaN时,其MonthlyCharges和tenure如下:
set_num = data[data['TotalCharges'].isnull().values==True][['tenure','MonthlyCharges','TotalCharges']]
set_num
我们对这 11 个数值为 0 的客户的信息进行分析,得出结果:
发现这 11 个客户的 tenure(入网时长)为 0,可以推测出他们是调查当月新入网的客户。相应的,观察他们的总消费额为 0 而月消费额不为 0,于是我们更新数据,将总消费额填充为月消费额,并将他们的入网时长改为 1。
data.loc[data['TotalCharges'].isnull(),'TotalCharges']=data[data['TotalCharges'].isnull()]['MonthlyCharges']
set_num = data[data['tenure']==0][['tenure','MonthlyCharges','TotalCharges']]
set_num
替换成功,得出结果:
#将入网时长的0改为1
data.loc[:,'tenure'].replace(to_replace=0,value=1,inplace=True)
#对数值型变量进行描述统计
data.describe()
可以得出结论:
- 客户中有16.2%为老人;
- 客户在公司平均停留32个月,最长的有6年;
- 运营商每月平均向客户收取64元,最大118.75元,最少18.25元
- 运营商向客户收取的总金额平均为2279.79元,最多为8684.8元,最少为18.8
1.2 可视化分析
根据客户特征字段的类型,我们对客户特征将从客户属性、服务属性、合同属性三个维度进行可视化分析:
1.2.1 客户属性分析
客户属性中分类属性有 SeniorCitizen、gender、Partner、Dependents 四个类别,本文通过将四个属性按类别分类的条形图对类别影响进行分析:
plt.figure(figsize=(6, 6))
#按性别统计流失与否占比
gender_data = (data.groupby('gender')['Churn'].value_counts()/len(data)).to_frame()
gender_data.rename(columns = {
'Churn': '客户占比'},inplace = True)
gender_data.reset_index(inplace = True)
gender_data
#同样可以生成按照是否为老年用户、是否为伴侣用户、是否为家属用户分类的统计表
def bar_per(feature, orient = 'v', axis_name = '客户占比'):
ratios = pd.DataFrame()
p = (data.groupby(feature)['Churn'].value_counts()/len(data)).to_frame()
p.rename(columns = {
'Churn': axis_name}, inplace = True)
p.reset_index(inplace = True)
#print(p)
if orient == 'v':
ax = sns.barplot(x = feature, y = axis_name,
hue = 'Churn', data = p,
orient = orient, palette="plasma_r", alpha=0.5)
ax.set_yticklabels(['{:,.0%}'.format(y) for y in ax.get_yticks()])
plt.rcParams.update({
'font.size': 13})
plt.legend(fontsize = 10)
else:
ax = sns.barplot(x = axis_name, y = feature,
hue = 'Churn', data = p, orient = orient,
palette="plasma_r", alpha=0.5)
ax.set_xticklabels(['{:,.0%}'.format(x) for x in ax.get_xticks()])
plt.legend(fontsize = 10)
#plt.title('按照 {} 分类的客户流失与否的比例'.format(feature))
plt.show()
bar_per('SeniorCitizen')
bar_per('gender')
结论:
- 客户的流失情况与性别基本无关,