银行营销大数据分析
一、选题背景
在互联网、云计算和物联网的高速发展下,大数据走入了人们的视野。银行业作为数据集中管理型行业,在大数据背景下如何进行数据挖掘、分析、加工和利用是银行业发展的重要课题之一某银行是一家客户群不断增长的银行,但其贷款业务的客户基数较小,因此该行希望能够将存款用户转化为贷款用户,扩大贷款业务量,从而赚取更多的存贷利差。为此,该行零售信贷部于2016年针对部分客户开展了一次推广个人贷款业务的营销活动,并希望通过数据分析识别出办理个贷业务的潜在客户。
二、大数据分析设计方案
1.本数据集的数据内容与数据特征分析
本案例是基于客户的基本信息(年龄、工作经验、年收入、邮政编码、家庭规模、文化程度、押品价值、月均信用卡消费额、存款客户、信用卡客户、证券客户、网上银行、个贷客户等)对客户情况进行分析。得出以下数据:
连续型特征: 1:年龄和工作经验的mean与中位数(50%)接近,说明二者分布比较均匀(可能数值接近) 2:年龄和工作经验的标准差不低(std),说明分布比较广(跨度大) 3:年收入,月均信用卡消费额,押品价值的mean都比中位数大,说明它们都呈右偏分布,可能存在极值 4:特别是年收入和押品价值标准差非常大,右偏程度很高 5:尤其是押品价值的中位数为0,可见50%以上的客户没有住房抵押。 类别型特征: 个贷客户:比例约为9.60% 证券客户:比例约为10.44% 存款客户:比例约为6.04% 网上银行:比例约为59.68% 信用卡客户:比例约为29.4%
2.数据分析的课程设计方案概述
首先,对某银行某次营销活动受众客户的特征进行了描述性统计,考察了营销活动的总体效果;同时还进行了特征间的相关性分析,筛掉了与响应行为之间没有显著相关性的特征;
其次,分别考察了存款和个贷客户在年龄、年收入等6个特征上的分布情况,分析了存款和个贷客户的自然属性和消费行为特征,并据此构建了存款客户画像和个贷客户画像;
然后,运用Apriori关联规则算法分析了各类业务之间的关联,并重点总结出了存款客户中潜在个贷客户的特征。接着,根据以上分析结果尝试为该银行扩大各类业务客户基数,提高获客能力提出建议;
三、数据分析步骤
数据源
本次课程设计的数据集来源于kaggle平台,该数据集展示了某银行某年一次贷款营销活动的5,000条客户信息记录。
附上网址:https://www.kaggle.com/
2.数据清洗
# 导入模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
import math
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# 读取数据
df = pd.read_excel('./Bank_Personal_Loan_Modelling.xlsx',sheet_name='Data')
df.head()
# 查看字段名的规范性
print("修改前的字段名:",df.columns)
df.columns = ['ID','年龄','工作经验','年收入','邮编','家庭规模','月均信用卡消费额','文化程度', '押品价值','个贷客户','证券客户','存款客户','网上银行','信用卡客户']
print("修改后的字段名:",df.columns)
# 查看各字段类型
df.info()
# 邮编数据没有用 直接删除这一列
del df['邮编']
# 修正ID、年收入、月均信用卡消费额和押品价值四个字段的类型
df['ID'] = df['ID'].astype('object') #由于ID不是连续性 直接换成数值类型
# 删除重复记录
df.drop_duplicates(inplace=True)
# 查看是否还有重复值
df[df.duplicated()].ID.count()
# 对数值型字段进行描述性统计,并查看异常值
df.describe()
# 先将工作经验字段为负数的记录另存并删除,便于接下来的描述性统计分析
df2 = df.loc[df['工作经验'] < 0]
df = df.drop(index=df2.index)
df.loc[df['工作经验'] < 0,'ID'].count()
# 查看各字段的缺失值数量
df.isna().sum()
3.大数据分析过程
- 绘制每个特征的分布
df.columns
# 绘制每个特征的分布
# dataset:数据集 cols:绘图中每行显示的列数
def plot_distribution(dataset, cols=5, width=20, height=5, hspace=0.2, wspace=0.5):
plt.style.use('seaborn') # 设置护板样式
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示
fig = plt.figure(figsize=(width,height))
fig.subplots_adjust(left=None,right=None,top=None,bottom=None,wspace=wspace,hspace=hspace)
rows = math.ceil(float(df.shape[1])) # df.shape[1]:列数 绘图的行数
for i,column in enumerate(dataset.columns): # 遍历数据集中的每一列(特征)
ax = fig.add_subplot(rows, cols, i + 1) # 增加子图
ax.set_title(column)
# 由于数值型数据只有ID这一列所以直接忽视
if dataset.dtypes[column] != np.object: # 数值型数据
g = sns.distplot(dataset[column]) # 直方图
plt.xticks(rotation=25)
plot_distribution(df, cols=3, width=25, height=60, hspace=0.5, wspace=0.5)
从图形中可以发现: 1:家庭规模方面:1人居多,即单身的客户最多,接下来从高到底依次是2人、4人和3人;但这4种家庭规模的客户数量彼此差异不大,分布较为均匀。 2:文化程度方面:本科学历以下的客户最多,但是文化程度在本科毕业及以上的客户数居多,所以该行客户以受过大学本科教育的客户为主。 3:响应行为方面:未办理个贷、证券、存款和信用卡业务的客户要远多于办理了相应业务的客户,可见该次营销活动的受众中只有很少一部分办理过该行的有关业务。
2.相关性分析
- 通过SPSS借助皮尔逊卡方独立性检验对各分类型字段之间的相关性进行分析,得到检验结果的显著性水平如下表
从相关性图片中发现:(分类型相关性图片) 1:个贷客户一般和家庭规模,存款客户和文化程度具有较强的相关性,所以在分析个贷客户画像时将不考虑证券客户、信用卡客户和网上银行 2:证券客户和存款客户具有较强的相关性 3:存款客户一般和个贷客户,证券客户,网上银行和信用卡客户具有较强的相关性,所以在分析存款客户画像时将不考虑文化程度这个特征 4:网上银行和存款客户具有较强的相关性 5:信用卡客户和存款客户具有较强的相关性
- 数值分布与相关性分析
# 矩阵散点图 (spss同样也绘制了相关的图片-数值型相关性.png)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# pairplot主要展现的是变量两两之间的关系
sns.pairplot(df.loc[:,['押品价值','年龄','工作经验','年收入','月均信用卡消费额']],diag_kind='kde',aspect=1.8)
结论:(1)数值分布分析:①押品价值多分布在0附近,说明绝大部分人没有住房抵押;还有一些客户大部分押品价值都在10万美元左右;②年龄多分布在30-60之间;③绝大多数客户的工作经验1趋于10年-30年之间,说明绝不部分的客户都是出社会的人;④年收入集中在4万到7.5万美元间,⑤月卡消费额度:集中在0.2到2千美元间;(2)相关性分析:(查阅数值型相关性 (2).png 或者因子分析数值相关性.png)①:年龄与工作经验的r趋近于1,说明有较强的相关性,虽然与年收入和月卡消费额度存在相关性,但是|r|只有0.5左右,相关性较弱②:年收入跟月卡消费额度和押品价值存在相关性,而且都是正相关,说明年收入越大,消费的额度也就越大,押品的价值也越高。
3.存款客户画像
# 1.1存款和非存款客户在年龄、年收入、月均信用卡消费额和押品价值上的分布差异
def multi_kde(data,pointsnum,unit):
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rc('font',size=13)
i = data.shape[1]
a = data.columns.values[0] # 第一列:存款客户
fig,axes = plt.subplots(1,i-1,figsize=(20,5)) # fig:画布(i-1列)axes:的对象
for j,k in zip(np.arange(1,i),np.arange(i-1)): # j = np.arange(1,i) , k = np.arange(i-1)
b = data[data[a] == 0] # 存款客户为0的数据 == 有存款
c = data[data[a] == 1] # 存款客户为1的数据 == 无存款
d = data.iloc[:,j] # 截取每一行的第n列
e = np.array(unit) # ['','(k$)','(k$)','(k$)'] 单位数组
plt.xticks(np.arange(d.min(),d.max(),int((d.max()-d.min())/pointsnum))) # 横坐标刻度尺 (这一列)
axes[k].set_xlabel(data.columns.values[j]+e[k]) # 第K个画布设置x轴标签列名+单位
b.iloc[:,j].plot.kde(ax=axes[k]) # 有存款
c.iloc[:,j].plot.kde(ax=axes[k]) # 无存款
axes[k].legend(labels=['非'+a,a],loc='best',fontsize=10) # 设置图例
plt.subplots_adjust(wspace=0.3) # 每张子图的中间空白
multi_kde(df.loc[:,['存款客户','年龄','年收入','月均信用卡消费额','押品价值']],
5,['','(k$)','(k$)','(k$)','(k$)'])
# 对押品价值进行分箱分析
def cutbar(data1,data2,num,xlabel,ylabel,data1label,data2label):
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rc('font',size=13)
fig,axes=plt.subplots(1,1,sharey=True,figsize=(10,6))
axes.set_xlabel('押品价值区间')
axes.set_ylabel('人数')
width=0.4
x=np.arange(num)
axes.set_xticks(x)
axes.bar(x-width/2,data1,width=width,label=data1label) # 广播
axes.bar(x+width/2,data2,width=width,label=data2label) # 广播
axes.legend(loc='best')
axes.set_xticklabels(data1.index.values,rotation=30)
for a,b in zip(x-width/2,data1):
axes.text(a,b,b,ha='center',va='bottom',color='k')
for a,b in zip(x+width/2,data2):
axes.text(a,b,b,ha='center',va='bottom',color='k')
a=sorted(list(set(np.concatenate([np.linspace(0,60,6),np.linspace(60,df.押品价值.max(),6)],axis=0))))
df['押品价值分箱']=pd.cut(df.押品价值,bins=a,right=False,precision=0)
bardata_cdmor=df[df.存款客户==1].groupby('押品价值分箱').ID.count()
bardata_notcdmor=df[df.存款客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_notcdmor,bardata_cdmor,10,'押品价值区间','人数','非存款客户','存款客户')
分析:(1)在年龄的分布上:存款客户的年龄集中在33到55岁之间,其中年龄在33-45之间的客户远高于其他存款客户,可见存款客户以青年为主(2)在年收入的分布上:非存款客户偏右太分布,整体集中在4美元左右,说明非存款客户以中低收入为主;而存款客户的年收入分布相对广泛且均匀,集中在4万到16万美元之间;(3)在月均信用卡消费额的分布上:存款和非存款客户的月均信用卡消费额都集中在1千美元左右,可见两类客户信用卡消费水平整体都不高;但存款客户的月均信用卡消费额呈右偏分布,存在高消费水平的客户。(4)在押品价值的分布上:存款和非存款客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,存款和非存款客户中绝大多数都没有住房抵押(押品价值为0),而有住房抵押的存款客户其押品价值在6万到17.5万美元间的最多,有住房抵押的非存款客户其押品价值在10万美元左右的最多(其核密度曲线在10万美元处有一极值),,同时随着押品价值的升高存款和非存款客户的数量都越来越少。
# 存款和非存款客户在家庭规模上的分布差异
piedata_cd=df.groupby('存款客户').ID.count()
df['家庭规模(人)']=df.家庭规模.apply(lambda x: f"{x}人")
piedata_cdfam=df.groupby(['存款客户','家庭规模(人)']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
def sunfig(data_level1,data_level2,bbox_to_anchor_left,pctdistance1,pctdistance2,labeldistance):
plt.rcParams['font.sans-serif'] =['SimHei']
plt.figure(figsize=(8,8))
cmap=plt.get_cmap("Pastel1") # 调色板
# data_level2.index:8 data_level2.index.levels:2层
points=np.arange(len(data_level2.index.levels[0]))*4 # levels:理解成分层(2组):[0, 1] array([0, 4]):再细分成4组(4个家庭)
inner_colors=cmap(points)
outer_colors=cmap(points.repeat([len(data_level2[0]),len(data_level2[1])]))
wedges,texts,autotexts=plt.pie(data_level1.values,radius=1,autopct='%1.2f%%',pctdistance=pctdistance1,
# wedgeprops:对象字典为了用来画一个饼图
textprops={'fontsize':15},colors=inner_colors,wedgeprops=dict(width=1,edgecolor='k'))
plt.legend(wedges,title="是否为%s"%(data_level2.index.get_level_values(0).name),labels=data_level1.index.get_level_values(0),fontsize=12,
bbox_to_anchor=(bbox_to_anchor_left,0,0.7,1))
plt.pie(data_level2.values,radius=1+0.7,autopct='%1.2f%%',labels=data_level2.index.get_level_values(1),
pctdistance=pctdistance2,labeldistance=labeldistance,
textprops={'fontsize':13},colors=outer_colors,wedgeprops=dict(width=0.7,edgecolor='k'))
plt.axis('equal') # 同一水平
sunfig(piedata_cd,piedata_cdfam,0.45,0.5,0.8,1.05)
spss也同样绘制了存款和非存款客户在家庭规模上的分布差异
- 个贷客户画像
# 个贷和非个贷客户在年龄、年收入、月均信用卡消费额和押品价值上的分布差异
multi_kde(df.loc[:,['个贷客户','年龄','年收入','月均信用卡消费额','押品价值']],
5,['','(k$)','(k$)','(k$)','(k$)'])
# 对押品价值进行分箱分析
a=sorted(list(set(np.concatenate([np.linspace(0,60,6),np.linspace(60,df.押品价值.max(),6)],axis=0))))
df['押品价值分箱']=pd.cut(df.押品价值,bins=a,right=False,precision=0)
bardata_cdmor=df[df.个贷客户==1].groupby('押品价值分箱').ID.count()
bardata_notcdmor=df[df.个贷客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_notcdmor,bardata_cdmor,10,'押品价值区间','人数','非个贷客户','个贷客户')
分析:(1)在年龄的分布上:个贷客户的年龄集中在33到55岁之间,其中年龄在33-40之间的客户远高于其他个贷客户,可见个贷客户以青年为主(2)在年收入的分布上:非个贷客户偏右太分布,整体集中在4万到8万美元,以中低收入为主;而个贷客户的年收入分布相对均匀,集中在13万美元到17.5万美元间,以中高收入为主;同时在9.8万美元右侧个贷客户的核密度曲线呈急剧上升,而非个贷客户的核密度曲线在急剧下降,可见年收入9.8万美元是个分界点,年收入高于该水平的客户更有可能办理个贷业务。(3)在月均信用卡消费额的分布上:非个贷客户的月均信用卡消费额呈右偏分布,但集中在0.5到1.7千美元之间,消费水平整体偏低;而个贷客户的月均信用卡消费额分布相对均匀,并集中在3.5千美元左右,以中高消费水平为主。同时在2.8千美元右侧,个贷客户的核密度曲线呈急剧上升并很快达到峰值,而非个贷客户的核密度曲线呈急剧下降,可见2.8千美元是一个分界点,月均信用卡消费额高于该水平的客户更有可能办理个贷业务。(4)在押品价值的分布上:个贷和非个贷客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,个贷和非个贷客户中绝大多数都没有住房抵押(押品价值为0),且个贷客户中有住房抵押的其押品价值在29万到40.5万美元间的最多,并且当押品价值在6万到40.5万美元之间时,随着押品价值的升高个贷客户的数量在增多,而非个贷客户的数量在减少。
# 个贷和非个贷客户在信用卡还款压力上的分布差异
# 计算年信用卡消费额占年均收入的比重可以得出客户对信用卡的使用程度,也能反映客户信用卡的还款压力
df['信用卡-收入比'] = round(df['月均信用卡消费额']*12/df['年收入'],3) # 保留三位小数
# 绘图
plt.style.use('seaborn')
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rc('font',size=13)
plt.figure(figsize=(8,6))
plt.xlabel('信用卡-收入比')
plt.xticks(np.arange(df['信用卡-收入比'].min(),df['信用卡-收入比'].max(),
round((df['信用卡-收入比'].max() - df['信用卡-收入比'].min())/10, 1)
))
df.loc[df.个贷客户==0,'信用卡-收入比'].plot.kde(label='非个贷客户')
df.loc[df.个贷客户==1,'信用卡-收入比'].plot.kde(label='个贷客户')
plt.legend(loc='upper right',fontsize=10)
plt.ylabel('核密度')
分析: ①:非个贷客户信用卡消费额占其收入的比重集中在20%左右,而个贷客户的信用卡消费额占其收入的比重集中在40%左右;同时,在20%到40%这一区间内,非个贷客户的核密度曲线急剧下降,而个贷客户的核密度曲线急剧上升并达到峰值,可见信用卡-收入比在30%到40%之间的客户办理个贷业务的倾向最强。但当信用卡消费额占收入的比重超过65%以后,个贷客户数量的下降幅度要大于非个贷客户,可见虽然大部分非个贷客户对信用卡的使用较为保守,但也存在小部分不理性使用信用卡的客户。
各响应行为间的关联分析
# 各类业务间的Apriori关联分析 Apriori算法找到频繁项集
# 导入Apriori关联规则算法包
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
# 设定最小支持度为0.04,挖掘频繁项集关联性按照支持度从小到大输出
frequent_itemsets = apriori(df.iloc[:,8:13],min_support=0.04,use_colnames=True).sort_values('support',ascending=False)
frequent_itemsets
分析:通过上表可知,①该行同时办理信用卡和网上银行业务的客户占比约为17.74%;②该行同时办理网上银行和个贷业务的客户占比约为5.88% ③该行同时办理网上银行和证券业务的客户占比约为6.47% ④该行同时办理网上银行和存款业务的客户占比约为5.72% ⑤该行同时办理存款和信用卡业务的客户占比约为4.85% ⑥该行同时办理存款和信用卡和网上银行业务的客户占比约为4.52%
# 设定最小置信度为0.7,挖掘强关联规则
rules = association_rules(frequent_itemsets,metric='confidence',min_threshold=0.7).sort_values('conviction',ascending=False)
rules
- 存款客户中的潜在个贷客户特征
# 既存款又个贷的客户与存款但非个贷客户在年龄、年收入、信用卡消费水平以及押品价值方面的差异
data_pd=df[df.存款客户==1]
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rc('font',size=13)
# pairplot主要展现的是变量两两之间的关系
sns.pairplot(data_pd.loc[:,['个贷客户','年龄','年收入','月均信用卡消费额','信用卡-收入比','押品价值']],
vars=['年龄','年收入','月均信用卡消费额','信用卡-收入比','押品价值'],hue='个贷客户',diag_kind='kde',aspect=1.8)
# 对押品价值的分布进行分箱细化
df['押品价值分箱2']=pd.cut(df.押品价值,10,right=False,precision=0)
bardata_cdloamor=data_pd[data_pd.个贷客户==1].groupby('押品价值分箱').ID.count()
bardata_cdnotloamor=data_pd[data_pd.个贷客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_cdnotloamor,bardata_cdloamor,10,'押品价值区间','人数','非个贷客户','个贷客户')
分析:①:从相关性矩阵散点图可以看出,存款客户中个贷和非个贷客户在年收入和月均信用卡消费额上的区分度比较高,具体来说,年收入在10.2万美元以上且月均信用卡消费额在3千美元以上的存款客户办理个贷业务的倾向非常强;②:在信用卡收入比方面,在0.65的水平以内二者的区分度不高,但超过0.65的水平后,非个贷的存款客户要多于个贷存款客户;③:在押品价值方面,存款个贷和存款非个贷客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,存款个贷和存款非个贷客户中绝大多数都没有住房抵押(押品价值为0),同时当押品价值高于400万美元后,存款个贷客户比存款非个贷客户要多。
# 既存款又个贷的客户与存款但非个贷客户在家庭规模上的分布差异
piedatacd_loa=data_pd.groupby('个贷客户').ID.count()
piedatacd_loafa=data_pd.groupby(['个贷客户','家庭规模']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
sunfig(piedatacd_loa,piedatacd_loafa,0.45,0.5,0.8,1.05)
分析:存款非个贷客户以独身或已婚但未育为主,而存款个贷客户以已婚且有子女为主。
# 既存款又个贷的客户与存款但非个贷客户在文化程度上的分布差异
def cut_ed(dataset):
if dataset == 1:
return '本科以下'
elif dataset == 2:
return '本科'
else:
return '更高'
data_pd['文化程度_分组'] = data_pd['文化程度'].apply(lambda x: cut_ed(x))
piedatacd_loaedu=data_pd.groupby(['个贷客户','文化程度_分组']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
sunfig(piedatacd_loa,piedatacd_loaedu,0.45,0.5,0.8,1.05)
分析:存款非个贷客户以本科以下的文化水平为主,而存款个贷客户以本科以上的文化水平为主,说明受教育水平越高,越有可能个贷
四、结论
(1)存款客户画像
1)年龄集中在33到45岁之间,以青中年为主;
2)家庭规模以单身和已婚且有子女为主;
3)年收入分布广泛,集中在4万到16万美元间;
4)信用卡消费以中低水平为主,集中在1千美元左右,但存在部分高消费水平客户;
5)绝大部分没有住房抵押,而有住房抵押的押品价值在6万到17.5万美元的最多。
(2)个贷客户画像
1)年龄集中在32到50岁之间,以青中年为主;
2)文化程度以大学本科及以上为主;
3)家庭规模以已婚且有子女为主;
4)年收入和信用卡消费都以中高水平为主(年收入在9.8万美元以上,月均信用卡消费额在2.8千美元以上);信用卡消费额占其收入比重在30%到40%之间;
5)绝大部分没有住房抵押,而有住房抵押的其押品价值集中在6万到40.5万美元间,且在这一区间内押品价值越高的客户办理个贷业务的倾向越强。
(3)存款客户中的潜在个贷客户画像
1)已婚且有子女;
2)学历在本科及以上;
3)年收入在10.2万美元以上;
4)月均信用卡消费额在3千美元以上;
5)信用卡消费额占其收入比重不超过65%;
6)押品价值高于29万美元。
1.2各类业务间的关联
绝大部分存款客户都会同时办理信用卡或网上银行业务,但同时办理个贷业务的较少,存款客户到个贷客户的转化率不高。
2、建议
(1)存款业务是该行的基础业务,对其他业务具有重要的带动和派生作用;但该次营销活动的受众中只有6.10%的客户在该行开立了存款账户,因而应进一步拓展存款业务的市场份额,扩大存款客户基数。
(2)存款客户中个贷和非个贷客户的区分度非常高,因而应充分利用和盘活存款客户,通过对其加大个贷营销力度、提供个贷优惠等方式促使其向个贷客户转化。
(3)针对绝大部分存款客户使用网上银行的习惯,可以充分利用网上银行作为平台和媒介对存款客户推送个性化的服务,诱导存款客户办理更多的相关业务。
(4)应根据客户画像进行存款和个贷业务的精准营销,以降低营销费用,提高获客效益。
银行营销大数据分析
一、选题背景
在互联网、云计算和物联网的高速发展下,大数据走入了人们的视野。银行业作为数据集中管理型行业,在大数据背景下如何进行数据挖掘、分析、加工和利用是银行业发展的重要课题之一某银行是一家客户群不断增长的银行,但其贷款业务的客户基数较小,因此该行希望能够将存款用户转化为贷款用户,扩大贷款业务量,从而赚取更多的存贷利差。为此,该行零售信贷部于2016年针对部分客户开展了一次推广个人贷款业务的营销活动,并希望通过数据分析识别出办理个贷业务的潜在客户。
二、大数据分析设计方案
1.本数据集的数据内容与数据特征分析
本案例是基于客户的基本信息(年龄、工作经验、年收入、邮政编码、家庭规模、文化程度、押品价值、月均信用卡消费额、存款客户、信用卡客户、证券客户、网上银行、个贷客户等)对客户情况进行分析。得出以下数据:
连续型特征: 1:年龄和工作经验的mean与中位数(50%)接近,说明二者分布比较均匀(可能数值接近) 2:年龄和工作经验的标准差不低(std),说明分布比较广(跨度大) 3:年收入,月均信用卡消费额,押品价值的mean都比中位数大,说明它们都呈右偏分布,可能存在极值 4:特别是年收入和押品价值标准差非常大,右偏程度很高 5:尤其是押品价值的中位数为0,可见50%以上的客户没有住房抵押。 类别型特征: 个贷客户:比例约为9.60% 证券客户:比例约为10.44% 存款客户:比例约为6.04% 网上银行:比例约为59.68% 信用卡客户:比例约为29.4%
2.数据分析的课程设计方案概述
首先,对某银行某次营销活动受众客户的特征进行了描述性统计,考察了营销活动的总体效果;同时还进行了特征间的相关性分析,筛掉了与响应行为之间没有显著相关性的特征;
其次,分别考察了存款和个贷客户在年龄、年收入等6个特征上的分布情况,分析了存款和个贷客户的自然属性和消费行为特征,并据此构建了存款客户画像和个贷客户画像;
然后,运用Apriori关联规则算法分析了各类业务之间的关联,并重点总结出了存款客户中潜在个贷客户的特征。接着,根据以上分析结果尝试为该银行扩大各类业务客户基数,提高获客能力提出建议;
三、数据分析步骤
数据源
本次课程设计的数据集来源于kaggle平台,该数据集展示了某银行某年一次贷款营销活动的5,000条客户信息记录。
附上网址:https://www.kaggle.com/
2.数据清洗
# 导入模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
import math
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# 读取数据
df = pd.read_excel('./Bank_Personal_Loan_Modelling.xlsx',sheet_name='Data')
df.head()
# 查看字段名的规范性
print("修改前的字段名:",df.columns)
df.columns = ['ID','年龄','工作经验','年收入','邮编','家庭规模','月均信用卡消费额','文化程度', '押品价值','个贷客户','证券客户','存款客户','网上银行','信用卡客户']
print("修改后的字段名:",df.columns)
# 查看各字段类型
df.info()
# 邮编数据没有用 直接删除这一列
del df['邮编']
# 修正ID、年收入、月均信用卡消费额和押品价值四个字段的类型
df['ID'] = df['ID'].astype('object') #由于ID不是连续性 直接换成数值类型
# 删除重复记录
df.drop_duplicates(inplace=True)
# 查看是否还有重复值
df[df.duplicated()].ID.count()
# 对数值型字段进行描述性统计,并查看异常值
df.describe()
# 先将工作经验字段为负数的记录另存并删除,便于接下来的描述性统计分析
df2 = df.loc[df['工作经验'] < 0]
df = df.drop(index=df2.index)
df.loc[df['工作经验'] < 0,'ID'].count()
# 查看各字段的缺失值数量
df.isna().sum()
3.大数据分析过程
- 绘制每个特征的分布
df.columns
# 绘制每个特征的分布
# dataset:数据集 cols:绘图中每行显示的列数
def plot_distribution(dataset, cols=5, width=20, height=5, hspace=0.2, wspace=0.5):
plt.style.use('seaborn') # 设置护板样式
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示
fig = plt.figure(figsize=(width,height))
fig.subplots_adjust(left=None,right=None,top=None,bottom=None,wspace=wspace,hspace=hspace)
rows = math.ceil(float(df.shape[1])) # df.shape[1]:列数 绘图的行数
for i,column in enumerate(dataset.columns): # 遍历数据集中的每一列(特征)
ax = fig.add_subplot(rows, cols, i + 1) # 增加子图
ax.set_title(column)
# 由于数值型数据只有ID这一列所以直接忽视
if dataset.dtypes[column] != np.object: # 数值型数据
g = sns.distplot(dataset[column]) # 直方图
plt.xticks(rotation=25)
plot_distribution(df, cols=3, width=25, height=60, hspace=0.5, wspace=0.5)
从图形中可以发现: 1:家庭规模方面:1人居多,即单身的客户最多,接下来从高到底依次是2人、4人和3人;但这4种家庭规模的客户数量彼此差异不大,分布较为均匀。 2:文化程度方面:本科学历以下的客户最多,但是文化程度在本科毕业及以上的客户数居多,所以该行客户以受过大学本科教育的客户为主。 3:响应行为方面:未办理个贷、证券、存款和信用卡业务的客户要远多于办理了相应业务的客户,可见该次营销活动的受众中只有很少一部分办理过该行的有关业务。
2.相关性分析
- 通过SPSS借助皮尔逊卡方独立性检验对各分类型字段之间的相关性进行分析,得到检验结果的显著性水平如下表
从相关性图片中发现:(分类型相关性图片) 1:个贷客户一般和家庭规模,存款客户和文化程度具有较强的相关性,所以在分析个贷客户画像时将不考虑证券客户、信用卡客户和网上银行 2:证券客户和存款客户具有较强的相关性 3:存款客户一般和个贷客户,证券客户,网上银行和信用卡客户具有较强的相关性,所以在分析存款客户画像时将不考虑文化程度这个特征 4:网上银行和存款客户具有较强的相关性 5:信用卡客户和存款客户具有较强的相关性
- 数值分布与相关性分析
# 矩阵散点图 (spss同样也绘制了相关的图片-数值型相关性.png)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# pairplot主要展现的是变量两两之间的关系
sns.pairplot(df.loc[:,['押品价值','年龄','工作经验','年收入','月均信用卡消费额']],diag_kind='kde',aspect=1.8)
结论:(1)数值分布分析:①押品价值多分布在0附近,说明绝大部分人没有住房抵押;还有一些客户大部分押品价值都在10万美元左右;②年龄多分布在30-60之间;③绝大多数客户的工作经验1趋于10年-30年之间,说明绝不部分的客户都是出社会的人;④年收入集中在4万到7.5万美元间,⑤月卡消费额度:集中在0.2到2千美元间;(2)相关性分析:(查阅数值型相关性 (2).png 或者因子分析数值相关性.png)①:年龄与工作经验的r趋近于1,说明有较强的相关性,虽然与年收入和月卡消费额度存在相关性,但是|r|只有0.5左右,相关性较弱②:年收入跟月卡消费额度和押品价值存在相关性,而且都是正相关,说明年收入越大,消费的额度也就越大,押品的价值也越高。
3.存款客户画像
# 1.1存款和非存款客户在年龄、年收入、月均信用卡消费额和押品价值上的分布差异
def multi_kde(data,pointsnum,unit):
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rc('font',size=13)
i = data.shape[1]
a = data.columns.values[0] # 第一列:存款客户
fig,axes = plt.subplots(1,i-1,figsize=(20,5)) # fig:画布(i-1列)axes:的对象
for j,k in zip(np.arange(1,i),np.arange(i-1)): # j = np.arange(1,i) , k = np.arange(i-1)
b = data[data[a] == 0] # 存款客户为0的数据 == 有存款
c = data[data[a] == 1] # 存款客户为1的数据 == 无存款
d = data.iloc[:,j] # 截取每一行的第n列
e = np.array(unit) # ['','(k$)','(k$)','(k$)'] 单位数组
plt.xticks(np.arange(d.min(),d.max(),int((d.max()-d.min())/pointsnum))) # 横坐标刻度尺 (这一列)
axes[k].set_xlabel(data.columns.values[j]+e[k]) # 第K个画布设置x轴标签列名+单位
b.iloc[:,j].plot.kde(ax=axes[k]) # 有存款
c.iloc[:,j].plot.kde(ax=axes[k]) # 无存款
axes[k].legend(labels=['非'+a,a],loc='best',fontsize=10) # 设置图例
plt.subplots_adjust(wspace=0.3) # 每张子图的中间空白
multi_kde(df.loc[:,['存款客户','年龄','年收入','月均信用卡消费额','押品价值']],
5,['','(k$)','(k$)','(k$)','(k$)'])
# 对押品价值进行分箱分析
def cutbar(data1,data2,num,xlabel,ylabel,data1label,data2label):
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rc('font',size=13)
fig,axes=plt.subplots(1,1,sharey=True,figsize=(10,6))
axes.set_xlabel('押品价值区间')
axes.set_ylabel('人数')
width=0.4
x=np.arange(num)
axes.set_xticks(x)
axes.bar(x-width/2,data1,width=width,label=data1label) # 广播
axes.bar(x+width/2,data2,width=width,label=data2label) # 广播
axes.legend(loc='best')
axes.set_xticklabels(data1.index.values,rotation=30)
for a,b in zip(x-width/2,data1):
axes.text(a,b,b,ha='center',va='bottom',color='k')
for a,b in zip(x+width/2,data2):
axes.text(a,b,b,ha='center',va='bottom',color='k')
a=sorted(list(set(np.concatenate([np.linspace(0,60,6),np.linspace(60,df.押品价值.max(),6)],axis=0))))
df['押品价值分箱']=pd.cut(df.押品价值,bins=a,right=False,precision=0)
bardata_cdmor=df[df.存款客户==1].groupby('押品价值分箱').ID.count()
bardata_notcdmor=df[df.存款客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_notcdmor,bardata_cdmor,10,'押品价值区间','人数','非存款客户','存款客户')
分析:(1)在年龄的分布上:存款客户的年龄集中在33到55岁之间,其中年龄在33-45之间的客户远高于其他存款客户,可见存款客户以青年为主(2)在年收入的分布上:非存款客户偏右太分布,整体集中在4美元左右,说明非存款客户以中低收入为主;而存款客户的年收入分布相对广泛且均匀,集中在4万到16万美元之间;(3)在月均信用卡消费额的分布上:存款和非存款客户的月均信用卡消费额都集中在1千美元左右,可见两类客户信用卡消费水平整体都不高;但存款客户的月均信用卡消费额呈右偏分布,存在高消费水平的客户。(4)在押品价值的分布上:存款和非存款客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,存款和非存款客户中绝大多数都没有住房抵押(押品价值为0),而有住房抵押的存款客户其押品价值在6万到17.5万美元间的最多,有住房抵押的非存款客户其押品价值在10万美元左右的最多(其核密度曲线在10万美元处有一极值),,同时随着押品价值的升高存款和非存款客户的数量都越来越少。
# 存款和非存款客户在家庭规模上的分布差异
piedata_cd=df.groupby('存款客户').ID.count()
df['家庭规模(人)']=df.家庭规模.apply(lambda x: f"{x}人")
piedata_cdfam=df.groupby(['存款客户','家庭规模(人)']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
def sunfig(data_level1,data_level2,bbox_to_anchor_left,pctdistance1,pctdistance2,labeldistance):
plt.rcParams['font.sans-serif'] =['SimHei']
plt.figure(figsize=(8,8))
cmap=plt.get_cmap("Pastel1") # 调色板
# data_level2.index:8 data_level2.index.levels:2层
points=np.arange(len(data_level2.index.levels[0]))*4 # levels:理解成分层(2组):[0, 1] array([0, 4]):再细分成4组(4个家庭)
inner_colors=cmap(points)
outer_colors=cmap(points.repeat([len(data_level2[0]),len(data_level2[1])]))
wedges,texts,autotexts=plt.pie(data_level1.values,radius=1,autopct='%1.2f%%',pctdistance=pctdistance1,
# wedgeprops:对象字典为了用来画一个饼图
textprops={'fontsize':15},colors=inner_colors,wedgeprops=dict(width=1,edgecolor='k'))
plt.legend(wedges,title="是否为%s"%(data_level2.index.get_level_values(0).name),labels=data_level1.index.get_level_values(0),fontsize=12,
bbox_to_anchor=(bbox_to_anchor_left,0,0.7,1))
plt.pie(data_level2.values,radius=1+0.7,autopct='%1.2f%%',labels=data_level2.index.get_level_values(1),
pctdistance=pctdistance2,labeldistance=labeldistance,
textprops={'fontsize':13},colors=outer_colors,wedgeprops=dict(width=0.7,edgecolor='k'))
plt.axis('equal') # 同一水平
sunfig(piedata_cd,piedata_cdfam,0.45,0.5,0.8,1.05)
spss也同样绘制了存款和非存款客户在家庭规模上的分布差异
- 个贷客户画像
# 个贷和非个贷客户在年龄、年收入、月均信用卡消费额和押品价值上的分布差异
multi_kde(df.loc[:,['个贷客户','年龄','年收入','月均信用卡消费额','押品价值']],
5,['','(k$)','(k$)','(k$)','(k$)'])
# 对押品价值进行分箱分析
a=sorted(list(set(np.concatenate([np.linspace(0,60,6),np.linspace(60,df.押品价值.max(),6)],axis=0))))
df['押品价值分箱']=pd.cut(df.押品价值,bins=a,right=False,precision=0)
bardata_cdmor=df[df.个贷客户==1].groupby('押品价值分箱').ID.count()
bardata_notcdmor=df[df.个贷客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_notcdmor,bardata_cdmor,10,'押品价值区间','人数','非个贷客户','个贷客户')
分析:(1)在年龄的分布上:个贷客户的年龄集中在33到55岁之间,其中年龄在33-40之间的客户远高于其他个贷客户,可见个贷客户以青年为主(2)在年收入的分布上:非个贷客户偏右太分布,整体集中在4万到8万美元,以中低收入为主;而个贷客户的年收入分布相对均匀,集中在13万美元到17.5万美元间,以中高收入为主;同时在9.8万美元右侧个贷客户的核密度曲线呈急剧上升,而非个贷客户的核密度曲线在急剧下降,可见年收入9.8万美元是个分界点,年收入高于该水平的客户更有可能办理个贷业务。(3)在月均信用卡消费额的分布上:非个贷客户的月均信用卡消费额呈右偏分布,但集中在0.5到1.7千美元之间,消费水平整体偏低;而个贷客户的月均信用卡消费额分布相对均匀,并集中在3.5千美元左右,以中高消费水平为主。同时在2.8千美元右侧,个贷客户的核密度曲线呈急剧上升并很快达到峰值,而非个贷客户的核密度曲线呈急剧下降,可见2.8千美元是一个分界点,月均信用卡消费额高于该水平的客户更有可能办理个贷业务。(4)在押品价值的分布上:个贷和非个贷客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,个贷和非个贷客户中绝大多数都没有住房抵押(押品价值为0),且个贷客户中有住房抵押的其押品价值在29万到40.5万美元间的最多,并且当押品价值在6万到40.5万美元之间时,随着押品价值的升高个贷客户的数量在增多,而非个贷客户的数量在减少。
# 个贷和非个贷客户在信用卡还款压力上的分布差异
# 计算年信用卡消费额占年均收入的比重可以得出客户对信用卡的使用程度,也能反映客户信用卡的还款压力
df['信用卡-收入比'] = round(df['月均信用卡消费额']*12/df['年收入'],3) # 保留三位小数
# 绘图
plt.style.use('seaborn')
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rc('font',size=13)
plt.figure(figsize=(8,6))
plt.xlabel('信用卡-收入比')
plt.xticks(np.arange(df['信用卡-收入比'].min(),df['信用卡-收入比'].max(),
round((df['信用卡-收入比'].max() - df['信用卡-收入比'].min())/10, 1)
))
df.loc[df.个贷客户==0,'信用卡-收入比'].plot.kde(label='非个贷客户')
df.loc[df.个贷客户==1,'信用卡-收入比'].plot.kde(label='个贷客户')
plt.legend(loc='upper right',fontsize=10)
plt.ylabel('核密度')
分析: ①:非个贷客户信用卡消费额占其收入的比重集中在20%左右,而个贷客户的信用卡消费额占其收入的比重集中在40%左右;同时,在20%到40%这一区间内,非个贷客户的核密度曲线急剧下降,而个贷客户的核密度曲线急剧上升并达到峰值,可见信用卡-收入比在30%到40%之间的客户办理个贷业务的倾向最强。但当信用卡消费额占收入的比重超过65%以后,个贷客户数量的下降幅度要大于非个贷客户,可见虽然大部分非个贷客户对信用卡的使用较为保守,但也存在小部分不理性使用信用卡的客户。
各响应行为间的关联分析
# 各类业务间的Apriori关联分析 Apriori算法找到频繁项集
# 导入Apriori关联规则算法包
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
# 设定最小支持度为0.04,挖掘频繁项集关联性按照支持度从小到大输出
frequent_itemsets = apriori(df.iloc[:,8:13],min_support=0.04,use_colnames=True).sort_values('support',ascending=False)
frequent_itemsets
分析:通过上表可知,①该行同时办理信用卡和网上银行业务的客户占比约为17.74%;②该行同时办理网上银行和个贷业务的客户占比约为5.88% ③该行同时办理网上银行和证券业务的客户占比约为6.47% ④该行同时办理网上银行和存款业务的客户占比约为5.72% ⑤该行同时办理存款和信用卡业务的客户占比约为4.85% ⑥该行同时办理存款和信用卡和网上银行业务的客户占比约为4.52%
# 设定最小置信度为0.7,挖掘强关联规则
rules = association_rules(frequent_itemsets,metric='confidence',min_threshold=0.7).sort_values('conviction',ascending=False)
rules
- 存款客户中的潜在个贷客户特征
# 既存款又个贷的客户与存款但非个贷客户在年龄、年收入、信用卡消费水平以及押品价值方面的差异
data_pd=df[df.存款客户==1]
plt.rcParams['font.sans-serif'] =['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rc('font',size=13)
# pairplot主要展现的是变量两两之间的关系
sns.pairplot(data_pd.loc[:,['个贷客户','年龄','年收入','月均信用卡消费额','信用卡-收入比','押品价值']],
vars=['年龄','年收入','月均信用卡消费额','信用卡-收入比','押品价值'],hue='个贷客户',diag_kind='kde',aspect=1.8)
# 对押品价值的分布进行分箱细化
df['押品价值分箱2']=pd.cut(df.押品价值,10,right=False,precision=0)
bardata_cdloamor=data_pd[data_pd.个贷客户==1].groupby('押品价值分箱').ID.count()
bardata_cdnotloamor=data_pd[data_pd.个贷客户==0].groupby('押品价值分箱').ID.count()
cutbar(bardata_cdnotloamor,bardata_cdloamor,10,'押品价值区间','人数','非个贷客户','个贷客户')
分析:①:从相关性矩阵散点图可以看出,存款客户中个贷和非个贷客户在年收入和月均信用卡消费额上的区分度比较高,具体来说,年收入在10.2万美元以上且月均信用卡消费额在3千美元以上的存款客户办理个贷业务的倾向非常强;②:在信用卡收入比方面,在0.65的水平以内二者的区分度不高,但超过0.65的水平后,非个贷的存款客户要多于个贷存款客户;③:在押品价值方面,存款个贷和存款非个贷客户的押品价值都集中在0值附近,进一步对押品价值分箱处理后发现,存款个贷和存款非个贷客户中绝大多数都没有住房抵押(押品价值为0),同时当押品价值高于400万美元后,存款个贷客户比存款非个贷客户要多。
# 既存款又个贷的客户与存款但非个贷客户在家庭规模上的分布差异
piedatacd_loa=data_pd.groupby('个贷客户').ID.count()
piedatacd_loafa=data_pd.groupby(['个贷客户','家庭规模']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
sunfig(piedatacd_loa,piedatacd_loafa,0.45,0.5,0.8,1.05)
分析:存款非个贷客户以独身或已婚但未育为主,而存款个贷客户以已婚且有子女为主。
# 既存款又个贷的客户与存款但非个贷客户在文化程度上的分布差异
def cut_ed(dataset):
if dataset == 1:
return '本科以下'
elif dataset == 2:
return '本科'
else:
return '更高'
data_pd['文化程度_分组'] = data_pd['文化程度'].apply(lambda x: cut_ed(x))
piedatacd_loaedu=data_pd.groupby(['个贷客户','文化程度_分组']).ID.count().groupby(level=0,group_keys=False).nlargest(10)
sunfig(piedatacd_loa,piedatacd_loaedu,0.45,0.5,0.8,1.05)
分析:存款非个贷客户以本科以下的文化水平为主,而存款个贷客户以本科以上的文化水平为主,说明受教育水平越高,越有可能个贷
四、结论
(1)存款客户画像
1)年龄集中在33到45岁之间,以青中年为主;
2)家庭规模以单身和已婚且有子女为主;
3)年收入分布广泛,集中在4万到16万美元间;
4)信用卡消费以中低水平为主,集中在1千美元左右,但存在部分高消费水平客户;
5)绝大部分没有住房抵押,而有住房抵押的押品价值在6万到17.5万美元的最多。
(2)个贷客户画像
1)年龄集中在32到50岁之间,以青中年为主;
2)文化程度以大学本科及以上为主;
3)家庭规模以已婚且有子女为主;
4)年收入和信用卡消费都以中高水平为主(年收入在9.8万美元以上,月均信用卡消费额在2.8千美元以上);信用卡消费额占其收入比重在30%到40%之间;
5)绝大部分没有住房抵押,而有住房抵押的其押品价值集中在6万到40.5万美元间,且在这一区间内押品价值越高的客户办理个贷业务的倾向越强。
(3)存款客户中的潜在个贷客户画像
1)已婚且有子女;
2)学历在本科及以上;
3)年收入在10.2万美元以上;
4)月均信用卡消费额在3千美元以上;
5)信用卡消费额占其收入比重不超过65%;
6)押品价值高于29万美元。
1.2各类业务间的关联
绝大部分存款客户都会同时办理信用卡或网上银行业务,但同时办理个贷业务的较少,存款客户到个贷客户的转化率不高。
2、建议
(1)存款业务是该行的基础业务,对其他业务具有重要的带动和派生作用;但该次营销活动的受众中只有6.10%的客户在该行开立了存款账户,因而应进一步拓展存款业务的市场份额,扩大存款客户基数。
(2)存款客户中个贷和非个贷客户的区分度非常高,因而应充分利用和盘活存款客户,通过对其加大个贷营销力度、提供个贷优惠等方式促使其向个贷客户转化。
(3)针对绝大部分存款客户使用网上银行的习惯,可以充分利用网上银行作为平台和媒介对存款客户推送个性化的服务,诱导存款客户办理更多的相关业务。
(4)应根据客户画像进行存款和个贷业务的精准营销,以降低营销费用,提高获客效益。
标签:数据分析,信用卡,df,个贷,银行,营销,客户,存款,押品 From: https://www.cnblogs.com/39yangjialong/p/16999757.html