1 引言
近年来,各行各业往往都会不可避免地面临用户流失的问题。研究表明,发展新用户所花费的宣传、促销等成本显然高于维持老用户的成本,因此,做好"客户流失预警"可以有效降低营销成本,做到精准营销。
如今,随着运营商的竞争不断加剧,电信运营商亟需提高用户留存率、增加用户黏性,减少客户流失。因此,需要对电信客户进行流失分析与预测,发掘客户流失的原因,进而改善自身业务,提高用户的满意度,延长用户生命周期。
2 数据来源与数据概况
2.1 数据来源
数据来源kaggle电信用户流失数据集。
https://www.kaggle.com/blastchar/telco-customer-churn
2.2 数据概况
电信客户流失数据集描述了电信用户是否流失以及其相关信息,共包含7043条记录,21个字段。 读入数据集后,了解数据集的基本信息。
> telco.data <- read.csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
> # 展示数据集的前六行数据
> head(telco.data)
customerID gender SeniorCitizen Partner Dependents tenure PhoneService
1 7590-VHVEG Female 0 Yes No 1 No
2 5575-GNVDE Male 0 No No 34 Yes
3 3668-QPYBK Male 0 No No 2 Yes
4 7795-CFOCW Male 0 No No 45 No
5 9237-HQITU Female 0 No No 2 Yes
6 9305-CDSKC Female 0 No No 8 Yes
MultipleLines InternetService OnlineSecurity OnlineBackup DeviceProtection
1 No phone service DSL No Yes No
2 No DSL Yes No Yes
3 No DSL Yes Yes No
4 No phone service DSL Yes No Yes
5 No Fiber optic No No No
6 Yes Fiber optic No No Yes
TechSupport StreamingTV StreamingMovies Contract PaperlessBilling
1 No No No Month-to-month Yes
2 No No No One year No
3 No No No Month-to-month Yes
4 Yes No No One year No
5 No No No Month-to-month Yes
6 No Yes Yes Month-to-month Yes
PaymentMethod MonthlyCharges TotalCharges Churn
1 Electronic check 29.85 29.85 No
2 Mailed check 56.95 1889.50 No
3 Mailed check 53.85 108.15 Yes
4 Bank transfer (automatic) 42.30 1840.75 No
5 Electronic check 70.70 151.65 Yes
6 Electronic check 99.65 820.50 Yes
> # 数据集的维度
> dim(telco.data)
[1] 7043 21
每个字段的介绍如下表所示:
字段名 | 字段含义 | 字段内容 |
---|---|---|
customerID | 客户ID | |
gender | 性别 | Female & Male |
SeniorCitizen | 老年用户 | 1表示是,0表示不是 |
Partner | 伴侣用户 | Yes or No |
Dependents | 亲属用户 | Yes or No |
tenure | 在网时长 | 0-72月 |
PhoneService | 是否开通电话服务服务 | Yes or No |
MultipleLines | 是否开通多线服务 | Yes 、No or No phoneservice 三种 |
InternetService | 是否开通上网服务 | No, DSL数字网络,fiber optic光纤网络 |
OnlineSecurity | 是否开通网络安全服务 | Yes,No,No internetserive |
OnlineBackup | 是否开通在线备份服务 | Yes,No,No internetserive |
DeviceProtection | 是否开通设备保护服务 | Yes,No,No internetserive |
TechSupport | 是否开通技术支持服务 | Yes,No,No internetserive |
StreamingTV | 是否开通网络电视 | Yes,No,No internetserive |
StreamingMovies | 是否开通网络电影 | Yes,No,No internetserive |
Contract | 签订合同方式 | 按月,一年,两年 |
PaperlessBilling | 是否开通电子账单 | Yes or No |
PaymentMethod | 付款方式 | bank transfer,credit card,electronic check,mailed check |
MonthlyCharges | 月租费 | 18.85-118.35 |
TotalCharges | 累计付费 | 18.85-8684.8 |
Churn | 该用户是否流失 | Yes or No |
3 研究问题
- 分析用户特征与流失的关系
- 流失客户普遍具有哪些特征?
- 尝试找到合适的模型预测流失客户。
- 针对性给出增加用户黏性、降低客户流失率的建议。
4 数据预处理
查看数据集中每个变量的类型。
> str(telco.data)
'data.frame': 7043 obs. of 21 variables:
$ customerID : chr "7590-VHVEG" "5575-GNVDE" "3668-QPYBK" "7795-CFOCW" ...
$ gender : chr "Female" "Male" "Male" "Male" ...
$ SeniorCitizen : int 0 0 0 0 0 0 0 0 0 0 ...
$ Partner : chr "Yes" "No" "No" "No" ...
$ Dependents : chr "No" "No" "No" "No" ...
$ tenure : int 1 34 2 45 2 8 22 10 28 62 ...
$ PhoneService : chr "No" "Yes" "Yes" "No" ...
$ MultipleLines : chr "No phone service" "No" "No" "No phone service" ...
$ InternetService : chr "DSL" "DSL" "DSL" "DSL" ...
$ OnlineSecurity : chr "No" "Yes" "Yes" "Yes" ...
$ OnlineBackup : chr "Yes" "No" "Yes" "No" ...
$ DeviceProtection: chr "No" "Yes" "No" "Yes" ...
$ TechSupport : chr "No" "No" "No" "Yes" ...
$ StreamingTV : chr "No" "No" "No" "No" ...
$ StreamingMovies : chr "No" "No" "No" "No" ...
$ Contract : chr "Month-to-month" "One year" "Month-to-month" "One year" ...
$ PaperlessBilling: chr "Yes" "No" "Yes" "No" ...
$ PaymentMethod : chr "Electronic check" "Mailed check" "Mailed check" "Bank transfer (automatic)" ...
$ MonthlyCharges : num 29.9 57 53.9 42.3 70.7 ...
$ TotalCharges : num 29.9 1889.5 108.2 1840.8 151.7 ...
$ Churn : chr "No" "No" "Yes" "No" ...
4.1 因子变量处理
需要将该数据集中的部分变量转化为因子类型。
> telco.data <- within(telco.data,{
+ SeniorCitizen <- factor(SeniorCitizen, levels = c(0,1), labels = c("No", "Yes"))
+ Partner <- factor(Partner)
+ Dependents <- factor(Dependents)
+ })
> Factors <- c("gender", "PhoneService", "MultipleLines", "InternetService", "OnlineSecurity", "OnlineBackup", "DeviceProtection", "TechSupport", "StreamingTV", "StreamingMovies", "Contract", "PaperlessBilling", "PaymentMethod", "Churn")
> telco.data[Factors] <- lapply(telco.data[Factors],factor)
4.2 缺失值处理
从图中可以看出,TotalCharges列有11个缺失值,占比大约0.16%。
> colSums(is.na(telco.data))
customerID gender SeniorCitizen Partner
0 0 0 0
Dependents tenure PhoneService MultipleLines
0 0 0 0
InternetService OnlineSecurity OnlineBackup DeviceProtection
0 0 0 0
TechSupport StreamingTV StreamingMovies Contract
0 0 0 0
PaperlessBilling PaymentMethod MonthlyCharges TotalCharges
0 0 0 11
Churn
0
> library(VIM)
> par(cex = 0.72, font.axis = 3)
> VIM::aggr(telco.data, prop = TRUE, numbers = TRUE)
处理缺失值数据的一种方法是插补均值、中位数或者众数。
从直方图可知,TotalCharges数据呈偏态分布。根据正态分布选均值、中位数填充,偏态分布选中位数填充的原则,选择用TotalCharges列的中位数去填充这11个缺失值。
> hist(telco.data$TotalCharges, breaks = 50, prob = TRUE,
+ main = "Histogram Of TotalCharges")
> library(Hmisc)
> # 插补中位数
> telco.data$TotalCharges <- as.numeric(Hmisc::impute(telco.data$TotalCharges, median))
4.3 简化分类变量的属性值
OnlineSecurity、OnlineBackup、DeviceProtection、TechSupport、StreamingTV、StreamingMovies这六个变量的属性值有Yes、No、No internet serive 三种。
通过分析这六个变量和Churn生成的二维列联表,不难发现"No internetserive"出现 的频数是一致的,可以认为该属性值不影响客户流失率,所以简化属性值,将其并入"No"这一属性值。
> for(i in 10:15)
+ {
+ print(xtabs(~ Churn + get(names(telco.data)[i]), data = telco.data))
+ }
结果如下:
get(names(telco.data)[i])
Churn No No internet service Yes
No 2037 1413 1724
Yes 1461 113 295
get(names(telco.data)[i])
Churn No No internet service Yes
No 1855 1413 1906
Yes 1233 113 523
get(names(telco.data)[i])
Churn No No internet service Yes
No 1884 1413 1877
Yes 1211 113 545
get(names(telco.data)[i])
Churn No No internet service Yes
No 2027 1413 1734
Yes 1446 113 310
get(names(telco.data)[i])
Churn No No internet service Yes
No 1868 1413 1893
Yes 942 113 814
get(names(telco.data)[i])
Churn No No internet service Yes
No 1847 1413 1914
Yes 938 113 818
> # 将“No internetserive”并入“No”这一属性值
> levels(telco.data$OnlineSecurity)[2] <- "No"
> levels(telco.data$OnlineBackup)[2] <- "No"
> levels(telco.data$DeviceProtection)[2] <- "No"
> levels(telco.data$TechSupport)[2] <- "No"
> levels(telco.data$StreamingTV)[2] <- "No"
> levels(telco.data$StreamingMovies)[2] <- "No"
4.4 处理"量纲差异大"
目前属于这类特征的变量有:MonthlyCharges和TotalCharges。我打算采用连续特征离散化的处理方式。原因是离散化后的特征对异常数据有更强的鲁棒性,降低过拟合的风险,模型会更稳定,预测的效果也会更好。
数据离散化也称为分箱操作,其方法分为有监督分箱(卡方分箱、最小熵法分箱)和无监督分箱(等频分箱、等距分箱)。 本次为采用无监督分箱中的等频分箱进行操作。
> library