银行客户贷款行为数据挖掘与分析

#1024程序员节 | 征文#

在新时代下,消费者的需求结构、内容与方式发生巨大改变,企业要想获取更多竞争优势,需要借助大数据技术持续创新。本文分析了传统商业银行面临的挑战,并基于knn、逻辑回归、人工神经网络三种算法 ,对银行客户的贷款需求进行分析。最后,使用KMeans聚类算法 进行客群分析,绘制出雷达图、t-SNE散点图、柱状图,多方面展现客户贷款行为。

前言

1、研究背景

银行主要业务包括:资产业务、负债业务、中间业务。其中资产业务主要是指贷款业务,并且它也是银行目前主要的收入来源。同时,随着互联网金融的兴起,一些客户向线上交易方式转移,国有银行的垄断地位开始动摇,其原因主要是这些互联网金融机构利用大数据、云计算、区块链、人工智能、物联网等技术,将其应用在很多应用场景中,包括智能投研、智能投顾、智能客服、智能营销、智能风控、银行云等,这些技术的作用不只是扩大客户的融资需求,还可以用于风险控制、项目评估等方面,达到利益与风险相均衡的状态。为扭转这一局面,传统银行业开始转型升级,与互联网领域融合,优化盈利模式。

2、影响客户贷款需求的因素

⑴客户基本信息

分析贷款客户的年龄、婚姻状况、教育水平、职业等特征,针对这些客户的特征进行分类,对每一类客户群体做出不同的营销方案。

如图1-1、1-2所示,从年龄上分析,进入银行办理业务的客户年龄大多集中在25-65岁之间,而具有贷款需求的客户的年龄分布与之相一致,同时,贷款客户占银行客户总人数的16.03%,说明贷款业务有很大的市场潜力,可以通过一些措施来激发客户的贷款需求。

复制代码
import matplotlib.pyplot as plt
#设置字体
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.hist(o_data.loc[o_data['loan']=='yes','age'].values,color='red',label='y',range=(10,80),alpha=0.1)
plt.hist(o_data.loc[o_data['loan']=='no','age'].values,color='green',label='n',range=(10,80),alpha=0.1)
plt.xlabel('年龄')
plt.ylabel('人数')
plt.title('银行客户的年龄分布')
plt.legend(['y','n'])
plt.show()

图1-1 银行客户的年龄分布图

复制代码
u,c=np.unique(np.array(data['loan']).astype(np.str),return_counts=True,axis=0)
#种类对应的个数
num=list(c)
#设置字体
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.pie(num,labels=['no', 'yes'],autopct='%1.2f%%') #绘制饼图,百分比保留小数点后两位
plt.title('贷款百分比饼图')
plt.show()

图1-2 贷款百分比饼图

如图1-3所示,从职业上分析,银行客户的职业大多集中在蓝领、银行人员、服务业从事人员、技术人员,而职业为蓝领的客户贷款可能性最大。

图1-3 银行客户的职业分布图

如图1-4所示,从受教育水平上分析,大部分银行客户的受教育水平处在中等、高等教育水平,有一小部分客户的受教育水平未知。

复制代码
import seaborn as sns
from matplotlib import pyplot as plt
#教育水平
fig, ax = plt.subplots(figsize=(8,6))
ax = sns.countplot(x=data.education,hue=data.loan,palette="Set1")

图1-4 客户受教育水平的分布图

如图1-5所示,从婚姻状况上分析,各种情况的人数占比都差不多,其中,已婚和离婚的客户人数较多。

复制代码
dataY=data.loc[data['loan']=='yes',:]
a=round(dataY.loc[dataY['marital']=='single','marital'].count()/data.loc[data['marital']=='single','marital'].count(),2)
b=round(dataY.loc[dataY['marital']=='married','marital'].count()/data.loc[data['marital']=='married','marital'].count(),2)
c=round(dataY.loc[dataY['marital']=='divorced','marital'].count()/data.loc[data['marital']=='divorced','marital'].count(),2)
print(a,b,c)
l=[0.13,0.17,0.18]

plt.bar(['single', 'married', 'divorced'],l)
plt.xlabel('婚姻状况')
plt.ylabel('贷款人数/总人数')
plt.title('银行贷款客户的婚姻状况分布')
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.show()
⑵业务情况

与业务情况相关的因素,主要包括与客户的交流方式、交流次数、客户的账户平均余额,通过对这一方面的分析,可以制定出贷款方案,以更大程度的满足客户需求,同时,通过对客户交易情况的了解,将信息推送限制在一定范围内,给客户带来银行交易的愉悦感,增强与客户之间的信任。

如图1-6、1-7、1-8所示,从账户平均余额上分析,客户的贷款金额较小,大多集中在0-3000元之间,高端客户资源稀少。从与客户办理业务时的交流方式上分析,大部分客户使用手机进行信息咨询。从交流次数上分析,与客户的交流次数大多集中在1-5次之间。

复制代码
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.hist(data['balance'],color='blue',label='y',range=(0,15000),alpha=0.1)
plt.xlabel('账户平均余额')
plt.ylabel('人数')
plt.title('银行客户的账户平均余额分布')
plt.show()
复制代码
#把异常值用均值代替
mean=round(data.iloc[:,14].describe()[1],0)
data.loc[data[:]['previous']>250,'previous']=mean
data.loc[data[:]['previous']==0,'previous']=mean
data[:]['previous']=data[:]['previous'].astype('int64')

#交流次数
dataY=data.loc[data['loan']=='yes',:]
fig, ax = plt.subplots(figsize=(10,6))
ax =sns.countplot(x='previous',data=dataY.loc[dataY['previous']<30,:],palette="Set1")

图1-8 交流次数分布图

数据预处理

1、筛选有效特征

如图1-9、1-10所示,由于原始数据的列数过多,考虑到在构建模型阶段可能会浪费很多的时间,因此,我们用逻辑回归分析方法对数据进行筛选,删除不必要的列,最后筛选出job、material、education、balance、housing、contact、previous、loan这几列,经过评估,模型的平均正确率为0.8438。

复制代码
data.corr()
复制代码
data=data.loc[:,['job','marital','education','balance','housing','contact','previous','loan','age','default']]

图1-9 原始数据

图1-10 筛选后数据

2、连续型数据的处理

如图1-10所示,使用info()方法来查看每一列的数据类型,其中,balance、previous这两列属于连续型数据。这类数据的处理方法是通过绘制箱线图,查看是否存在异常值,如果存在,需要利用describe()查看该列的均值,用均值替换掉异常值。

复制代码
#连续型数据的处理
import matplotlib.pyplot as plt
#设置字体
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.boxplot(data.iloc[:,3]) #绘制饼图,百分比保留小数点后两位
plt.title('账户余额箱线图')
plt.show()
复制代码
#把异常值用均值代替
mean=round(data.iloc[:,3].describe()[1],0)
data.loc[data[:]['balance']>100000,'balance']=mean
data.loc[data[:]['balance']==0,'balance']=mean

3、离散型数据的处理

构造如下函数来处理离散型数据,首先要查看所在列中的值的种类数,并创建一个连续的数组,然后将该列的所有数据用数据进行替换,并将数据类型转成int64。

复制代码
def replaceData(df):

    count=data[df].describe()[1]

    l=[]

    for i in range(0,count):

        l.append(str(i))

     data[df].replace(np.unique(data[df]),l,inplace=True)

     data[df]=data[df].astype('int64')

#数据离散化
l=[]
for i in range(0,10):
    l.append(str(i))
print(l)
data['job'].replace(['blue-collar', 'entrepreneur', 'housemaid', 'management',
       'retired', 'self-employed', 'services', 'student', 'technician',
       'unemployed'],l,inplace=True)

#把离散数据转成连续型
def replaceData(df):
    count=data[df].describe()[1]
    l=[]
    for i in range(0,count):
        l.append(str(i))
    data[df].replace(np.unique(data[df]),l,inplace=True)

replaceData('marital')
replaceData('education')
replaceData('default')
replaceData('housing')
replaceData('loan')
replaceData('contact')
replaceData('poutcome')

4、处理后的数据

数据预测方法

对银行客户的贷款需求做分析,需要用到分类算法,我们将使用knn、逻辑回归分析和人工神经网络三种算法来构建模型,并对模型进行评估,计算每种算法的准确率。

1、knn

(1)实现原理

Knn是一种基于已有样本进行推理的算法,通过对已有训练样本集和新进的未知样本做比较,找到与未知样本最相似的k个样本。最后通过对这k个样本的类标号投票得出该测试样本的类别。

(2)步骤

1.对离散数据做one-hot编码,将编码后的数据与连续型数据进行拼接,并对该数据统一做归一化处理,保证所有列对预测结果的影响程度都相同。

2.编写函数,根据测试集准确率与训练集准确率的比值,选定n-neighbors参数的值。

3.预测并得出测试集准确率与训练集准确率。通过计算得出,测试集准确率为0.8368,训练集准确率为0.8482。

复制代码
from sklearn.model_selection import train_test_split#导入模块
from sklearn.neighbors import KNeighborsClassifier
def ping(n):
    X_train, X_test, y_train, y_test = train_test_split(iris_X, iris_y,test_size=0.4,random_state=2)
    knn = KNeighborsClassifier(n_neighbors=n)
    # 训练
    knn.fit(X_train,y_train)
    accuracy_train=knn.score(X_train, y_train)#评估-精确率
    accuracy_test=knn.score(X_test, y_test)#评估-精确率
    print(str(round(accuracy_test/accuracy_train,2)))
(3)评估

如图2-1、2-2所示,通过构建混淆矩阵的方式对模型进行评估,其中,对无贷款需求的客户判定的准确率为85%,对有贷款需求的客户判定的准确率为24%,总体准确率为84%,证明预测结果有效。

复制代码
#混淆矩阵
from sklearn import metrics
metrics.accuracy_score(y_test_pre, y_test)
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(metrics.confusion_matrix(y_test_pre, y_test),
           interpolation='nearest', 
           cmap=plt.cm.binary)
plt.grid(False)
plt.colorbar()
plt.xlabel("predicted label")
plt.ylabel("true label")
复制代码
#评估报告
from sklearn.metrics import classification_report
print(classification_report(y_test,y_test_pre))
复制代码
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(10, 6))
plt.scatter(range(0,50),data.iloc[39951:,8], color='g',label='实际值',linewidth=3,alpha=0.1)
plt.scatter(range(0,50),y_train[23950:], color='r',label='预测值',linewidth=2,alpha=0.1)
plt.legend()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.title('knn预测结果')
plt.show()
(4)预测
复制代码
import seaborn as sns
from matplotlib import pyplot as plt
fig, ax = plt.subplots(figsize=(8,6))
ax = sns.barplot(x=ndata.job,y=ndata.education,hue=ndata.knn,palette="Set1")

贷款客户主要集中在蓝领、管理者、技术人员中,且客户的教育水平普遍都很高 。

复制代码
from matplotlib import pyplot as plt
plt.hist(ndata.loc[ndata['knn']==1,'balance'].values,range=(0,15000))
plt.xlabel('账户余额')
plt.ylabel('人数')
plt.title('银行贷款客户的账户余额分布')
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.show()

2、逻辑回归

(1)实现原理

逻辑回归是根据输入值域对记录进行分类的统计方法。它是将输入值域与输出字段每一类别的概率联系起来。一旦生成模型,便可用于预测。对于每一记录,计算其从属于每种可能输出类的概率,概率最大的类即为预测结果。

(2)步骤

1.划分测试集与训练集。

复制代码
#划分自变量数据集与因变量数据集
x = data.iloc[:,[1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17]]
y = data.iloc[:,8]

2.使用RandomizedLogisticRegression筛选特征

复制代码
#使用RandomizedLogisticRegression筛选有效特征
from sklearn.linear_model import RandomizedLogisticRegression as RLR 
rlr = RLR() #建立随机逻辑回归模型,筛选变量
rlr.fit(x, y) #训练模型
rlr.get_support() #获取特征筛选结果,也可以通过.scores_方法获取各个特征的分数
print(u'通过随机逻辑回归模型筛选特征结束。')
print(u'有效特征为:%s' % ','.join(data.columns[rlr.get_support(indices=True)]))
x = data[data.columns[rlr.get_support(indices=True)]].as_matrix()#筛选好特征

x = data.loc[:,['job','marital','education','balance','housing','contact','previous']]

3.进行预测并计算准确率。通过计算得出,测试集准确率为0.8403,训练集准确率为0.8461。

复制代码
#使用筛选后的特征数据用LogisticRegression来训练模型
from sklearn.linear_model import LogisticRegression as LR
lr = LR() #建立逻辑回归模型
#训练集
x=p_data.iloc[0:24000,1:8]
y=p_data.iloc[0:24000,8]
#测试集
x1=p_data.iloc[24000:,1:8]
y1=p_data.iloc[24000:,8]
lr.fit(x, y) #训练数据
r=lr.score(x, y); # 模型准确率(针对训练数据)
#训练集的预测准确率
trainR=lr.predict(x)
trainZ=trainR-y
trainRs=len(trainZ[trainZ==0])/len(trainZ)
print('训练集的预测准确率为:',trainRs)
#测试集的预测准确率
R=lr.predict(x1)
Z=R-y1
Rs=len(Z[Z==0])/len(Z)
print('测试集的预测准确率为:',Rs)
(3)评估

如图2-3、2-4所示,通过构建混淆矩阵的方式对模型进行评估,其中,对无贷款需求的客户判定的准确率为84%,召回率100%;对有贷款需求的客户判定的准确率为0%,总体准确率为84%。

复制代码
from sklearn import metrics
metrics.accuracy_score(R, y1)
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(metrics.confusion_matrix(R, y1),
           interpolation='nearest', 
           cmap=plt.cm.binary)
plt.grid(False)
plt.colorbar()
plt.xlabel("predicted label")
plt.ylabel("true label")

3、人工神经网络

(1)实现原理

在人工神经网络算法中,对损失函数用梯度下降法进行迭代优化求极小值的过程使用的是BP算法。BP算法由信号的正向传播和误差的反向传播构成。首先,将信号从输入层传递至输出层。若实际输出与期望输出不一致,则进入误差反向传播阶段,将误差反向传递,获得各层的误差信号,对误差做调整。通过反复执行信号的正向传播和误差的反向传播操作,直至输出误差达到期望值,或进行到预定的学习次数为止。

(2)步骤

1.对离散数据做one-hot编码,将编码后的数据与连续型数据进行拼接,并对该数据统一做归一化处理,保证所有列对预测结果的影响程度都相同。

2.划分训练集和测试集。

复制代码
#分离训练集与测试集,median_house_value列的数据是研究的目标
from sklearn.model_selection import train_test_split
Train_X,Test_X,Train_y,Test_y=train_test_split(x,y,
                                              test_size=0.4,random_state=2)

3.采用GridSearchCV来进行参数调整实验,对solver、hidden_layer_sizes两个参数的值进行调整,找出最佳参数组合。

4.预测并计算准确率。通过计算得出,测试集准确率为0.9997,训练集准确率为0.9998。

复制代码
#采用GridSearchCV来进行参数调整实验,找出最佳参数组合
from sklearn.model_selection import GridSearchCV
from sklearn.neural_network import MLPRegressor 
param_grid = {'solver':['lbfgs','sgd','adam'],
 'hidden_layer_sizes': [(5,5),(10,10)]
             }
#对param_grid中的各参数进行组合,传递进MPL回归器。
#cv=3,3折交叉验证,将数据集随机分为3份,每次将一份作为测试集,其他为训练集
#n_jobs=-1,使用CPU核心数,-1表示所有可用的核
best_mlp =GridSearchCV(MLPRegressor(max_iter=200),param_grid,cv=3)
best_mlp.fit(Train_X,Train_y)
print('当前最佳参数组合:',best_mlp.best_params_)
best_score=best_mlp.score(Test_X,Test_y)*100
print('sklearn人工神经网络上述参数得分: %.1f' %best_score + '%')
#用以上模型对Test_X进行预测
mlp_pred = best_mlp.predict(Test_X)
(3)评估
复制代码
accuracy_train=best_mlp.score(Train_X,Train_y)#评估-精确率
accuracy_test=best_mlp.score(Test_X,Test_y)#评估-精确率
print('训练集精确率:'+str(accuracy_train)+' 测试集:'+str(accuracy_test))

三种算法之间的比较

(1)逻辑回归:该算法的数据处理过程较为简单,并且在构建模型的时候不能输入参数进行设置,因此需要手动划分训练集和测试集。

(2)人工神经网络:该算法内部带有很多方法,可以对数据进行one-hot编码、归一化等处理,排除特殊数值对结果的影响,还能进行参数调整,找到最佳参数组合,因此,在这三种算法中,人工神经网络算法的拟合度最高。

(3)Knn:在预测前需要对数据进行处理,排除特殊数值对结果的影响,同时,该算法在构建模型的过程中可以指定参数,尤其是n-neighbors,这个需要我们自行编写方法来找到n-neighbors的最佳值。

复制代码
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(10, 6))
plt.plot(range(0,50),data.iloc[39951:,8], 'go--',label='实际值',linewidth=1)
plt.plot(range(0,50),f_data1.iloc[:,1], 'y--',label='逻辑分析',linewidth=2)
plt.plot(range(0,50),f_data1.iloc[:,2], 'r:',label='knn',linewidth=2)
plt.plot(range(0,50),f_data1.iloc[:,3], 'b',label='sklearn',linewidth=2,alpha=0.5)
plt.legend()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.title('三种算法预测结果')
plt.show()

KMeans聚类客群分析

1、将每个特征值归一化到一个固定范围

复制代码
from sklearn import preprocessing
x=data.iloc[:,[1,3,4,5,6,7]]
x= preprocessing.MinMaxScaler(feature_range=(0,1)).fit_transform(x)#将每个特征值归一化到一个固定范围  

2、开始聚类

复制代码
from sklearn.cluster import KMeans
import numpy as np
#model = KMeans(init=np.array([[4,5],[5,5]]),n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4
model = KMeans(n_clusters = 4,max_iter = 200) #分为k类,并发数4
model.fit(x) #开始聚类

3、预测并绘图

(1)雷达图
复制代码
coreData=np.array(model.cluster_centers_)
ydata0 = np.concatenate((coreData[0], [coreData[0][0]]))
ydata1 = np.concatenate((coreData[1], [coreData[1][0]]))
ydata2 = np.concatenate((coreData[2], [coreData[2][0]]))
ydata3 = np.concatenate((coreData[3], [coreData[3][0]]))

xdata = np.linspace(0,2*np.pi,6,endpoint=False)
xdata = np.concatenate((xdata,[xdata[0]]))
from matplotlib import pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111,polar=True)  #111表示"1×1网格,第一子图"
ax.plot(xdata, ydata0, 'ro--', linewidth=1.2, label='A组客户')
ax.plot(xdata, ydata1, 'b^--', linewidth=1.2, label='B组客户')
ax.plot(xdata, ydata2, 'y*--', linewidth=1.2, label='C组客户')
ax.plot(xdata, ydata2, 'g+-', linewidth=1.2, label='D组客户')
# ax.plot(xdata, ydata3, 'go--', linewidth=1.2, label='D组客户')
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 解决负号"-"显示异常
ax.set_thetagrids(xdata * 180 / np.pi, ['job ', 'education', 'balance', 'housing', 'contact','previous'])  # 有六个值,将一个圆分为六块
ax.set_rlim(-4, 13)  # 轴值范围,圆点是-4,最外层是13
plt.legend(loc=4)
plt.show()
复制代码
#简单打印结果
r1 = pd.Series(model.labels_).value_counts() #统计各个类别的数目
r2 = pd.DataFrame(model.cluster_centers_) #找出聚类中心
r = pd.concat([r2, r1], axis = 1) #横向连接(0是纵向),得到聚类中心对应的类别下的数目
r.columns =  ['job ', 'education', 'balance', 'housing', 'contact','previous'] + [u'kind'] #重命名表头
(2)t-SNE散点图
复制代码
from sklearn.manifold import TSNE
t=TSNE()
t.fit_transform(x)
t=pd.DataFrame(t.embedding_)

d=t[r[u'kind']==0]
plt.scatter(d[0],d[1],color='r')
d=t[r[u'kind']==1]
plt.scatter(d[0],d[1],color='b')
d=t[r[u'kind']==2]
plt.scatter(d[0],d[1],color='y')
# d=t[r[u'聚类类别']==3]
# plt.scatter(d[0],d[1],color='g')
plt.show()
(3)柱状图
复制代码
import seaborn as sns
sns.countplot(x='job',color='salmon',data=r,hue='kind')
复制代码
from matplotlib import pyplot as plt
l=[1415.26, 1599.9, 1661.7, 1056.26]
plt.bar(['客群1','客群2','客群3','客群4'],l)
plt.xlabel('客群种类')
plt.ylabel('账户余额')
plt.title('银行贷款客户的账户余额分布')
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.show()
复制代码
sns.barplot(x='contact',y='education',color='salmon',data=r,hue='kind')

结论

如图2-5所示,在这三种算法中,人工神经网络算法的拟合度最高。通过模型评估发现,每个算法对于无贷款需求的判定准确率较高,而对于有贷款需求的判定准确率较低。

相关推荐
ai大模型中转api测评5 分钟前
解密 GPT-5.5:原生多模态架构如何重定义 AI 逻辑推理与精准制图
大数据·人工智能·gpt·架构·api
冷雨夜中漫步8 分钟前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
xixixi7777711 分钟前
英伟达Agent专用全模态模型出击,仿冒AI智能体泛滥成灾,《AI伦理安全指引》即将落地——AI治理迎来“技术-风险-规范”三重奏
人工智能·5g·安全·ai·大模型·英伟达·智能体
直奔標竿13 分钟前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
数据皮皮侠AI17 分钟前
中国城市可再生能源数据集(2005-2021)|顶刊 Sci Data 11 种能源面板
大数据·人工智能·笔记·能源·1024程序员节
G311354227321 分钟前
如何用 QClaw 龙虾做一个规律作息健康助理 Agent
大数据·人工智能·ai·云计算
幂律智能22 分钟前
零售行业合同管理数智化转型解决方案
大数据·人工智能·零售
旺财矿工24 分钟前
零基础搭建 OpenClaw 2.6.6 Win11 本地化运行环境
人工智能·openclaw·小龙虾·龙虾·openclaw安装包
九成宫25 分钟前
动手学深度学习PyTorch版初步安装过程
人工智能·pytorch·深度学习
Traving Yu25 分钟前
Prompt提示词工程
人工智能·prompt