Stacking算法预测银行客户流失率

Stacking算法预测银行客户流失率

描述

为了防止银行的客户流失,通过数据分析,识别并可视化哪些因素导致了客户流失,并通过建立一个预测模型,识别客户是否会流失,流失的概率有多大。以便银行的客户服务部门更加有针对性的去挽留这些流失的客户。

本任务的实践内容包括:

1、学习并熟悉Stacking/Blending算法原理。

2、使用Stacking算法预测银行客户流失率。

源码下载

环境

  • 操作系统:Windows 10、Ubuntu18.04

  • 工具软件:Anaconda3 2019、Python3.7

  • 硬件环境:无特殊要求

  • 依赖库列表

    scikit-learn	1.0.2
    numpy           1.19.3
    pandas          1.3.5
    

分析

本任务涉及以下环节:

A)熟悉Stacking/Blending算法原理

B)加载并观察银行客户

C)使用决策树分类器和KNN分类器模型,分别生成预测结果

D)把上面的预测结果连接成一个新的特征集,标签则保持不变,用回原始的标签集

E)最后使用逻辑回归算法对新的特征集进行分类预测

实施

1、Stacking/Blending算法原理

1.1 Stacking算法

Stacking算法的思路是使用初始训练集学习若干个基模型之后,用这几个基模型的预测结果作为新的训练集的特征来训练新模型。Stacking算法的流程如下图所示:

请添加图片描述

这些基模型在异质类型中进行选择,比如决策树、KNN、SVM或神经网络等,都可以组合在一起。

Stacking具体步骤如图:

请添加图片描述

Stacking具体步骤如下:

(1)通常把训练集拆成K折(请大家回忆第1课中介绍过的K折验证)

(2)利用K折验证的方法在K-1折上训练模型,在第K折上进行验证

(3)这样训练K次之后,用训练好的模型对训练集整体进行最终训练,得到一个基模型

(4)使用基模型预测训练集,得到对训练集的预测结果

(5)使用基模型预测测试集,得到对测试集的预测结果

(6)重复步骤(2)~(5),生成全部基模型和预测结果(比如CART、KNN、SVM以及神经网络,4组预测结果)

(7)只需要用训练集预测结果作为新训练集的特征,测试集预测结果作为新测试集的特征去训练新模型。新模型的类型不必与基模型有关联

1.2 Blending算法

Blending的思路和Stacking几乎是完全一样的,唯一的不同之处在于Blending的过程中不进行k折验证,而是只将原始样本训练集分为训练集和验证集,然后只针对验证集进行预测,生成的新训练集就只是对于验证集的预测结果,而不是对全部训练集生成的预测结果。Blending集成的流程如图所示:

请添加图片描述

2、加载分析银行客户数据集

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代表没有流失

3、数据处理

将二元数据文本化,创建数据集。

# 把二元类别文本数字化
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() #显示新的特征集

结果如下:

请添加图片描述

4、拆分数据集

使用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)

5、Stacking算法实现

定义函数,实现Stacking算法流程。

from sklearn.model_selection import StratifiedKFold

'''
train:训练集特征
y:训练集标签
test:测试集
'''

def Stacking(model, train, y, test, n_fold):
    folds = StratifiedKFold(n_splits=n_fold, random_state=None)
    test_pred = np.empty((0, 1), float)
    train_pred = np.empty((0, 1), float)

    for train_indices, val_indices in folds.split(train, y.values):   # 将测试集特征和标签划分为n个子集
        X_train, x_val = train.iloc[train_indices], train.iloc[val_indices]   # X_train:训练集特征, x_val:验证集特征
        y_train, y_val = y.iloc[train_indices], y.iloc[val_indices]          # y_train:训练集标签, y_val:验证集标签
        model.fit(X=X_train, y=y_train)

        train_pred = np.append(train_pred, model.predict(x_val))  # 验证集预测
        test_pred = np.append(test_pred, model.predict(test))   # 传入的测试集预测

    return test_pred, train_pred

6、训练基模型

创建决策树分类器模型和KNN分类器模型,用刚才定义的Stacking函数训练两个模型:

from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier

model1 = DecisionTreeClassifier(random_state=1)
test_pred1, train_pred1 = Stacking(model=model1, n_fold=10,
                                   train=X_train, test=X_test, y=y_train)
train_pred1 = pd.DataFrame(train_pred1)
test_pred1 = pd.DataFrame(test_pred1)

model2 = KNeighborsClassifier()
test_pred2, train_pred2 = Stacking(model=model2, n_fold=10,
                                   train=X_train, test=X_test, y=y_train)
train_pred2 = pd.DataFrame(train_pred2)
test_pred2 = pd.DataFrame(test_pred2)

7、分类预测

把上面的预测结果连接成一个新的特征集,标签则保持不变,用回原始的标签集。最后使用逻辑回归算法对新的特征集进行分类预测:

from sklearn.linear_model import LogisticRegression

df = pd.concat([train_pred1, train_pred2], axis=1)    # (8000,2)
df_test = pd.concat([test_pred1, test_pred2], axis=1)   # (20000,2)

a = y_test
for i in range(9):
    y_test = pd.concat([y_test, a], axis=0)

model = LogisticRegression(random_state=1)
model.fit(df, y_train)
print(model.score(df_test, y_test))

结果如下:

0.7915

猜你喜欢

转载自blog.csdn.net/qq_40186237/article/details/130147809