1. 数据集介绍
- AT&T数据,用户个人,通话,上网等信息数据
- 充分利用数据预测客户的流失情况
- 帮助挽留用户,保证用户基数和活跃程度
具体数据说明如下:
- CustomerID 客户ID
- Gender 性别
- partneratt 配偶是否也为att用户
- dependents_att 家人是否也是att用户
- landline 是否使用att固话服务
- internet_att/internet_other 是否使用att的互联网服务
- Paymentbank/creditcard/electroinc 付款方式
- MonthlyCharges 每月话费
- TotalCharges 累计话费
- Contract_month/1year 用户使用月度/年度合约
- StreamingTv/streamingMovies 是否使用在线视频或者电影app
- Churn 客户转化的flag
2. 处理流程
分析流程:数据概况分析->单变量分析->可视化->逻辑回归模型
数据概况分析
- 数据行/列数量
- 缺失值分布
单变量分析
- 数字型变量的描述指标(平均值,最大最小值,标准差)
- 类别型变量(多少个分类,各自占比)
- 正负样本占比
相关性分析与可视化
- 按类别交叉对比
- 变量之间的相关性分析
- 散点图/热力图
逻辑回归分析
- 模型建立
- 模型评估与优化
3. 案例实现
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
churn=pd.read_csv('data/churn.csv')
churn.info()
输出结果:
RangeIndex: 7043 entries, 0 to 7042
Data columns (total 16 columns):
Churn 7043 non-null object
gender 7043 non-null object
Partner_att 7043 non-null int64
Dependents_att 7043 non-null int64
landline 7043 non-null int64
internet_att 7043 non-null int64
internet_other 7043 non-null int64
StreamingTV 7043 non-null int64
StreamingMovies 7043 non-null int64
Contract_Month 7043 non-null int64
Contract_1YR 7043 non-null int64
PaymentBank 7043 non-null int64
PaymentCreditcard 7043 non-null int64
PaymentElectronic 7043 non-null int64
MonthlyCharges 7043 non-null float64
TotalCharges 7043 non-null float64
dtypes: float64(2), int64(12), object(2)
memory usage: 880.5+ KB
#预测目标是churn,是类别型变量 gender也是类别型变量 需要对类别型变量进行处理
churn.head()
输出结果:
Churn gender Partner_att Dependents_att landline internet_att
0 No Female 1 0 0 1
1 No Male 0 0 1 1
2 Yes Male 0 0 1 1
3 No Male 0 0 0 1
4 Yes Female 0 0 1 0
internet_other StreamingTV StreamingMovies Contract_Month Contract_1YR
0 0 0 0 1 0
1 0 0 0 0 1
2 0 0 0 1 0
3 0 0 0 0 1
4 1 0 0 1 0
PaymentBank PaymentCreditcard PaymentElectronic MonthlyCharges
0 0 0 1 29.85
1 0 0 0 56.95
2 0 0 0 53.85
3 1 0 0 42.30
4 0 0 1 70.70
TotalCharges
0 29.85
1 1889.50
2 108.15
3 1840.75
4 151.65
需要把churn和gender转变为数字型变量,使用get_dummies
churn=pd.get_dummies(churn)
churn.head()
输出结果:
Churn_No Churn_Yes gender_Female gender_Male
0 1 0 1 0
1 1 0 0 1
2 0 1 0 1
3 1 0 0 1
4 0 1 1 0
数据整理,将churn_yes保留,将female保留,drop不需要的数据
churn.drop(['Churn_No','gender_Male'],axis=1,inplace=True)
#变量大小写不规则,统一变成小写
churn.columns=churn.columns.str.lower()
churn.head()
输出结果
churn_yes gender_female
0 0 1
1 0 0
2 1 0
3 0 0
4 1 1
将churn_yes重命名
churn=churn.rename(columns={'churn_yes':'flag'})
#二分类模型,分析flag 1和0的占比
churn.flag.value_counts()
输出结果:
0 5174
1 1869
Name: flag, dtype: int64
churn.flag.value_counts(1)
输出结果:
0 0.73463
1 0.26537
Name: flag, dtype: float64
按照标签进行分组,查看不同标签分组的平均值
summary=churn.groupby('flag')
summary.mean()
输出结果:
partner_att dependents_att landline internet_att internet_other
flag
0 0.528218 0.344801 0.901044 0.379204 0.347700
1 0.357945 0.174425 0.909042 0.245586 0.693954
streamingtv streamingmovies contract_month contract_1yr paymentbank
flag
0 0.365868 0.369927 0.429068 0.252609 0.248550
1 0.435527 0.437667 0.885500 0.088818 0.138042
paymentcreditcard paymentelectronic monthlycharges totalcharges
flag
0 0.249324 0.250097 61.265124 2545.918081
1 0.124131 0.573034 74.441332 1528.514714
gender_female
flag
0 0.492656
1 0.502408
观察flag在0和1的情况下,所有自变量的差别 internet_other变量,在0的分组中,均值是0.35,在1的分组中,均值是0.69。数据显示如果使用别的公司的互联网,用户流失的概率就越高
sns.countplot(y='contract_month',hue='flag',data=churn)
结论:contract_month为1的客户流失的概率更高,即与非按月付费客户相比,按月付费客户流失比例高
逻辑回归模型
自变量可以分为几类,partner/dependents,internet,streaming,contract,payment,charges,后续大家可以自己挑选进行建模
这里先选取几个contract_month,internet_other与streamingtv
# 确定目标值和特征值
y=churn['flag']
x=churn[['contract_month','internet_other','streamingtv']]
#调用sklearn模块,随机抽取训练集与测试集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=100)
#使用sklearn
from sklearn import linear_model
lr=linear_model.LogisticRegression()
lr.fit(x_train,y_train)
模型的评估
y_pred_train=lr.predict(x_train)
y_pred_test=lr.predict(x_test)
import sklearn.metrics as metrics
metrics.accuracy_score(y_train,y_pred_train)
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, y_pred_test)
参数调整
从Y标签的类别分布上看,未流失用户为:5174 流失用户为:1869,属于样本分布不均衡问题,我们可以通过调整逻辑回归的模型参数来为占比较低的类别增加权重
LogisticRegression(class_weight='balanced')
除此之外我们可以进一步通过网格搜索来调整其它参数
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import GridSearchCV
kfold = StratifiedKFold(n_splits=5, shuffle=True)
lr = linear_model.LogisticRegression()
param_grid = {'solver': ['newton-cg', 'lbfgs', 'liblinear'],
'C': [0.001, 0.01, 1, 10, 100],'class_weight':['balanced']}
search = GridSearchCV(lr, param_grid, cv=kfold)
lr = search.fit(x_train, y_train)
我们打印获取到的最优参数组合
lr.best_params_
{‘C’: 1, ‘class_weight’: ‘balanced’, ‘solver’: ‘newton-cg’}
查看模型的回归系数
# x=churn[['contract_month','internet_other','streamingtv']]
lr.coef_
[[2.25630305 1.12102112 0.28519637]]
从结果中反应了特征重要性, contract_month 重要性最高,internet_other 其次,为了降低流失率,可以考虑针对月付费用户以及使用它网宽带的用户做针对性的营销
4. 小结
本小节,我们使用了逻辑回归算法做了用户流失分析的案例
- 除了直接预测用户是否会流失之外, 还可以利用模型中的回归系数得出对业务有帮助的建议
- 当样本类别分布不均衡时(如本例中,0样本是数量是5174,1样本数量是1869),可以通过添加参数class_weight=’balanced’来增加样本占比较低类别的权重