摘要:
合集:AI案例-ML-零售业
赛题:电信客户流失预测挑战赛
主办方:科大讯飞
主页:https://challenge.xfyun.cn/topic/info?type=telecom-customer
AI问题:分类问题
数据集:某通信运营公司的3,333条客户信息和使用情况数据。
数据集价值:电信客户流失预测
解决方案:多种分类方法包括LogisticRegression(逻辑回归)、LinearDiscriminantAnalysis(线性判别分析)、
KNeighborsClassifier(K近邻)、DecisionTreeClassifier(决策树)、
GaussianNB(高斯朴素贝叶斯)、SVC(支持向量机)、集成方法(RandomForest, GradientBoosting, AdaBoost, Bagging)
一、赛题描述
随着市场饱和度的上升,电信运营商的竞争也越来越激烈,电信运营商亟待解决减少用户流失,延长用户生命周期的问题。对于客户流失率而言,每增加5%,利润就可能随之降低25%-85%。因此,如何减少电信用户流失的分析与预测至关重要。
鉴于此,运营商会经常设有客户服务部门,该部门的职能主要是做好客户流失分析,赢回高概率流失的客户,降低客户流失率。某电信机构的客户存在大量流失情况,导致该机构的用户量急速下降。面对如此头疼的问题,该机构将部分客户数据开放,诚邀大家帮助他们建立流失预测模型来预测可能流失的客户。
给定某电信机构实际业务中的相关客户信息,包含69个与客户相关的字段,其中“是否流失”字段表明客户会否会在观察日期后的两个月内流失。任务目标是通过训练集训练模型,来预测客户是否会流失,以此为依据开展工作,提高用户留存。
本案例对某通信运营公司的 3,333 条客户信息做出分析和预测。
二、数据集说明
每条数据有 20 个特征项,其中1 个类别项 (churn)为是否流失分类。特征字段包括:客户ID、地理区域、是否双频、是否翻新机、当前手机价格、手机网络功能、婚姻状况、家庭成人人数、信息库匹配、预计收入、信用卡指示器、当前设备使用天数、在职总月数、家庭中唯一订阅者的数量、家庭活跃用户数、……. 、过去六个月的平均每月使用分钟数、过去六个月的平均每月通话次数、过去六个月的平均月费用、是否流失。
数据样例如下:
state | account length | area code | international plan | phone number | voice mail plan | number vmail messages | total day minutes | total day calls | total day charge | total eve minutes | total eve calls | total eve charge | total night minutes | total night calls | total night charge | total intl minutes | total intl calls | total intl charge | customer service calls | churn |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
KS | 128 | 415 | no | 382-4657 | yes | 25 | 265.1 | 110 | 45.07 | 197.4 | 99 | 16.78 | 244.7 | 91 | 11.01 | 10 | 3 | 2.7 | 1 | FALSE |
OH | 107 | 415 | no | 371-7191 | yes | 26 | 161.6 | 123 | 27.47 | 195.5 | 103 | 16.62 | 254.4 | 103 | 11.45 | 13.7 | 3 | 3.7 | 1 | FALSE |
NJ | 137 | 415 | no | 358-1921 | no | 0 | 243.4 | 114 | 41.38 | 121.2 | 110 | 10.3 | 162.6 | 104 | 7.32 | 12.2 | 5 | 3.29 | 0 | FALSE |
OH | 84 | 408 | yes | 375-9999 | no | 0 | 299.4 | 71 | 50.9 | 61.9 | 88 | 5.26 | 196.9 | 89 | 8.86 | 6.6 | 7 | 1.78 | 2 | FALSE |
OK | 75 | 415 | yes | 330-6626 | no | 0 | 166.7 | 113 | 28.34 | 148.3 | 122 | 12.61 | 186.9 | 121 | 8.41 | 10.1 | 3 | 2.73 | 3 | FALSE |
AL | 118 | 510 | yes | 391-8027 | no | 0 | 223.4 | 98 | 37.98 | 220.6 | 101 | 18.75 | 203.9 | 118 | 9.18 | 6.3 | 6 | 1.7 | 0 | FALSE |
数据集版权许可协议
BY-NC-SA 4.0
https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans
三、解决方案样例
解决方案
使用多种分类方法包括LogisticRegression(逻辑回归)、LinearDiscriminantAnalysis(线性判别分析)、 KNeighborsClassifier(K近邻)、DecisionTreeClassifier(决策树)、 GaussianNB(高斯朴素贝叶斯)、SVC(支持向量机)、集成方法(RandomForest, GradientBoosting, AdaBoost, Bagging)。
安装开发包
【本样例运行环境的关键版本信息】
python 3.12.3
sklearn-compat 0.1.3
导入相关系统库
import pandas as pd
import numpy as np
import itertools
import pickle
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score
from sklearn.metrics import f1_score
from sklearn.metrics import recall_score
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
处理流程
- 数据加载与探索:了解数据基本情况,查看类别分布
- 可视化分析:通过图表直观展示数据特征
- 数据预处理:标准化特征值
- 机器学习准备:导入了多种机器学习算法和评估工具
- 模型训练:使用多种算法训练模型
- 模型评估:通过交叉验证和多种指标评估模型性能
- 结果分析:选择最佳模型进行客户流失预测
1、数据加载与探索
- 数据读取:使用pandas读取CSV格式的客户数据(churn.csv),并为各列指定了有意义的名称
- 数据探索:
- 查看数据形状(3333行×21列)
- 统计流失客户数量(False:2850, True:483)
- 可视化分析客服电话次数分布
# 打开文件,并对每列重新命名,返回的是原始数据
names = ['state', 'acc_length', 'area', 'ph_num', 'inter_plan', 'vm_plan', 'num_vm_message', 'day_min',
'day_calls', 'day_charge', 'eve_min', 'eve_calls', 'eve_charge', 'night_min', 'night_calls',
'night_charge', 'inter_min', 'inter_calls', 'inter_charge', 'cus_ser_calls', 'churn']
all_data = pd.read_csv("./data/churn.csv", names=names, header=0)
pd.set_option('display.max_columns', 30)
pd.set_option('display.precision', 3)
2、可视化分析
# 对数据特征进行可视化,由图可知,在电话时长、电话次数、电话费用以及国际电话等方面其频率图几乎都符合于高斯分布
fig = plt.figure()
fig.set(alpha=0.8)
fig.add_subplot(121)
all_data['churn'].value_counts().plot(kind='bar') # 对churn进行统计,查看流失与未流失的用户数量
plt.title('Churn True or False')
fig.add_subplot(122)
all_data['cus_ser_calls'].value_counts().plot(kind='bar') # 对拨打客服电话次数进行统计
plt.title('Customer service calls times')
3、标准化特征值
数据集包含的特征包括:
- 客户基本信息(state, acc_length, area等)
- 服务计划(inter_plan, vm_plan)
- 通话行为(day_min, day_calls, day_charge等)
- 客服联系情况(cus_ser_calls)
- 目标变量(churn)
标准化特征值:StandardScaler
data_result = all_data['churn']
y = np.where(data_result==True, 1, 0)
new_inter = pd.get_dummies(all_data['inter_plan'], prefix='_inter_plan')
new_vm_plan = pd.get_dummies(all_data['vm_plan'], prefix='_vm_plan')
data_temp = pd.concat([all_data, new_inter, new_vm_plan], axis=1)
to_drop = ['state', 'area', 'ph_num', 'inter_plan', 'vm_plan', 'churn']
data_df = data_temp.drop(to_drop, axis=1)
array = data_df.values
std = StandardScaler()
X = std.fit_transform(array)
4、机器学习准备
导入了多种机器学习算法和评估工具:
- 分类算法:
- LogisticRegression(逻辑回归)
- LinearDiscriminantAnalysis(线性判别分析)
- KNeighborsClassifier(K近邻)
- DecisionTreeClassifier(决策树)
- GaussianNB(高斯朴素贝叶斯)
- SVC(支持向量机)
- 集成方法(RandomForest, GradientBoosting, AdaBoost, Bagging)
- 评估指标:
- confusion_matrix(混淆矩阵)
- precision_score(精确率)
- f1_score(F1分数)
- recall_score(召回率)
- precision_recall_curve(PR曲线)
- roc_curve(ROC曲线)
- auc(AUC值)
- 交叉验证:KFold, cross_val_score
# 比较六种算法的准确度,画出箱型图,在运行中系统对 Logistics 和 LDA 都进行了变量之间共线的提示
# 从最终的箱型图来看,在这个问题上 CART 和 SVM 两种算法都好于其他的几种算法,所以优先选择 CART 和 SVM
models = list()
models.append(('LR', LogisticRegression()))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
models.append(('SVM', SVC()))
result = []
names = []
kfo = KFold(n_splits=10, shuffle=True, random_state=1)
for name, model in models:
cro_result = cross_val_score(model, X, y, scoring='accuracy', cv=kfo)
result.append(cro_result)
names.append(name)
msg = ("{}: {:3f}\t({:3f})".format(name, cro_result.mean(), cro_result.std()))
print(msg)
fig = plt.figure()
fig.suptitle('Algorithm to compare')
ax = fig.add_subplot(111)
plt.boxplot(result)
plt.ylabel('accuracy')
ax.set_xticklabels(names)
plt.show()
输出:
LR: 0.860795 (0.014757)
LDA: 0.852392 (0.011603)
KNN: 0.894688 (0.017012)
CART: 0.913283 (0.022192)
NB: 0.857196 (0.014240)
SVM: 0.919293 (0.014107)
5、比较各种算法并训练模型
# 创建并训练模型
kfo = KFold(n_splits=10, shuffle=True, random_state=1)
X_tranin, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=1)
gb_model = GradientBoostingClassifier(n_estimators=300, learning_rate=0.1)
gb_model.fit(X_tranin, y_train)
cv_result = cross_val_score(gb_model, X_tranin, y_train, cv=kfo)
gb_model.fit(X_tranin, y_train)
6、保存/加载模型数据并评估
# 将模型以文件的形式保存到本地
pickle.dump(gb_model, open('./final_model.sav', 'wb'))
# 读取本地的模型文件
model_load = pickle.load(open('./final_model.sav', 'rb'))
# 评估模型在训练数据上的表现
result = model_load.score(X, y)
print(result)
输出:0.9813981398139814
7、结果分析
- 数据集显示客户流失率为约14.5%(483/3333)
- 客服电话次数(cus_ser_calls)的分布显示大多数客户拨打客服电话次数较少
- 电话时长、电话次数、电话费用等特征呈现近似高斯分布
源码开源协议
GPL-v3