电信用户流失分析与预测


这是作者自己做的一个数据分析项目,通篇采用大量python源码编写,欢迎一起学习交流,提升自我。
作者的博客园地址: https://www.cnblogs.com/lverkou/p/13441302.html
转载请标明出处,谢谢!
数据集下载地址: https://www.datafountain.cn/datasets/35guide

一. 研究背景

用户流失预测在机器学习中算是一种比较典型的分类场景,做好用户的流失预测可以降低营销成本,留住用户并且获得更好的用户体验,在三大巨头的瓜分下,做好营销运营比重新获取一个新用户更节省成本。达到较好的运营回报。如果在传统分类模式下,通常是通过人工对各个特征进行统计,然后分到合适的类别中,这样不但会耗费大量的资源,且低效。

二. 分析结论与建议

  1. 增加套餐福利,解锁更多权益,如赠送流量,免费看视频,增设小游戏,贵族制度,
  2. 加强电话服务质量,设立评分反馈系统,及时跟踪异常评分
  3. 加强光纤相关设施的建设,增强网络稳定性
  4. 鼓励用户开通各种服务,如在线安全,在线备份,设备保护,技术支持
  5. 增加充值返现,充值满减,发放优惠券的方式,用户消费达到一定金额解锁特权
  6. 针对老年人建议赠送通话时长,提高活跃度
  7. 针对排名前十的职业根据相应的职业给予相应的优惠和福利,提高用户的粘性。

三. 任务与实现

我们的任务在于:
1.分析出流失用户有哪些显著性特征?
2.找出哪些用户容易流失?
具体实现内容包括:
能够对数据进行数据预处理 包括缺失值,异常值,重复值
能够描述性分析各个特征与流失用户的占比是否显著
能够将连续型变量进行分箱离散化
能够将离散型特征进行独热编码
能够建立基模型,将源数据进行标准化
能够处理样本不均衡
能够熟练运用多种分类模型对电信用户进行预测
分析模型有:逻辑回归,KNN,朴素贝叶斯,决策树,多层感知器。

四. 数据集解析

每行代表一个客户,每列包含元数据列中描述的客户属性。
一共7043行数据,21个列。前20个为特征列,最后一个为研究对象。
1 customerID Integer :用户ID
2 gender String:性别(Female or Male)
3 SeniorCitizen Integer: 老年人(1表示是,0表示不是)
4 Partner String:配偶(Yes or No)
5 Dependents String:家属(Yes or No)
6 tenure Integer :职位(0~72,共73个职位)
7 PhoneService String:电话服务(Yes or No)
8 MultipleLines String:多线(Yes 、No or No phoneservice 三种)
9 InternetService String:互联网服务(No, DSL数字网络,fiber optic光纤网络 三种)
10 OnlineSecurity String:在线安全(Yes,No,No internetserive 三种)
11 OnlineBackup String:在线备份(Yes,No,No internetserive 三种)
12 DeviceProtection String:设备保护(Yes,No,No internetserive 三种)
13 TechSupport String:技术支持(Yes,No,No internetserive 三种)
14 StreamingTV String:网络电视(Yes,No,No internetserive 三种)
15 StreamingMovies:网络电影 (Yes,No,No internetserive 三种)
16 Contract String:合同(Month-to-month,One year,Two year 三种)
17 PaperlessBilling String:账单(Yes or No)
18 PaymentMethod String:付款方式(bank transfer,credit card,electronic check,mailed check 四种)
19 MonthlyCharges Integer :月费用
20 TotalCharges Integer :总费用
21 Churn String:流失(Yes or No)

五. 数据分析套餐

1.准备工作

本文数据源来自网上,数据源除了各大网站可以下载,还可以来自自家公司的数据库,爬虫等方式获取。

导入相关的库

# 导入库 
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import seaborn as sns
import warnings
from matplotlib import font_manager
import time

sns.set(style="darkgrid", font_scale=1.2)
# plt.rcParams["font.family"] = "SimHei"
plt.rcParams['font.family'] = ['Arial Unicode MS']
plt.rcParams["axes.unicode_minus"] = False
my_font=font_manager.FontProperties(fname=
                                    '/System/Library/Fonts/PingFang.ttc',
                                    size=15)  
warnings.filterwarnings("ignore")

from scipy import stats #用于方差分析

# from sklearn.linear_model import LinearRegression  #线性回归模型
from sklearn.model_selection import train_test_split #切分训练集 测试集
from sklearn.linear_model import LogisticRegression #逻辑回归模型
from sklearn.metrics import classification_report #混淆矩阵打分
from sklearn.model_selection import GridSearchCV #网格交叉验证
from imblearn.over_sampling import SMOTE,ADASYN # 引入SMOTE和ADASYN处理样本不均衡
from collections import Counter #查看每个类别出现的次数
from sklearn.pipeline import Pipeline #引入流水线
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 评估指标 --正确率 精准率 召回率 F1调和平均值
from sklearn.neighbors import KNeighborsClassifier #KNN分类模型
from sklearn.preprocessing import StandardScaler, MinMaxScaler # StandardScaler:均值标准差标准化 # MinMaxScaler:最小最大值标准化
from sklearn.neural_network import MLPClassifier #多层感知器

导入数据集

data = pd.read_csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
print(data.shape)
data.sample(10)

在这里插入图片描述

2.数据预处理

查看数据整体情况

data.info()

在这里插入图片描述

类型转换

我们发现TotalCharges本应该是float64类型,这里却是object类型,那么需要转换。

data['TotalCharges'].astype(np.float64)

会报错 无法转换。这里用到一个函数:DataFrame.convert_objects( convert_dates = True,convert_numeric = False,convert_timedeltas = True,copy = True )

data["TotalCharges"]=data["TotalCharges"].convert_objects(convert_numeric=True)
data['TotalCharges'].dtype

输出:dtype(‘float64’) ,转换完成。

缺失值处理

data.isnull().sum(axis=0)


TotalCharges有11个缺失值,查看数据分布 再确定是删除还是填充

print(data["TotalCharges"].skew()) 
sns.distplot(data["TotalCharges"].dropna())

在这里插入图片描述
结果大于0, 属于右偏 ,当然 ,也能一眼从图形看出。
缺失值的处理方式有:删除,中位数填充,均值填充,众数填充。
右偏数据我们用中位数填充,两种方式计算中位数,计算中位数时会剔除缺失值

data["TotalCharges"].median()
或者
np.median(data["TotalCharges"].dropna().values)

输出为:1397.475

填充缺失值

data.fillna({
   "TotalCharges":data["TotalCharges"].median()},inplace=True)
data.isnull().sum(axis=0)

在这里插入图片描述

重复值处理

如果有重复值:可直接删除


# data.drop_duplicates(inplace=True)
data.duplicated().sum()

输出:0
说明没有重复值

3.查看流失情况

整体流失情况 条形图查看

Churn_value=data["Churn"].value_counts()
display(Churn_value)
sns.countplot(x="Churn",data=data)

在这里插入图片描述
也可饼状图查看

size=Churn_value.values
label_list=Churn_value.index
color=["#009999","#FF7400"]
explode=[0,0.1]
plt.figure(figsize=(8,8),dpi=80)
patches,l_text,p_text=plt.pie(size,
                            explode=explode,
                            colors=color,
                            labels=label_list,
                            labeldistance=1.1,
                            autopct='%1.1f%%',   
                            shadow=True,
                            startangle=90,
                            pctdistance=0.6,
                            )  
plt.show()

在这里插入图片描述

饼状图可以内部直接算出百分比,从图中可以看出流失比例26.5%,占比较高,也处于样本不均衡问题,后面可以采用过采样来解决,过采样相比欠采样较稳定。

对于研究对象:Churn,我们用pandas中的map函数实现数字化处理,我们通常将关注的类别设为1。

data["Churn"]=data["Churn"].map({
   "Yes":1,"No":0})
data.head()

在这里插入图片描述
可以看出已经成功的将Churn做了离散化处理。

4.类别特征的描述性分析

特征列主要分两大阵容,类别变量和连续型变量,我们有两种方式把他们分离出来,第一种是直接一个一个drop掉,第二种方法是采用pandas里面提供的判断类别类型和数值型的方法,这里我们采用第二种方式。

data_columns=[]
for col in data.columns.drop(["customerID","Churn"]):
    # is_object_dtype:查看特征是否为类别类型,是的话往下执行;
    # is_numeric_dtype:查看类别是否是数值类型的,是的话就继续往下
    if pd.api.types.is_object_dtype
  • 17
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值