电信流失客户特征分析及预测

0.项目背景

kaggle网站上的数据集,拿来学习分析。下载地址:Telco Customer Churn | Kaggle

       老年用户、未婚用户及经济未独立用户流失率比较高,根据市场份额分析,预测个体客户的生存时长,针对该类用户特征喜好制定专属套餐。

        目的:分析流失用户的共同属性,预测流失用户

1.数据准备

1.1搭建环境

!pip install imblearn -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
!pip install lifelines -i https://pypi.tuna.tsinghua.edu.cn/simple
#搭建环境
import numpy as np
import pandas as pd
from pyecharts.charts import *
from pyecharts import options as opts
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

#读取文件
df = pd.read_csv('WA_Fn-UseC_-Telco-Customer-Churn.csv')

1.2字段信息

字段解释
customerID用户ID
gender性别
SeniorCitizen是否是老年人(1代表是)
Partner是否有配偶(Yes or No)
Dependents是否经济独立(Yes or No)
tenure用户入网时间
PhoneService是否开通电话业务(Yes or No)
MultipleLines是否开通多条电话业务(Yes 、 No or No phoneservice)
InternetService是否开通互联网服务(No、DSL数字网络或Fiber optic光线网络)
OnlineSecurity是否开通网络安全服务(Yes、No or No internetservice)
OnlineBackup是否开通在线备份服务(Yes、No or No internetservice)
DeviceProtection是否开通设备保护服务(Yes、No or No internetservice)
TechSupport是否开通技术支持业务(Yes、No or No internetservice)
StreamingTV是否开通网络电视(Yes、No or No internetservice)
StreamingMovies是否开通网络电影(Yes、No or No internetservice)
Contract合同签订方式(按月、按年或者两年)
PaperlessBilling是否开通电子账单(Yes or No)
PaymentMethod付款方式(bank transfer、credit card、electronic check、mailed check)
MonthlyCharges月度费用
TotalCharges总费用
Churn 是否流失(Yes or No)

2.框架分析

找到流失用户共同属性:     

用户属性性别、是否老年人、有无配偶、是否经济独立......
服务属性是否开通电话业务、是否开通互联网服务......
消费属性合同签订方式、是否开通电子账单、付款方式......

3.数据清洗

3.1数据信息

# 查看基本信息
df.info()

# 查看是否存在重复值--无重复值
df.duplicated().sum()

  • 共21个变量,7043条数据,无缺失值,无重复值
  • TotalCharges 需要转换为浮点型
# 转换变量类型
# 在转换变量中报错了,列当中存在空格字符串,逐一排查其他列是否存在同样情况
for i in df.columns:
    if i == 'SeniorCitizen':
        print(i,df[i].isnull().sum())
    elif i == 'tenure':
        print(i,df[i].isnull().sum())
    elif i == 'MonthlyCharges':  
        print(i,df[i].isnull().sum())
    else:
        print(i,df[df[i] == ' '][i].count())

TotalCharges 有11个空白值,需要进行填充。这11个用户,只消费了第一个月,故TotalCharges = MonthlyCharges,即用MonthlyCharges来填充TotalCharges

total_id_blank = df.query("TotalCharges == ' '")['customerID']
df.query("customerID in @total_id_blank").groupby(
    ['customerID', 'tenure'])[['MonthlyCharges']].sum().reset_index()
# TotalCharges = MonthlyCharges
for i in total_id_blank:
    df.loc[df.query("customerID == @i").index[0], 'TotalCharges'] = df.loc[df.query(
        "customerID == @i").index[0], 'MonthlyCharges']
df['TotalCharges'] = df['TotalCharges'].astype(float)

3.2异常值处理

# 查看分类变量的所有取值
for i in df.columns:
    if i not in ('customerID','MonthlyCharges','TotalCharges'):
        print(i,df[i].unique())

分类型变量无异常值,接下来观察离散型变量是否存在异常值

# 离散型变量分布
pic = plt.figure(figsize=(9,3),dpi=80)
pic.add_subplot(1,2,1)#第一个子图(行数,列数,本子图位置)
plt.boxplot(df["MonthlyCharges"])
plt.title('MonthlyCharges')
pic.add_subplot(1,2,2)#第一个子图(行数,列数,本子图位置)
plt.boxplot(df["TotalCharges"])
plt.title('TotalCharges')
# 子图间距
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.5, hspace=0.5)
plt.show()

 可以看出均无异常值

4.流失用户属性分析

4.1用户属性

用户属性:gender、SeniorCitizen、Partner、Dependents

#用户属性分析
pic = plt.figure(figsize=(12,6),dpi=80)
pic.subplots_adjust(wspace=0.3,hspace=0.3)
for i,j in zip(df.iloc[:,1:5].columns,range(1,5)):
    df_count = df.pivot_table(index='Churn',columns=i,values='customerID',aggfunc='count')
    df_ratio = df_count.div(df_count.sum())
    #print(df_ratio)
    pic.add_subplot(2,2,j)
    plt.title('Churn by '+ i)
    plt.bar([0,1],df_ratio.iloc[0,:],label = df_ratio.index.values[0],width=0.5)
    plt.bar([0,1],df_ratio.iloc[1,:],bottom = df_ratio.iloc[0,:],label=df_ratio.index.values[1],width=0.5)
    plt.xticks([0,1],df_count.columns.values)
    for a,b in zip(range(df_ratio.shape[1]),df_ratio.iloc[1,:]):
        plt.text(a,0.88,round(b,4),va='bottom',ha='center',fontsize=12)
    plt.legend()  
plt.show()

可得到:

  • 性别对于用户是否流失几乎不存在差异,流失差异2.91%
  • 老年人要比年轻人更容易流失,流失率高于年轻人76.57%
  • 无配偶用户(未婚)比有配偶用户(已婚)更容易流失,流失率高于已婚用户67.59%
  • 经济不独立用户比经济独立用户更容易流失,流失率高于经济独立用户102.45%

4.2服务属性

服务属性:

  • PhoneService 是否开通电话业务(Yes or No)
  • MultipleLines 是否开通多条电话业务(Yes 、 No or No phoneservice)
  • InternetService 是否开通互联网服务(No、DSL数字网络或Fiber optic光线网络)
  • OnlineSecurity 是否开通网络安全服务(Yes、No or No internetservice)
  • OnlineBackup 是否开通在线备份服务(Yes、No or No internetservice)
  • DeviceProtection 是否开通设备保护服务(Yes、No or No internetservice)
  • TechSupport 是否开通技术支持业务(Yes、No or No internetservice)
  • StreamingTV 是否开通网络电视(Yes、No or No internetservice)
  • StreamingMovies 是否开通网络电影(Yes、No or No internetservice)
#服务属性
pic = plt.figure(figsize=(16,9),dpi=80)
pic.subplots_adjust(wspace=0.3,hspace=0.3)
for i,j in zip(df.iloc[:,6:15].columns,range(1,10)):
    df_count = df.pivot_table(index='Churn',columns=i,values='customerID',aggfunc='count')
    df_ratio = df_count.div(df_count.sum())
    
    pic.add_subplot(3,3,j)
    plt.title('Churn by '+ i)
    plt.bar(range(df_ratio.shape[1]),df_ratio.iloc[0,:],label = df_ratio.index.values[0],width=0.5)
    plt.bar(range(df_ratio.shape[1]),df_ratio.iloc[1,:],bottom = df_ratio.iloc[0,:],label=df_ratio.index.values[1],width=0.5)
    plt.xticks(range(df_ratio.shape[1]),df_count.columns.values)
    for a,b in zip(range(df_ratio.shape[1]),df_ratio.iloc[1,:]):
        plt.text(a,0.88,round(b,4),va='bottom',ha='center',fontsize=12)
    if i=='PhoneService':
        plt.legend()  
plt.show()

可看出:

  • 是否开通电话业务对流失率无影响

  • 未开通互联网服务的流失率最低

  • 开通了互联网服务的用户中,光纤网络的用户流失率最高

4.3消费属性

消费属性:

  • Contract 合同签订方式(按月、按年或者两年)
  • PaperlessBilling 是否开通电子账单(Yes or No)
  • PaymentMethod 付款方式(bank transfer、credit card、electronic check、mailed check)
  • MonthlyCharges 月度费用
  • TotalCharges 总费用
pic = plt.figure(figsize=(20,9),dpi=120)
pic.subplots_adjust(wspace=0.3,hspace=0.3)
for i,j in zip(df.iloc[:,15:18].columns,range(1,4)):
    df_count = df.pivot_table(index='Churn',columns=i,values='customerID',aggfunc='count')
    df_ratio = df_count.div(df_count.sum())
   
    pic.add_subplot(2,2,j)
    plt.title('Churn by '+ i)
    plt.bar(range(df_ratio.shape[1]),df_ratio.iloc[0,:],label = df_ratio.index.values[0],width=0.5)
    plt.bar(range(df_ratio.shape[1]),df_ratio.iloc[1,:],bottom = df_ratio.iloc[0,:],label=df_ratio.index.values[1],width=0.5)
    plt.xticks(range(df_ratio.shape[1]),df_count.columns.values)
    for a,b in zip(range(df_ratio.shape[1]),df_ratio.iloc[1,:]):
        plt.text(a,0.95,round(b,4),va='bottom',ha='center',fontsize=12)
    if i=='PaperlessBilling':   
        plt.legend()  
plt.show()

流失率:

  • Two year < One year < Month-to-month
  • 未开通电子账单 < 开通电子账单
  • credit card < bank transfer < mailed check < electronic check
# MonthlyCharges 和 TotalCharges 属于离散型变量,对他们进行分组做直方图,观察分布情况。
import seaborn as sns 
sns.distplot(df.query("Churn == 'Yes'")["MonthlyCharges"])
plt.title("MonthlyCharges")
plt.show()

sns.distplot(df.query("Churn == 'Yes'")["TotalCharges"])
plt.title("TotalCharges")
plt.show()

可以看出:

  • 流失率较高的月支付金额区间主要在[65,105]之间,流失率较低区间主要在[20,65]

  • 总支付金额越高,流失率越低

5.构建预测模型

  • 对数据集的一些未流失用户个体进行预测,并绘制生存线,数字代表样本序号。
  • 以个体半衰期作为预测生存时间,得到各个时间结点流失的用户占比

(图书馆闭馆了,明天再写呜呜呜)

6.总结

利用回归模型比较了不同特征对于客户流失的影响,并且预测了个体客户的生存时长,计算了各时间点用户流失的比例,结果具有一定的参考性。并对用户流失特征做了一定分析

用户属性:
流失特征:老年用户、未婚用户及经济未独立用户流失率较高。
建议:根据市场份额,考虑是否针对这类户特征喜好制订专属套餐,建议价格区间[20,65]

服务属性:
流失特征:网络使用Fiber Optic流失率高。
建议:
1、对用户进行针对性调研,调研分析老年用户,经济独立用户不选择Fiber Optic的原因
2、可对签订长期合同的客户基于价格优惠,提高长期合同份额
3、电子账单流失率较高,存在疑问,需要具体业务分析,电子账单展示是否可以进行优化
4、引导用户优先使用信用卡支付方式
5、适当下调Fiber Optic资费

消费属性:
流失特征:月付流失率较高,开通账单流失率较高,使用电子支票的用户流失率较高。
建议:
1、可对签订长期合同的客户基于价格优惠,提高长期合同份额。
2、电子账单流失率较高,存在疑问,需要具体业务分析,电子账单展示是否可以进行优化
3、引导用户优先使用信用卡支付方式

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值