为了防止银行的客户流失,通过数据分析,识别并可视化哪些因素导致了客户流失,并通过建立一个预测模型,识别客户是否会流失,流失的概率有多大。以便银行的客户服务部门更加有针对性的去挽留这些流失的客户。
本任务的实践内容包括:
1、学习并熟悉Bagging算法原理。
2、使用决策树的聚合,创建预测银行客户流失率模型,并训练评估。
源码下载
操作系统:Windows 10、Ubuntu18.04
工具软件:Anaconda3 2019、Python3.7
硬件环境:无特殊要求
依赖库列表
scikit-learn 1.0.2
numpy 1.19.3
pandas 1.3.5
本任务涉及以下环节:
A)熟悉Bagging算法原理
B)加载并观察银行客户
C)创建决策树模型,进行训练,评估其准确率和F1分数
D)使用决策树聚合模型,进行训练,评估其准确率和F1分数
E)对比分析使用单个决策树和决策树聚合算法的模型效果
通过自助采样的方法生成众多并行的分类器,通过少数服从多数的原则确定最终结果。从同一样本、同一指标集里抽样,每次抽样都生成一棵简单树,可以并行建立。
典型算法:随机森林
随机森林基于bagging思想,解决决策树泛化的问题,决策树是一棵树,只有一个决策权,随机森林是多棵树,每棵树都有一个决策权,这样把所有树的结果综合起来,这样的分类能力,自然比单棵树的结果好。所以随机森林是基于这样的思想去分类的。随机森林的随机主要体现在两个方面,一个是随机选取样本,一个是随机选取特征。随机森林是根据特征构造多棵决策树,那每棵树是怎么构造的呢?它从训练样本中随机选取固定数量的样本集,然后随机选取固定数量的特征,来构造决策树,相当于样本集和特征集都是总样本和总特征中的子集。而且这个随机选取是有放回地抽取过程。这样每个决策树都有一个分类结果,根据少数服从多数的原则,得到最后的结果。这就是随机森林算法的核心内容。
import numpy as np # 基础线性代数扩展包
import pandas as pd # 数据处理工具箱
df_bank = pd.read_csv("../dataset/BankCustomer.csv") # 读取文件
df_bank.head() # 显示文件前5行
结果如下:
数据集特征说明:
name:客户姓名
Gender:客户性别
Age:客户年龄
City:城市
Tenure:用户时长
ProductsNo:使用产品数量
HasCard:是否拥有信用卡
ActiveMember:是否为活跃会员
Credit:信用评分
AccountBal:账户余额
Salary:薪资
Exited(标签):是否流失,1代表流失,0代表没有流失
将二元数据文本化,创建数据集。
# 把二元类别文本数字化
df_bank['Gender'].replace("Female",0,inplace = True)
df_bank['Gender'].replace("Male",1,inplace=True)
# 显示数字类别
print("Gender unique values",df_bank['Gender'].unique())
# 把多元类别转换成多个二元哑变量,然后贴回原始数据集
d_city = pd.get_dummies(df_bank['City'], prefix = "City")
df_bank = [df_bank, d_city]
df_bank = pd.concat(df_bank, axis = 1)
# 构建特征和标签集合
y = df_bank['Exited']
X = df_bank.drop(['Name', 'Exited', 'City'], axis=1)
X.head() #显示新的特征集
结果如下:
使用sklearn.model_selection.train_test_split()方法将数据集划分为训练集和测试集。
from sklearn.model_selection import train_test_split # 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, random_state=0)
创建单棵决策树模型和多棵决策树聚合模型,用相同的数据集进行训练和预测,比较两种模型的准确率。
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import (accuracy_score, f1_score, confusion_matrix)
dt = DecisionTreeClassifier() # 只使用一棵决策树
dt.fit(X_train, y_train) # 拟合模型
y_pred = dt.predict(X_test) # 进行预测
print("决策树测试准确率: {:.2f}%".format(dt.score(X_test, y_test) * 100))
print("决策树测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred) * 100))
bdt = BaggingClassifier(DecisionTreeClassifier()) # 树的Bagging
bdt.fit(X_train, y_train) # 拟合模型
y_pred = bdt.predict(X_test) # 进行预测
print("决策树Bagging测试准确率: {:.2f}%".format(bdt.score(X_test, y_test) * 100))
print("决策树Bagging测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred) * 100))
结果如下:
决策树测试准确率: 79.20%
决策树测试F1分数: 50.71%
决策树Bagging测试准确率: 85.20%
决策树Bagging测试F1分数: 56.98%
在这里比较了只使用一棵决策树和经过Bagging之后的树这两种算法的预测效果,可以看到决策树Bagging的准确率及F1分数明显占优势。当然,因为Bagging过程的随机性,每次测试的分数都稍有不同。