银行客户流失预测(BP神经)


目录

1、概述

2、数据集准备

3、实验部分

        3.1 模块加载

         3.2 数据读取

        3.3 构建向量

                训练集数据

                标签数据

         3.4 数据编码

        3.5 网络结构设计

                 使用到的函数

                网络结构

                 损失函数

                正确率

                优化器

        3.6 网络训练


1、概述

        前馈神经网络(feedforward neural network),简称前馈网络,是人工神经网络的一种。在此种神经网络中,各神经元从输入层开始,接收前一级输入,并输入到下一级,直至输出层。整个网络中无反馈,可用一个有向无环图表示。前馈神经网络是最早被提出的人工神经网络,也是最简单的人工神经网络类型。按照前馈神经网络的层数不同,可以将其划分为单层前馈神经网络和多层前馈神经网络。常见的前馈神经网络有感知机(Perceptrons)、BP(Back Propagation)网络、RBF(Radial Basis Function)网络等。

2、数据集准备

owNumber
行号
CustomerID
用户编号
Surname
用户姓名
CreditScore
信用分数
Geography
用户所在国家 / 地区
Gender
用户性别
Age
年龄
Tenure
当了本银行多少年用户
Balance
存贷款情况
NumOfProducts
使用产品数量
HasCrCard
是否有本行信用卡
IsActiveMember
是否活跃用户
EstimatedSalary
估计收入
Exited
是否已流失,这将作为我
们的标签数据

        训练集:select-data.csv

        测试集:scalar-test.csv

3、实验部分

        3.1 模块加载

import numpy as np
import tensorflow.compat.v1 as tf
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.font_manager import FontProperties
import os
from sklearn.preprocessing import OneHotEncoder

        3.2 数据读取

curentPath = os.getcwd()
print(curentPath)
df = pd.read_csv("../data/loss_of_silver_customers/select-data.csv");
df_test = pd.read_csv("../data/loss_of_silver_customers/scalar-test.csv");

         3.3 构建向量

train = []
target = []
for i in range(0,len(df["EstimatedSalary"])):
    mid = []
    mid.append(df["Geography"][i])
    mid.append(df["Gender"][i])
    mid.append(df["EB"][i])
    mid.append(df["Age"][i])
    mid.append(df["EstimatedSalary"][i])
    mid.append(df["NumOfProducts"][i])
    mid.append(df["CreditScore"][i])
    mid.append(df["Tenure"][i])
    mid.append(df["HasCrCard"][i])
    mid.append(df["IsActiveMember"][i])
    target.append(df["Exited"][i]);
    train.append(mid);
train = np.array(train);
target = np.array(target);
       训练集数据:

         标签数据:

         3.4 数据编码

#随机打乱训练集与标签
np.random.shuffle(train)
print(train)
np.random.shuffle(target)
print(target)
target = target.reshape(-1,1)
test_target = test_target.reshape(-1,1)
print(target)
print(test_target)
#one-hot编码
enc = OneHotEncoder()
enc.fit(test_target)
test_target = enc.transform(test_target).toarray()
print(test_target)
enc.fit(target)
target = enc.transform(target).toarray()
print(target)

        3.5 网络结构设计

#定义输入占位符
tf.disable_eager_execution()
x=tf.placeholder(tf.float32,shape=(None,10))
#二分类问题[0,1]
y=tf.placeholder(tf.float32,shape=(None,2))
keep = tf.placeholder(tf.float32)
        使用到的函数:

tf.truncated_normal

truncated_normal(
    shape,
    mean=0.0,
    stddev=1.0,
    dtype=tf.float32,
    seed=None,
    name=None
)
功能说明:
产生截断正态分布随机数,取值范围为 [ mean - 2 * stddev, mean + 2 * stddev ]。
参数名    必选    类型    说明
shape    是     1 维整形张量或 array      输出张量的维度
mean    否    0 张量或数值            均值
stddev    否    0 维张量或数值         标准差
dtype    否    dtype               输出类型
seed    否    数值                 随机种子,若 seed 赋值,每次产生相同随机数
name    否    string               运算名称
///
tf.zeros

tf.zeros(
    shape,
    dtype=tf.float32,
    name=None
)
函数参数:

shape:整数、整数元组或类型为int32的1维Tensor的列表.
dtype:结果Tensor中元素的类型.
name:操作的名称(可选).
函数返回值:

tf.zeros函数返回将所有元素设置为零的张量
/
tf.nn.dropout(
    x,
    keep_prob,
    noise_shape=None,
    seed=None,
    name=None
)
参数:

x:一个浮点型Tensor.
keep_prob:一个标量Tensor,它与x具有相同类型.保留每个元素的概率.
noise_shape:类型为int32的1维Tensor,表示随机产生的保持/丢弃标志的形状.
seed:一个Python整数.用于创建随机种子.
name:此操作的名称(可选).

返回:

该函数返回与x具有相同形状的Tensor.

可能引发的异常:

ValueError:如果keep_prob不在(0, 1]或如果x不是浮点型Tensor.

        网络结构:
#定义网络结构
#layer1
var1 = tf.Variable(tf.truncated_normal([10,256],stddev=0.1))
bias1 = tf.Variable(tf.zeros(256));
hc1= tf.add(tf.matmul(x,var1),bias1)
h1=tf.sigmoid(hc1)
h1 = tf.nn.dropout(h1,keep_prob=keep)
#layer2
var2 = tf.Variable(tf.truncated_normal([256,256],stddev=0.1))
bias2 = tf.Variable(tf.zeros(256));
hc2= tf.add(tf.matmul(h1,var2),bias2)
h2=tf.sigmoid(hc2)
h2 = tf.nn.dropout(h2,keep_prob=keep)

tf.nn.softmax(
    logits, # 输入:全连接层(往往是模型的最后一层)的值,一般代码中叫做logits
    axis = None,
    name = None
    dim = None
)
函数的参数说明如下:

logits:需要进行softmax操作的张量,可以任意维度。
axis:指定进行softmax操作的维度,默认为None,此时将进行最后一维的softmax操作。

作用:softmax函数的作用就是归一化。
输入:全连接层(往往是模型的最后一层)的值,一般代码中叫做logits
输出:归一化的值,含义是属于该位置的概率,一般代码叫做probs,例如输出[0.4, 0.1, 0.2, 0.3],那么这个样本最可能属于第0个位置,也就是第0类。这是由于logits的维度大小就设定的任务的类别,所以第0个位置就代表第0类。softmax函数的输出不改变维度的大小。(该样本属于各个类的概率)
用途:如果做单分类的问题,那么输出的值就取top1(最大, argmax); 如果做多分类问题,那么输出的值就取topN。

#layer3
var3 = tf.Variable(tf.truncated_normal([256,2],stddev=0.1))
bias3 = tf.Variable(tf.zeros(2));
hc3 = tf.add(tf.matmul(h2,var3),bias3)
h3 = tf.nn.softmax(hc3)
        损失函数:

tf.nn.softmax_cross_entropy_with_logits_v2(_sentinel, labels, logits, dim, name)  

计算 softmax(logits) 和 labels 之间的交叉熵

参数:_sentinel -->内部,一般不使用。

            labels       --> 真实数据的类别标签

            logits        -->神经网络最后一层的类别预测输出值

            dim           --> 类维度。默认为-1,这是最后一个维度。

一般用于交叉熵损失函数的设定:

cross_entropy_loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits = y, labels = y_))
///
tf.reduce_mean
tf.reduce_mean(
    input_tensor,
    axis=None,
    keep_dims=False,
    name=None,
    reduction_indices=None)
释义:用于计算tensor(张量)沿着指定的数轴(即tensor的某一维度)上的平均值,用作降维或者计算tensor的平均值
参数:
input_tensor:输入的tensor
axis:指定的轴,axis=0沿列进行求均值,axis=1沿行进行求均值,若不指定,则计算所有元素的均值
keep_dims:是否将维度,默认为False,输出结果会降低维度;若设置为True,输出的结果保持输入tensor的形状
name:操作的名称

        

#定义损失
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=h3,labels=y))
tf.summary.scalar("loss",loss)
        正确率:

tf.argmax
tf.argmax(
    input,
    axis=None,
    name=None,
    dimension=None,
    output_type=tf.int64
)
释义:主要功能是找出最大值并返回索引
参数:
input代表输入的数组
axis代表张量的最大维数0代表1维,1代表行二维为None(0)
name代表操作的名称,默认为None
dimension:按某维度查找。0代表列,1代表行默认为None(0)。
output_type,为输出的数据类型,可以指定
//
tf.cast(x, dtype, name=None)
释义:数据类型转换
x,输入张量
dtype,转换数据类型
name,名称
//

#定义正确率
ac = tf.cast(tf.equal(tf.argmax(h3,1),tf.argmax(y,1)),tf.float32)
acc = tf.reduce_mean(ac)
tf.summary.scalar("accuracy",acc)
        优化器:
#定义优化器
optimizer = tf.train.AdamOptimizer(1e-3).minimize(loss)
merge_summary = tf.summary.merge_all()

isTrain = 1

        3.6 网络训练

保存模型/加载模型
saver=tf.train.Saver(max_to_keep=1)
参数:
max_to_keep: 表明保存的最大checkpoint 文件数。当一个新文件创建的时候,旧文件就会被删掉。如果值为None或0,表示保存所有的checkpoint 文件。默认值为5(也就是说,保存最近的5个checkpoint 文件)。
keep_checkpoint_every_n_hour: 除了保存最近的max_to_keep checkpoint 文件,你还可能想每训练N小时保存一个checkpoint 文件。这将是非常有用的,如果你想分析一个模型在很长的一段训练时间内是怎么改变的。例如,设置 keep_checkpoint_every_n_hour=2 确保没训练2个小时保存一个checkpoint 文件。默认值10000小时无法看到特征。
————————————————————————————————————————————————————————————————
保存模型
saver.save(sess=sess,save_path=model_save_path,global_step=step)
参数:
sess=sess,会话名字
save_path=model_save_path,设定权重参数保存的路径和文件名
global_step=step,将训练的次数作为后缀加入到模型名字中
————————————————————————————————————————————————————————————————
实际上每调用一次保存操作会创建后3个数据文件并创建一个检查点(checkpoint)文件。
checkpoint
model.ckpt.data-00000-of-00001
model.cpkt.index
model.ckpt.meta
简单理解就是权重等参数被保存到 .ckpt.data 文件中,以字典的形式;
.ckpt-index,应该是内部需要的某种索引来正确映射前两个文件;
图和元数据被保存到 .ckpt.meta 文件中,可以使用tf.train.import_meta_graph 加载
————————————————————————————————————————————————————————————————
加载模型
saver.restore(sess=sess, save_path=model_save_path)
参数:
sess=sess,会话名字;
save_path=model_save_path,权重参数的保存的路径和文件名。

指定一个文件用来保存图
tf.summary.scalar("loss",loss)
merge_summary = tf.summary.merge_all()
writer = tf.summary.FileWriter(path, session.graph)
train_summary = sess.run(merge_summary,feed_dict={x:train,y:target,keep:1})
summary_writer.add_summary(train_summary,i)

print("正在训练")
saver = tf.train.Saver(max_to_keep=1)
font_size = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=15)
with tf.Session() as sess:
    if isTrain:
        init_top = tf.global_variables_initializer()
        sess.run(init_top)
        summary_writer = tf.summary.FileWriter("./logs/loss_of_silver_customers/",sess.graph)
        nepoch = []
        trainacc = []
        testacc = []
        loss1 = []
        for i in range(0,10001):
            sess.run(optimizer,feed_dict={x:train,y:target,keep:0.5})
            train_summary = sess.run(merge_summary,feed_dict={x:train,y:target,keep:1})
            summary_writer.add_summary(train_summary,i)
            
            if i%50==0:
                accu = sess.run(acc,feed_dict={x:train,y:target,keep:0.5})
                accuT = sess.run(acc,feed_dict={x:test,y:test_target,keep:1})
                losss = sess.run(loss,feed_dict={x:train,y:target,keep:1})
            
                print("epoch:"+str(i)+"train_acc:"+str(accu)+"test_acc:"+str(accuT)+"loss:"+str(losss))
            
                nepoch.append(i)
                trainacc.append(accu)
                testacc.append(accuT)
                loss1.append(losss)
        plt.title(u"BP神经网络训练性能曲线",fontproperties = font_size)
        plt.xlabel(u"训练次数",fontproperties = font_size)
        plt.ylabel(u"训练样本和校验样本的精准度",fontproperties = font_size)
        plt.plot(nepoch,trainacc,nepoch,testacc)
        plt.plot(nepoch,trainacc,nepoch,loss1)
        plt.show()

 notebook代码下载:

        链接:https://pan.baidu.com/s/103pZje-H11nqjbQp8hcnFQ 
        提取码:1234

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值