在目前的商业市场,客户流失是各行各业不可逃避的问题,客户流失不仅造成成本浪费,而且挽回成本也比较大。

因此,在商业竞争日益激烈的今天,如何减少客户流失是客户运营过程中至关重要的一个环节。为了更好地研究如何减少用户流失,本文从用户特征,分析用户流失原因,并对用户流失做出预测,便于提前准备应对策略。

提出问题:观察流失用户的特征;

分析用户流失的原因;

构建用户流失模型,建立用户流失预测模型。

数据描述customerID :用户ID。

gender:性别。(Female & Male)

SeniorCitizen :老年人 (1表示是,0表示不是)

Partner :是否有配偶 (Yes or No)

Dependents :是否经济独立 (Yes or No)

tenure :客户的职位(0-72,共73个职位)

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)

一、导入数据

# 导入数据分析包
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
data = pd.read_csv('F:\\python\\python每日练习\\5、电信客户流失数据\\WA_Fn-UseC_-Telco-Customer-Churn.csv')
#查看数据
data.head()

二、数据准备2.1数据准备—观察数据

# 观察数据类型和数据完整性
data.info()

由此可知,(1)数据没有缺失值;

(2)TotalCharges表示总费用,应为数字类型,这里为object类型,因此需要转换为float类型

接下来,对总费用进行数据转换。2.2数据转换

# convert_numeric=True 强制转换为数字类型
data['TotalCharges']=data['TotalCharges'].convert_objects(convert_numeric=True)
# 再次查找缺失值
data.isnull().sum()

由此可知,TotalCharges含有11个缺失值,由于缺失值较少,因此直接删除缺失值即可。2.3删除缺失值

#删除缺失值
data = data.dropna()
#统计缺失值
data.isnull().sum()2.4将流失列数据进行编码
# 观察流失列数据
dataDF['Churn'].value_counts()

由此可知,流失用户1869个,未流失用户5163个。

# 对churn进行0-1编码
ChurnDict={'No':0,
'Yes':1}
dataDF['Churn']=dataDF['Churn'].map(ChurnDict)

三、数据分析3.1流失用户占比

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#解决中文乱码问题
import matplotlib as mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
接下来采用饼图观测流失用户的占比
# 为画图准备数据
data_Churn = dataDF['Churn'].value_counts()
labels= dataDF['Churn'].value_counts().index
# 分裂饼图
plt.pie(data_Churn,
labels = labels, autopct = '%3.1f%%',
startangle = 0, shadow = True,
colors = ['c', 'y'])
# 显示标题
plt.title('电信用户流失用户类型')
# 显示图形
plt.show()

由此可知,7032个用户中,流失用户共1869人,占全部人数26.6%。3.2 查看性别、老人、配偶以及经济是否独立对流失率的影响

# 建立画板及画布
fig = plt.figure(figsize = (16,4))
ax1 = fig.add_subplot(1,4,1)
ax2 = fig.add_subplot(1,4,2)
ax3 = fig.add_subplot(1,4,3)
ax4 = fig.add_subplot(1,4,4)
#性别
sns.countplot(x='gender',hue = 'Churn',data =dataDF, ax=ax1)
#是否是老人
sns.countplot(x='SeniorCitizen',hue = 'Churn',data =dataDF, ax=ax2)
#是否有配偶
sns.countplot(x='Partner',hue = 'Churn',data =dataDF, ax=ax3)
#经济是否独立
sns.countplot(x='Dependents',hue = 'Churn',data =dataDF, ax=ax4)

由此可以看出,1)性别对流失率几乎无影响;

2)老人的流失率占比比年轻人流失率高;

3)没有配偶的用户流失率高于有配偶的用户;

4)经济未独立的用户的流失率远高于经济独立的用户的流失率。3.3多线业务、网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视和网络电影对客户流失率的影响

fig = plt.figure(figsize = (16,8))
ax1 = fig.add_subplot(2,4,1)
ax2 = fig.add_subplot(2,4,2)
ax3 = fig.add_subplot(2,4,3)
ax4 = fig.add_subplot(2,4,4)
ax5 = fig.add_subplot(2,4,5)
ax6 = fig.add_subplot(2,4,6)
ax7 = fig.add_subplot(2,4,7)
#多线业务 MultipleLines
sns.countplot(x='MultipleLines',hue = 'Churn',data =dataDF, ax=ax1)
#网络安全服务 OnlineSecurity
sns.countplot(x='OnlineSecurity',hue = 'Churn',data =dataDF, ax=ax2)
#在线备份业务 OnlineBackup
sns.countplot(x='OnlineBackup',hue = 'Churn',data =dataDF, ax=ax3)
#设备保护业务 DeviceProtection
sns.countplot(x='DeviceProtection',hue = 'Churn',data =dataDF, ax=ax4)
#技术支持服务 TechSupport
sns.countplot(x='TechSupport',hue = 'Churn',data =dataDF, ax=ax5)
#网络电视 StreamingTV
sns.countplot(x='StreamingTV',hue = 'Churn',data =dataDF, ax=ax6)
#网络电影 StreamingMovies
sns.countplot(x='StreamingMovies',hue = 'Churn',data =dataDF, ax=ax7)

由此可知,1)除多线业务 MultipleLines外,其余6个变量在无网络服务的情况下,流失率都很低且低于有网络服务时的流失率,说明没有网络服务,不是导致用户流失的原因;

2)在多线业务的问题上,未开通多线业务的流失率略低于开通多线业务的流失率;

3)网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视和网络电影等六项业务在开通的情况下的流失率比不开通的时候的流失率低。3.4 签订合同方式对流失率的影响

3.4.1 用户签订合同方式的整体情况

# 观察签订合同的方式整体情况
ContractDf = dataDF['Contract'].value_counts()
Contract_labels=ContractDf.index
#饼图
plt.pie(ContractDf,
labels=Contract_labels,
autopct='%3.1f%%',
)
plt.title('电信用户签订合同方式')
plt.show()

由此可知,

按月签订合同的用户最多,占55.1%,一年签的用户占20.9%,两年前的用户占24.0%。

3.4.2 分别分析3种签订合同方式的流失情况

# 按月签订合同的流失率
data_Churn_Month =dataDF[dataDF['Contract']=='Month-to-month'][['Contract','Churn']]
# 按一年签订合同的流失率
data_Churn_Oneyear =dataDF[dataDF['Contract']=='One year'][['Contract','Churn']]
# 按两年签订合同的流失率
data_Churn_Twoyear =dataDF[dataDF['Contract']=='Two year'][['Contract','Churn']]
# 统计按月签订合同流失用户和未流失用户
Contract_monthDf = data_Churn_Month['Churn'].value_counts()
Contract_month_labels=Contract_monthDf.index
# 统计按一年签订合同流失用户和未流失用户
Contract_oneyearDf = data_Churn_Oneyear['Churn'].value_counts()
Contract_oneyear_labels=Contract_oneyearDf.index
# 统计按两年签订合同流失用户和未流失用户
Contract_twoyearDf = data_Churn_Twoyear['Churn'].value_counts()
Contract_twoyear_labels=Contract_twoyearDf.index
#按月签订合同的用户流失情况饼图
plt.pie(Contract_monthDf,
labels=Contract_month_labels,
autopct='%3.1f%%')
plt.title('按月签订合同的用户流失情况')
#饼图
plt.pie(Contract_oneyearDf,
labels=Contract_oneyear_labels,
autopct='%3.1f%%' )
plt.title('按一年签订合同的用户流失情况')
#饼图
plt.pie(Contract_twoyearDf,
labels=Contract_twoyear_labels,
autopct='%3.1f%%',
)

plt.title('按一年两年订合同的用户流失情况')

通过对签订合同不同方式对流失率的分析可得:签订时间越久,用户流失率越低。3.5电子账单对与用户流失

sns.countplot(x= 'PaperlessBilling',hue='Churn',data=dataDF)
plt.title('PaperlessBilling & Churn')

由此可见,开通电子账单的用户流失率更高。3.6付款方式与用户流失

fig = plt.figure(figsize=(10,5))
sns.countplot(x= 'PaymentMethod',hue='Churn',data=dataDF)
plt.title('PaymentMethod & Churn')

由此可知,使用Electronic check支付的用户流失率最高。

四、特征提取4.1数据标准化

#数据标准化包
from sklearn import preprocessing
#采用min-max方式进行标准化
min_max_scaler = preprocessing.MinMaxScaler()
dataDF[['tenure','MonthlyCharges','TotalCharges']]= min_max_scaler.fit_transform(dataDF[['tenure','MonthlyCharges','TotalCharges']])4.2特征编码

为了便于接下来的分析,对各特征进行编码。

#编码,采用字典映射的方式
genderDict = {'Female':1,
'Male':0}
PartnerDict = {'Yes':1,
'No':0}
DependentsDict={'Yes':1,
'No':0}
PhoneServiceDict={'Yes':1,
'No':0}
MultipleLinesDict={'Yes':1,
'No':0,
'No phone service':2}
InternetServiceDict= {'No':0,
'DSL':1,
'Fiber optic':2}
OnlineSecurityDict={'Yes':1,
'No':0,
'No internet service':2}
OnlineBackupDict={'Yes':1,
'No':0,
'No internet service':2}
DeviceProtectionDict={'Yes':1,
'No':0,
'No internet service':2}
TechSupportDict={'Yes':1,
'No':0,
'No internet service':2}
StreamingTVDict = {'Yes':1,
'No':0,
'No internet service':2}
StreamingMoviesDict = {'Yes':1,
'No':0,
'No internet service':2}
ContractDict={'Month-to-month':0,
'Two year':2,
'One year':1}
PaperlessBillingDict={'Yes':1,
'No':0}
PaymentMethodDict={'Bank transfer (automatic)':0,
'Credit card (automatic)':1,
'Electronic check':2,
'Mailed check':3}
dataDF['gender']=dataDF['gender'].map(genderDict)
dataDF['Partner']=dataDF['Partner'].map(PartnerDict)
dataDF['Dependents']=dataDF['Dependents'].map(DependentsDict)
dataDF['PhoneService']=dataDF['PhoneService'].map(PhoneServiceDict)
dataDF['MultipleLines']=dataDF['MultipleLines'].map(MultipleLinesDict)
dataDF['InternetService']=dataDF['InternetService'].map(InternetServiceDict)
dataDF['OnlineSecurity']=dataDF['OnlineSecurity'].map(OnlineSecurityDict)
dataDF['DeviceProtection']=dataDF['DeviceProtection'].map(DeviceProtectionDict)
dataDF['OnlineBackup']=dataDF['OnlineBackup'].map(OnlineBackupDict)
dataDF['TechSupport']=dataDF['TechSupport'].map(TechSupportDict)
dataDF['StreamingTV']=dataDF['StreamingTV'].map(StreamingTVDict)
dataDF['StreamingMovies']=dataDF['StreamingMovies'].map(StreamingMoviesDict)
dataDF['Contract']=dataDF['Contract'].map(ContractDict)
dataDF['PaperlessBilling']=dataDF['PaperlessBilling'].map(PaperlessBillingDict)
dataDF['PaymentMethod']=dataDF['PaymentMethod'].map(PaymentMethodDict)
#查看编码过程中是否有误,若有误会有缺失值出现
dataDF.isnull().sum()
由于没有缺失值,故编码是正确的。4.3各特征与用户流失之间的相关性
#相关性
corr = dataDF.corr()
# 相关性的热图
fig = plt.figure(figsize=(16,16))
sns.heatmap(corr,annot=True)
由热图可知,monthlycharges 与InternetService的相关性0.91,故相关水平较高,因此二者选其一即可。
corr_Churn = dataDF.corr()['Churn'].sort_values(ascending = True)
corr_Churn
# 观察用户流失与各特征的相关性
fig = plt.figure(figsize=(12,6))
corr_Churn.plot(kind='bar')

由此可知,gender、PhoneService和MultipleLines与Churn的相关性接近0,故这三个指标可以删除。

# 综合以上,取特征如下:
features = ['Contract','tenure','OnlineSecurity','TechSupport','OnlineBackup','DeviceProtection','StreamingMovies','StreamingTV',
'TotalCharges','Dependents','Partner','PaymentMethod','SeniorCitizen','PaperlessBilling','MonthlyCharges']
features_X= dataDF[features]
labels_y=dataDF['Churn']

五、模型选择

#选择逻辑回归
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# 获取训练数据集与测试数据集
train_X,test_X,train_y,test_y = train_test_split(features_X,
labels_y,
train_size=.8
)
#建立模型
model = LogisticRegression()
#模型拟合
model.fit(train_X,train_y)
# 用测试数据集做数据预测
pridict_y = model.predict(test_X)
# 预测准确率
score = model.score(test_X,test_y)
score = 0.8073916133617626

由此可知,逻辑回归的准确率为80.7%

六、分析报告

总结数据集共7032个用户,其中流失用户共1869人,占全部人数26.6%;

从用户个人特征来看,老年人、单身和经济不独立的用户的流失率高;

从开通网络服务的角度来看,多线业务、网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视和网络电影等7项业务在开通的情况下的流失率低于未开通;

从签订合同的维度来看,按月签订合同的用户最多,占全部用户的55.1%,流失率为42.7%,一年签的用户占全部用户的20.9%,流失率为11.3%,两年前的用户占全部用户的24.0%,流失率为2.8%,因此可得,增加用户签订合同的时间,可以有效减少用户流失;

从是是否开通电子账单来看,开通电子账单的用户流失率更高;

从付款方式来看,使用Electronic check支付的用户流失率最高。

建议与优化方向:加大签订两年合同的优惠力度,通过送手机或者送流量、送家庭宽带,分月返话费的方式引导用户签订2年合同;

遇到老年人,单身及经济不独立的用户时,可通过半赠送半付费的方式进行引导其更多的网络服务,签订2年合同,并且避免其采用Electronic check的支付方式;

运营商开通电子账单,是为了让客户有更好的客户体验,增加用户粘性,从目前的结果来看,电子账单开通的用户流失率更高,考虑是否是电子账单的用户体验不好,或者电子账单呈现的消费明细角度有问题。因此,运营商需要优化电子账单;

通过随机立减,送优惠等方式,引导客户在付款时采用bank transfer,credit card,mailed check的方式。