金融评分卡项目—5.神经网络模型在银行业客户流失预警模型中的应用—MLP



一、神经网络模型概述

  人工神经网络(ANN),它的基本特点是试图模仿大脑的神经元之间传递、处理信息的模式。其具有以下两个特性:

  • 每个神经元通过激活函数(非线性变换)来处理来自其他相邻神经元的加权输入值。
  • 神经元之间信息信息传递的强度,用权重来定义,神经网络训练就是不断的调整权重。

在这里插入图片描述

1.ANN的类型

  按照网络连接的拓扑结构,神经网络可以分为前向网络和反馈网络。
前向网络:

网络中各个神经元接受前一级的输入,并输出到下一级,网络中没有反馈,可以用一个有向无环路图来表示。这种网络实现了信号从输入空间到输出空间的变换,它的信息处理能力来自于简单非线性函数的多次复合,网络结构简单,易于实现。

反馈网络:

网络内神经元有反馈,可以用一个无向的完备图表示。这种神经网络的信息处理是状态的变化,可以用动力学系统理论处理。

2.感知机模型

单层感知机
**在这里插入图片描述**

前馈型多层感知机

原理部分见该博客,其实很简单

Softplus
Softplus(x) = a = log(1 + ex)
求导得:
Softplus`(x) = 1 - exp(-a)

在这里插入图片描述

  • 训练方法:反向传播
    输出层的误差反向传播到隐藏层迭代调整隐藏层的权重
  • 损失函数
    在这里插入图片描述

二、神经网络在流失预警模型中的应用

1.数据预处理

  • 不能有缺失值
    将异常值拉回正常状态,缺失值进行补缺
  • 移除常量型特征(即这个特征的最大值与最小值相等)
  • 不能接受非数值形式的输入,字符型变量需要编码

    One hot 编码
    Dummy编码
    浓度编码—比如在本案例中依据收入的高低进行浓度编码可以这样描述:收入分为高收入、中收入、低收入,标签分为流失与不流失。可以将收入中的高转变成高收入中的流失率,中收入与低收入同理

  • 变量的归一化/标准化

    归一化—[0,1]
    标准化—数据量大时,绝大多数数据在(-3,3)之间

2.参数设置

  • 输入层节点个数—特征数
  • 隐藏层层数
  • 隐藏层节点个数
  • 隐藏层联接状态
  • 激活函数
  • 损失函数
  • 学习速率
  • 迭代次数

3.代码部分

"""
@author: admin
@file: 流失预警模型—MLP.py
@time: 2021/03/06
@desc:
"""
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, losses, optimizers, metrics, Model, Sequential
from tensorflow.keras.layers import Input, Dense, BatchNormalization, Dropout, Lambda, GaussianNoise, Activation
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score, accuracy_score, auc
import operator
import matplotlib as mpl
import matplotlib.pyplot as plt

# from sklearn.preprocessing import Ma

# 加载数据
modelData = pd.read_csv('data/modelData.csv', header=0)
# 查看是否有空值
# print(sum(modelData.isnull().sum()))
allFeatures = list(modelData.columns)
# 删除id与标签
allFeatures.remove('CUST_ID')
allFeatures.remove('CHURN_CUST_IND')

constantFeatures = []


# 归一化:这个过程要找出常量型特征,所以自定义
def maxminscaler(df, col):
    mi, ma = min(df[col]), max(df[col])
    gap = ma - mi
    if gap == 0:
        return constantFeatures.append(col)
    df[col] = df[col].map(lambda x: (x - mi) * 1.0 / gap)


# 迭代进行归一化
for col in allFeatures:
    maxminscaler(modelData, col)

# 迭代删除常量型特征
print(constantFeatures)
# ['TELEBANK_ALL_TX_NUM', 'RATIO_21']
for col in constantFeatures:
    allFeatures.remove(col)

print(len(allFeatures))
# 数据集分割
x_train, x_test, y_train, y_test = train_test_split(modelData[allFeatures], modelData['CHURN_CUST_IND'], test_size=0.3,
                                                    shuffle=True, random_state=9)


# 定义多层感知机MLP模型
def MLP(input_dim, output_dim):
    input = Input(shape=input_dim)
    # 批归一化
    x = BatchNormalization()(input)
    hidden_units = [40, 50]
    for id, hidden_unit in enumerate(hidden_units):
        x = Dense(hidden_unit)(x)
        x = BatchNormalization()(x)
        x = Lambda(tf.keras.activations.relu)(x)
        x = Dropout(0.2)(x)

    x = Dense(output_dim, activation='sigmoid')(x)
    model = Model(inputs=input, outputs=x)
    model.compile(optimizer=optimizers.Adam(learning_rate=0.01),
                  loss=losses.BinaryCrossentropy(label_smoothing=0.05),
                  metrics=[tf.keras.metrics.AUC(name='auc')])
    return model


model = MLP(input_dim=175, output_dim=1)
# 训练模型
# 早停keras.callbacks.EarlyStopping
es = keras.callbacks.EarlyStopping(monitor='val_auc', patience=5)
history = model.fit(x_train, y_train, batch_size=128, epochs=100, validation_split=0.2,
                    callbacks=[es], verbose=2)

# 迭代打印训练情况
train_auc = history.history['auc']
val_auc = history.history['val_auc']
iter_epoch = len(train_auc)
fig = plt.figure(figsize=(8, 8))
ax = plt.subplot(111)
ax.plot(np.arange(iter_epoch), train_auc, label='train_auc')
ax.plot(np.arange(iter_epoch), val_auc, label='val_auc')
ax.set_title('train iter auc')
ax.set_ylabel('AUC')
ax.set_xlabel('epoch')
ax.legend(loc='upper right')
plt.show()

# 模型预测
y_pred = model.predict(x_test)
auc = roc_auc_score(y_test, y_pred)
print('测试集的auc为', auc)
Epoch 1/100
2021-03-06 20:47:41.902055: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_100.dll
9654/9654 - 1s - loss: 0.3206 - auc: 0.8415 - val_loss: 0.3068 - val_auc: 0.9660
Epoch 2/100
9654/9654 - 0s - loss: 0.2589 - auc: 0.9231 - val_loss: 0.3708 - val_auc: 0.7609
Epoch 3/100
9654/9654 - 0s - loss: 0.2430 - auc: 0.9422 - val_loss: 0.4170 - val_auc: 0.6296
Epoch 4/100
9654/9654 - 0s - loss: 0.2304 - auc: 0.9542 - val_loss: 0.3781 - val_auc: 0.9127
Epoch 5/100
9654/9654 - 0s - loss: 0.2157 - auc: 0.9646 - val_loss: 0.3078 - val_auc: 0.9951
Epoch 6/100
9654/9654 - 0s - loss: 0.2067 - auc: 0.9710 - val_loss: 0.2176 - val_auc: 0.9985
Epoch 7/100
9654/9654 - 0s - loss: 0.1984 - auc: 0.9756 - val_loss: 0.1559 - val_auc: 0.9994
Epoch 8/100
9654/9654 - 0s - loss: 0.1988 - auc: 0.9731 - val_loss: 0.1421 - val_auc: 0.9993

测试集的auc为 0.9988610867024407
测试集的准确率为 0.9899458623356535

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46649052/article/details/114446458