电信用户流失预测

任务描述:
随着电信行业的不断发展,运营商们越来越重视如何扩大其客户群体。据研究,获取新客户所需的成本远高于保留现有客户的成本,因此为了满足在激烈竞争中的优势,保留现有客户成为一大挑战。对电信行业而言,可以通过数据挖掘等方式来分析可能影响客户决策的各种因素,以预测他们是否会产生流失(停用服务、转投其他运营商等)
数据集:


image.png

电信用户流失预测中,运营商最为关心的是客户的召回率,即在真正流失的样本中,我们预测到多少条样本。

import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore') #  忽略弹出的warnings信息
data = pd.read_csv('./WA_Fn-UseC_-Telco-Customer-Churn.csv')
data.tail(10)

数据预处理

data.duplicated().sum()
(data['TotalCharges'] == ' ').sum()
drop_index = data.loc[data['TotalCharges'] == ' '].index
data.drop(labels=drop_index,axis=0,inplace=True)
data['TotalCharges'] = data['TotalCharges'].astype(dtype='float')
#发现只有4列为数值型特征,其中SeniorCitizen只有0,1组成可以视为类别特征,无需进行异常值处理
data.describe().T

使用箱型图对tenure、MonthlyCharges和TotalCharges进行异常值探索

import matplotlib.pyplot as plt
%matplotlib inline
a = plt.boxplot(data['tenure'],vert=False)
plt.title('tenure')
a = plt.boxplot(data['MonthlyCharges'],vert=False)
plt.title('MonthlyCharges')
a = plt.boxplot(data['TotalCharges'],vert=False)
plt.title('TotalCharges')
image.png

image.png

image.png

特征工程
特征抽取
在特征介绍图中观察如下几列特征的组成元素:
‘MultipleLines’,'OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies'
发现MultipleLines特征组成元素为:yes,no和No phone service
剩下几列特征的组成元素为:yes,no和No internet service,那么No phone service就表示no,所以可以将其修改为no,从而减少特征组成元素的数量,方便后期进行特征值化

data.loc[data['MultipleLines']=='No phone service', 'MultipleLines'] = 'No'
internetCols = ['OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies']
for i in internetCols:
    data.loc[data[i]=='No internet service', i] = 'No'

一些类别特征只有两类取值,可以直接用0、1代替
'Partner','Dependents','PhoneService','MultipleLines','OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies','PaperlessBilling'
顺便把目标变量也进行编码,直接用0、1代替

cols_name = ['Partner','Dependents','PhoneService','MultipleLines','OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies','PaperlessBilling']
for col in cols_name:
    data[col] = data[col].map({'Yes': 1, 'No': 0})
data['Churn'] = data['Churn'].map({'Yes': 1, 'No': 0})

其他无序的类别特征采用独热编码
'InternetService', 'Contract', 'PaymentMethod'

cols_name = ['InternetService', 'Contract', 'PaymentMethod']
for col in cols_name:
    oneHot_df = pd.get_dummies(data[col],prefix=col) 
    data = pd.concat(objs=[data,oneHot_df],axis=1)
#删除原来的列
data.drop(labels=cols_name,axis=1,inplace=True)

特征选择
'customerID'特征的每个特征值都不同,因此对模型预测不起贡献,可以直接删除。

data.drop(labels='customerID',axis=1,inplace=True)

通过可视化分析探测不重要的特征,进行特征选择
基本特征对客户流失影响
性别、是否老年人、是否有配偶、是否有家属特征对客户流失的影响(占比情况:例如在性别特征中,统计女性流失占不流失的比例and男性)
'gender', 'SeniorCitizen', 'Partner', 'Dependents'
这些特征的组成元素只有【是和否】
入网月数特征对客户流失的影响
‘tenure’
该特征的组成元素有多个

pd.crosstab(data['gender'], data['Churn'])
baseCols = ['gender', 'SeniorCitizen', 'Partner', 'Dependents']
for col in baseCols:
    col_df = pd.crosstab(data[col], data['Churn'])
    p_a = col_df.iloc[0][1] / col_df.iloc[0][0]
    p_b = col_df.iloc[1][1] / col_df.iloc[1][0]
    print(col,":",p_a,p_b)
image.png

由数据可知:性别对客户流失基本没有影响;年龄对客户流失有影响;是否有配偶对客户流失有影响;是否有家属对客户流失有影响。
观察流失率和入网月数之间的关系
计算不同入网月数对应的流失率(每月流失客户占当月总客户的比例)

s = data.groupby(by='tenure')['Churn'].sum() / data.groupby(by='tenure')['Churn'].count()
plt.plot(s.index,s.values)
plt.xlabel('month')
plt.ylabel('p')
image.png

发现:流失率随着入网时间的延长呈下降趋势

剩下的合约类型特征、业务类型特征同上进行分析即可,最终发现如下特征对目标标签没有影响,可以将其删除
'gender'、'PhoneService'、'StreamingTV' 和 'StreamingMovies'

data.drop(labels=['gender','PhoneService','StreamingTV','StreamingMovies'],axis=1,inplace=True)

可以对数据集中的三列连续型数值特征 'tenure', 'MonthlyCharges', 'TotalCharges' 计算相关系数.
如果存在较强相关性,因此可以考虑删除该列,以避免特征冗余

import seaborn as sns
nu_fea = data[['tenure', 'MonthlyCharges', 'TotalCharges']]    # 选择连续型数值特征计算相关系数
nu_fea = list(nu_fea)    # 特征名列表
pearson_mat = data[nu_fea].corr()    # 计算皮尔逊相关系数矩阵
plt.figure(figsize=(8,8)) # 建立图像
sns.heatmap(pearson_mat, square=True, annot=True, cmap="YlGnBu")    # 用热度图表示相关系数矩阵
plt.show() # 展示热度图
image.png

其中 'TotalCharges' 与其他两列特征的相关系数均大于0.6,即存在较强相关性,因此可以考虑删除该列

data.drop(labels='TotalCharges',axis=1,inplace=True)

类别不平衡问题处理
不同样本类别数量统计

p = data['Churn'].value_counts()
a = plt.pie(p,autopct='%.2f%%',labels=p.index)
image.png

由饼状图可见流失用户占比为26.54%,存在类别不平衡现象,需要进行相应处理。

from imblearn.over_sampling import SMOTE
s = SMOTE(k_neighbors=3)
x_cols = [col for col in data.columns if col != 'Churn']
X = data[x_cols]
y = data['Churn']
feature,target = s.fit_sample(X,y)

模型选择和评估
召回率代表的意义则是:在真正流失的样本中,我们预测到多少条样本。很明显,召回率是运营商们关心的指标,即宁可把未流失的客户预测为流失客户而进行多余的留客行为,也不漏掉任何一名真正流失的客户。

from sklearn.linear_model import LogisticRegression    # 逻辑回归
from sklearn.svm import SVC    # SVM
from sklearn.ensemble import RandomForestClassifier    # 随机森林
from sklearn.model_selection import train_test_split
from sklearn.metrics import recall_score, f1_score    

x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.2,random_state=2020)

lr = LogisticRegression()
svm = SVC()
rf = RandomForestClassifier()
model_list = [lr,svm,rf]
for model in model_list:
    model = model.fit(x_train,y_train)
    y_pred = model.predict(x_test)
    score = recall_score(y_test,y_pred)
    print(model,score)
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • 闲言碎语   决定转行做数据分析有3个月了,这段时间里学了SQL,Python,PowerBI,还掌握了电商和内容...
    SSS41260阅读 6,729评论 7 15
  • 1、研究背景 1、做好“用户流失预测”可以降低营销成本。老生常谈,“新客户开发成本”是“老客户维护成本”的5倍。2...
    L大肆阅读 1,131评论 0 0
  • 本文以电信行业数据为基础,对其进行用户流失预警的建模,整理如下,欢迎拍砖~ 一、流失知识点整理 1. 流失定义 不...
    茶小美阅读 4,416评论 1 11
  • 可视化分析报告见:报告全文 前言 无论是互联网还是传统行业,如何减少用户流失率都是企业在客户管理中的重要问题,谁的...
    siqizhang阅读 1,141评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,523评论 16 22