一、项目背景
电信服务是生活中常见的消费服务,在现代社会,凡是使用手机打电话,或者在家看电视,都必须通过电信运营商提供的通话、网络等服务才能实现。本文采用来自kaggle平台的电信客户数据集,来分析人们对电信服务的使用情况,以及帮助电信运营商找出客户流失的原因,并建立流失预测模型,从而降低客户流失率。数据集链接如下:https://www.kaggle.com/blastchar/telco-customer-churnwww.kaggle.com
分析工具:本项目主要使用pandas, matplotlib, seaborn, sklearn等Python数据分析库,并在Jupyter Lab环境下运行。为了节省篇幅,本文不展示详细代码,仅展示关键步骤的代码。
项目流程如下:
二、业务流程+分析目的
根据kaggle上的数据集介绍,该数据集共有21个字段,7043条记录。每条记录表示一个客户。
通过理解字段,将字段分为4类,包括客户的基本信息、开通的服务信息、付费信息以及流失标签。基本信息包括性别、年龄(以是否老年人来区分)、是否有合伙伙伴(可以理解为工作伙伴或者朋友之类的)以及家属。观察服务信息,可以分为两类基本服务:电话+网络服务,这两类基本服务又有各自的增值服务,如:多线电话、网络安全、在线备份等。此外还有支付方式、消费金额等付费信息。
虽然字段不多,但我们可以将这些字段提炼成一个业务流程,或者说一个“故事”,并依据业务流程提出问题,这是数据分析中基础而又核心的思维。
业务流程
根据业务流程,我们提出分析目的:
分析目的
1、构建客户画像,深入了解客户了解客户的性别、年龄等特征是如何分布的?
这些客户会选择什么类型的服务,合同期限以及支付方式?
不同类型的客户,他们消费能力有什么区别?
2、分析客户流失的原因,并建立客户流失预警模型哪些特征与客户是否流失息息相关?如何避免客户流失?
提出业务建议
三、数据清洗
导入数据
# 导入数据
df = pd.read_csv('datasets_13996_18858_WA_Fn-UseC_-Telco-Customer-Churn.csv')
df.info()
# 输出
RangeIndex: 7043 entries, 0 to 7042
Data columns (total 21 columns):
customerID 7043 non-null object
gender 7043 non-null object
SeniorCitizen 7043 non-null int64
Partner 7043 non-null object
Dependents 7043 non-null object
tenure 7043 non-null int64
PhoneService 7043 non-null object
MultipleLines 7043 non-null object
InternetService 7043 non-null object
OnlineSecurity 7043 non-null object
OnlineBackup 7043 non-null object
DeviceProtection 7043 non-null object
TechSupport 7043 non-null object
StreamingTV 7043 non-null object
StreamingMovies 7043 non-null object
Contract 7043 non-null object
PaperlessBilling 7043 non-null object
PaymentMethod 7043 non-null object
MonthlyCharges 7043 non-null float64
TotalCharges 7043 non-null object
Churn 7043 non-null object
dtypes: float64(1), int64(2), object(18)
memory usage: 1.1+ MB
导入数据后,发现这个数据集十分工整,乍一看似乎没有缺失值,但仔细查看会发现,TotalCharges总消费金额这一列,本应该和MonthlyCharges一样是float类型,但现在是object类型,说明有部分记录被pandas识别为字符串了。
df['TotalCharges'].value_counts()
# 输出
20.2 11
11
19.75 9
19.9 8
20.05 8
..
2431.95 1
1325.85 1
188.1 1
3058.15 1
191.35 1
Name: TotalCharges, Length: 6531, dtype: int64
可以看到,有11行记录是空白字符串,pandas没有将其识别为缺失值,我们将其替换为空值。
# 处理TotalCharges
df['TotalCharges'].replace(' ', np.nan, inplace=True)
df['TotalCharges'] = df['TotalCharges'].astype('float')
缺失值处理
# 缺失值处理
mis_val_df = df[df['TotalCharges'].isnull()]
mis_val_df.loc[:, ['tenure','MonthlyCharges','TotalCharges']]
观察这11个客户,发现有且只有他们的注册月数为0,由此猜测这部分客户由于是新注册用户,注册月数在1个月之内,所以导致TotalCharges没有记录,我们将其补充各自对应的MonthlyCharges。
df['TotalCharges'].fillna(df['MonthlyCharges'], inplace=True)
重复值处理
# 重复值处理
df.duplicated().sum()
# 输出
0
本数据集没有重复值。
异常值处理
# 异常值处理,查看描述性统计
df.describe([0.01,0.2