全文下载链接:http://tecdat.cn/?p=26219

该数据(查看文末了解数据获取方式)与银行机构的直接营销活动相关,营销活动基于电话。通常,需要与同一客户的多个联系人联系,以便访问产品(银行定期存款)是否会(“是”)或不会(“否”)订阅点击文末“阅读原文”获取完整代码数据

银行数据集

我们的数据集描述

y - 客户是否订阅了定期存款?(二进制:'是','否')

相关视频

我们的目标是选择最好的回归模型来让客户订阅或不订阅定期存款。我们将使用如下算法:

  • 线性回归

  • 随机森林回归

  • KNN近邻

  • 决策树

  • 高斯朴素贝叶斯

  • 支持向量机

选择最佳模型的决定将基于:

  • 准确性

  • 过采样

数据准备

在本节中,我们加载数据。我们的数据有 45211 个变量。

输入变量:
银行客户数据
1 - 年龄(数字)
2 - 工作:工作类型(分类:'行政'、'蓝领'、'企业家'、'女佣'、'管理'、'退休'、'自雇'、'服务'、'学生'、'技术员'、'失业'、'未知')
3 - 婚姻:婚姻状况(分类:'离婚'、'已婚'、'单身'、'不详';注:'离婚'指离婚或丧偶)。
4 - 教育(分类:'基础4年'、'基础6年'、'基础9年'、'高中'、'文盲'、'专业课程'、'大学学位'、'未知')
5 - 违约:是否有违约的信贷?(分类: '没有', '有', '未知')
6-住房:是否有住房贷款?(分类: '否', '是', '未知')
7 - 贷款:有个人贷款吗?
8 - contact: 联系通信类型(分类:'手机', '电话')。
9 - 月:最后一次联系的年份月份(分类:'一月', '二月', '三月', ..., '十一月', '十二月')
10 - day\_of\_week:最后一次联系的星期(分类:'mon', 'tue', 'wed', 'thu', 'fri')
11 - 持续时间:最后一次联系的持续时间,以秒为单位(数字)。
12 - 活动:在这个活动期间为这个客户进行的接触次数(数字,包括最后一次接触)。
13 - pdays: 在上次活动中最后一次与客户联系后的天数(数字,999表示之前没有与客户联系)。
14 - 以前:在这次活动之前,为这个客户进行的接触次数(数字)。
15 - 结果:上次营销活动的结果(分类:"失败"、"不存在"、"成功")。
社会和经济背景属性
16 - emp.var.rate:就业变化率--季度指标(数值)。
17 - cons.price.idx:消费者价格指数--月度指标(数值)。
18 - cons.conf.idx:消费者信心指数--月度指标(数字)。
19 - euribor3m:银行3个月利率--每日指标(数值)
20 - nr.employed: 雇员人数 - 季度指标(数字)

输出变量(所需目标):

  • y -  客户是否认购了定期存款?(二进制: '是', '否')

data.head(5)

73d0852c097533a00e2f8460176d45b4.png

我们的下一步是查看变量的形式以及是否存在缺失值的问题。

df1 = data.dtypes
df1

704f7481689ee562c28f755e1e7b6f8c.png

df2 = data.isnull().sum() 
df2

3ebc71efba6b6c88305e3d0b9a3eaff4.png

我们的下一步是计算所有变量的值。

data\['y'\].value_counts()

bb5cf6aa9f21eacdfda33f134daeb8ec.png

data\['job'\].value_counts()

2d66ef13e6302810b7f46a4933de9912.png

data\['marital'\].value_counts()

afbd0cb3868fbac8b199ef5a012380e7.png

data\['education'\].value_counts()

ece8c969202c9543c5e2cf102edc19c3.png

data\['housing'\].value_counts()

d30f27a165e98b1320ed79c656919dda.png

data\['loan'\].value_counts()

dcbf0b93a11b93e6cdb3a02e81d0b21c.png

data\['contact'\].value_counts()

055c89c07f97304361a7eb817f2dd84b.png

data\['month'\].value_counts()

8e7f15a8d8b9386cba44cace08bae0d6.png

data\['poutcome'\].value_counts()

32a86e5a2c4df348c2a8428b3c5c4f56.png

描述性统计

数值总结

data.head(5)

b0a610bdf372bf03bb1b09d039898b03.png

改变因变量 y 的值。代替 no - 0 和代替 yes - 1。

data\['y'\] = data\['y'\].map({'no': 0, 'yes': 1})
data.columns

d945952d6d1e3e618fab63f233cb576b.png

对于我们的每个变量,我们绘制一个箱线图来查看是否有任何可见的异常值。

plt.figure(figsize=\[10,25\])
ax = plt.subplot(611)
sns.boxplot(data\['age'\],orient="v")

d8a0ba16712f2470e6a6e4211767a449.png

3c1a63d9829fffe3272fbed28c2417e4.png

0b77a32019eb1ef8332eb637a6f1e824.png

20b27b7bf16e84c782b59b68e0bf2d78.png

9e7a4b4d0cc59342e6fe53739c7f69ed.png

c9ddcb7710a2a3c87eeaa20402073aec.png

我们可以看到许多可见的异常值,尤其是在 balance 、 campaign 、 pdays 的情况下。在 pdays ,我们可以看到很多变量都在分位数范围之外。这个变量是一个特例,它被解码为 -1,这就是我们的图看起来像这样的原因。在表示变量之前的箱线图的情况下,它表示在此活动之前执行的联系数量,在这种情况下,我们还可以注意到许多超出分位数范围的值。

直方图

我们的下一步是查看连续变量的分布和直方图
我们可以看到没有一个变量具有正态分布。

plt.figure(figsize=\[10,20\])
plt.subplot(611)
g = sns.distplot(data\["age"\], color="r")

9d3785954a2970d54388b494ff9cf7df.png

a26c93e76fb82e73edcc6e0bc3df9488.png

273ad838d7a07629f9f51fc12307e9b7.png

b7a2b146d376beee66fea0c85226e257.png

71389ac14886cfea4c65d0c6bac094f1.png

054817ae5476b5b35c47bf3fea668745.png

我们的下一步是查看因变量 y 与每个变量或连续变量之间的关系。

g = sns.FacetGrid(data, col='y',size=4)
g.map

fa4f8614eeca85ab96959536ec9ec294.png

55ca5b98e9709dfbea06c1867a0c3b30.png

55ad9bb70bf57812d36b0a5fd68f67c0.png

fc0e812ae6c13b48b76497fd3bf0cc09.png

aa7ef97669c6edc9f0d3546c7a8954ea.png

66d658788eab57ca1672b070db8819b9.png

从这些变量中我们可以得到的最有趣的观察是,大多数说不的人年龄在20-40岁之间,在月底的第20天,大多数人也拒绝了这个提议。

分类总结

我们制作仅包含分类变量的数据子集,以便更轻松地绘制箱线图

data_categorical = data\[\['job',
 'marital',
 'education',
 'default', 'housing',
 'loan','month', 'y'\]\]

e61fbb33e6f079f0f442596407121e9a.png

17abc7e7842d3c3c29a4aa8ee3fc2f79.png

9eaf3e659af91519bc98066b32ab1c4f.png

我们还查看了分类变量,看看是否有一些有趣的特征
从上面的条形图中可以看出,最有趣的结果来自变量:婚姻状况、教育和工作。
从代表婚姻状况的图表来看,大多数人都已婚。
正如我们在代表教育的图表上看到的那样 - 最大的是接受过中等教育的人数。
在约伯的情况下,我们可以看到大多数人都有蓝领和管理工作。

我们还想在马赛克图上查看我们的分类变量与 y 变量之间的关系。

plt.rcParams\['font.size'\] = 16.0

8f95d3708443ee448036b378ff4fb91a.png

正如我们所见,大多数人都拒绝了该提议。就地位而言,已婚的人说“不”最多。

21b893cc1697c5b76dd2a47a8acc0dd4.png

在可变违约的情况下,大多数没有违约信用的人也拒绝了该提案。

52b3095e70fb1041dc6c50f1d6a323b8.png

大多数有住房贷款的人也拒绝了该提议。

a5c30610d346df7164e6b8cc3c9a93aa.png

大多数没有贷款的人拒绝了这个提议。


点击标题查阅往期内容

cf2fd5febb26d1b9c4a28164ad2f0337.png

用PyTorch机器学习神经网络分类预测银行客户流失模型

outside_default.png

左右滑动查看更多

outside_default.png

01

d15d66bada315b74a51fbfe1fd16ddbc.png

02

f922ba1a04f63299e7082fd72dc97d7e.png

03

115c13a7f68388984f840153444c02e0.png

04

232912de6f6cf642cbb3e084d41c9c35.png

数据挖掘

data.head(5)

11ee60619ccb1c356e13abd2b8afbfd6.png

我们想更深入地研究我们的变量,看看我们是否可以用它们做更多的事情。

我们的下一步是使用 WOE 分析。

finv, IV = datars(data,data.y)
IV

54ec5b49bac91ffe381d06e1d14b1e06.png

基于对我们有用的 WOE 分析变量是:pdays、previous、job、housing、balance、month、duration、poutcome、contact。
在下一步中,我们决定根据 WOE 结果和变量的先前结果删除无用的列。
我们删除的其中一个列是 poutcome,尽管它的 WOE 很高,但我们决定删除它,因为从 prevois 分析中我们看到它有许多未知的观察结果。
在可变持续时间的情况下,我们也可以看到WOE相当大,甚至可以说这个结果有点可疑。我们决定根据 WOE 结果放弃它,因为我们的模型应该根据过去的数据说明是否建议给某个人打电话。
在可变接触的情况下,我们放弃了它,因为对我们来说,接触形式在我们的模型中没有用。
我们还删除了变量 day 因为它对我们没有用,因为这个变量代表天数,而该变量的 WOE 非常小。我们删除的最后一个变量是变量 pdays,尽管这个变量 WOE 的结果非常好,但它对我们来说并不是一个有用的变量。

我们分析中剩下的列:

3e63cfc8b65cdad4576f6fd523d936d3.png

特征选择和工程

要执行我们的算法,我们首先需要将字符串更改为二进制变量。

data = pd.get_dummies(data=data, columns = \['job', 'marital', 'education' , 'month'\], \
                                   prefix = \['job', 'marital', 'education' , 'month'\])

d50100cbdc18de1a58416a8ca01a7984.png

我们更改了列的名称。

data.head(5)

a60fad79b9eebc8b10b503e90cc933c7.png

创建虚拟变量后,我们进行了 Pearson 相关。

age = pearsonr(data\['age'\], data\['y'\])

1213f8c9cbc8c5dbf3f8e485adf8ba93.png

sns.heatmap(corr

cb77020710183bf3f0b487c1cf293fd2.png

我们选择了数字列来检查相关性。正如我们所看到的,没有相关性。

我们查看因变量和连续变量之间的关系。

pylab.show()

0fcff48c1947aac8641e63d33aae74b1.png

交叉验证

经过所有准备工作,我们终于可以将数据集拆分为训练集和测试集。

算法的实现

逻辑回归

K=5
kf = KFold(n_splits=K, shuffle=True)

logreg = LogisticRegression()
\[\[7872   93\]
 \[ 992   86\]\]

5ab21ddc5615095d7d549ec3c36a4b5c.png

cb58a7ad8851006e2e5416e68f3ebe54.png

\[\[7919   81\]
 \[ 956   86\]\]

28c395ed3b6f45926aef96906a038ef8.png

d479ed35882692fd3f6e123bbfc64fbe.png

\[\[7952   60\]
 \[ 971   59\]\]

8e9762b5b54d5155f2b185bc294246df.png

b4378d460b30e881dd6730fe33549579.png

\[\[7871   82\]
 \[1024   65\]\]

2e9e29d7a400905cf90fdc3033bb90f0.png

1f7af0d726df6dec9fe5e12f3d8c7ddd.png

\[\[7923   69\]
 \[ 975   75\]\]

8265af1e0193656d96b32fd5d4b90411.png

fa698cd0474baaa75ff11015ea6ec98a.png

决策树

dt2 = tree.DecisionTreeClassifier(random\_state=1, max\_depth=2)
\[\[7988    0\]
 \[1055    0\]\]

ca05735f506fa9f5665f1197acbb2f7f.png

9298e4184951025602d8eaee07789b88.png

\[\[7986    0\]
 \[1056    0\]\]

762e65cb829d7e40e18cef9b1a31138d.png

91a19a04e78ed3bd79a49fe945ce9dde.png

\[\[7920   30\]
 \[1061   31\]\]

52b0783d7368fbe5669130d114e8bf9d.png

9cfa0ad29014f75259e7bb60d220de62.png

\[\[8021    0\]
 \[1021    0\]\]

9473ed2a58d1c89ee2ec561cc0602646.png

4de4639d2849474f9f1c27da92d2e816.png

\[\[7938   39\]
 \[1039   26\]\]

21d5cf4847457427e4b3a5a60151283b.png

e0f041023c2f568171faa63356d55bca.png

随机森林

random_forest = RandomForestClassifier
\[\[7812  183\]
 \[ 891  157\]\]

50daa771a4b0325e5bde74f442595658.png

81840f750c7ecf5f0fd586200fe76d36.png

\[\[7825  183\]
 \[ 870  164\]\]

cb77854aeb1f5421431293ed022ccd2b.png

fc6f1826ab6f7469ccba830adf959730.png

\[\[7774  184\]
 \[ 915  169\]\]

29dd43aa595ce3a4ac46608fd199eb80.png

f951d0e061cdd12a4204d62312c26869.png

\[\[7770  177\]
 \[ 912  183\]\]

900b9611c370abb182a586a9bd19f3d2.png

6b5e252c9aa435b077a2a483644802af.png

\[\[7818  196\]
 \[ 866  162\]\]

046ca4d3c2f3d4ac15ce3e9047d14b6a.png

a32902799e0f706efab9a4a044829d43.png

KNN近邻

classifier = KNeighborsClassifier(n_neighbors =13,metric = 'minkowski' , p=2)

print("Mean accuracy: ",accuracyknn/K)
print("The best AUC: ", bestaucknn)
\[\[7952   30\]
 \[1046   15\]\]

cb599e2710b60b51e9bf2cccf81e353b.png

b5572477230457a878a2e4206a9b07ed.png

\[\[7987   30\]
 \[1010   15\]\]

106eed86115bac09c337841b3de32502.png

451d380da7cb0308348ac81c77c2505f.png

\[\[7989   23\]
 \[1017   13\]\]

09cbea2067f8385d98349cd219085b98.png

e99af0b528ebdf9053ba38b679b431ea.png

\[\[7920   22\]
 \[1083   17\]\]

f49d19d58ac80107622a68fca74541ad.png

9dc2b208e7324ec8b2200f3355c1b37b.png

\[\[7948   21\]
 \[1052   21\]\]

24403f0ae86e42a258c42ba8cd31cbb2.png

e8b78d45137e1e1b6ec8930ac2fba4e9.png

高斯朴素贝叶斯

kf = KFold(n_splits=K, shuffle=True)

gaussian = GaussianNB()
\[\[7340  690\]
 \[ 682  331\]\]

ff2c8737ade836878fd42e691b045444.png

0ece593ce8ec9c7b65dfdd3db26f08e4.png

\[\[7321  633\]
 \[ 699  389\]\]

c9d88f63c7ffd7032522820cdaca5f98.png

8481e1cebad8d14c8b0abb616aa2df58.png

\[\[7291  672\]
 \[ 693  386\]\]

37a40a212decc81ac86d4d4b730112b2.png

4a968396716b01b621a4aa6b94eac040.png

\[\[7300  659\]
 \[ 714  369\]\]

a93ecdb6446a3bf910a3437ec4a8e2e9.png

ddbe8f2ea58456c83f7e1996585ad617.png

\[\[7327  689\]
 \[ 682  344\]\]

458d7e3bb89af7ba6e913641c8811635.png

ce79da27ab71e93216610f5c91d8e6b5.png

``````
models = pd.DataFrame({
    'Model': \['KNN', 'Logistic Regression', 
              'Naive Bayes', 'Decision Tree','Random Forest'\],
    'Score': \[ accuracyknn/K, accuracylogreg/K, 
              accuracygnb/K, accuracydt/K, accuracyrf/K\],
    'BestAUC': \[bestaucknn,bestauclogreg,bestaucgnb,
                bestaucdt,bestaucrf\]})

75c18129a178fee1c1f1dc37aaadb6f6.png

我们看到根据 AUC 值的最佳模型是朴素贝叶斯我们不应该太在意最低的 R2 分数,因为数据非常不平衡(很容易预测 y=0)。在混淆矩阵中,我们看到它预测了漂亮的价值真正值和负值。令我们惊讶的是,决策树的 AUC 约为 50%。

欠采样

我们尝试对变量 y=0 进行欠采样

gTrain, gValid = train\_test\_split

325a953f29538031b9106f4892b61cd0.png

逻辑回归

predsTrain = logreg.predict(gTrainUrandom)

0371eb8fb8a7981c616b300384310765.png

predsTrain = logreg.predict(gTrain20Urandom)

8639473706a7fe1a814a144ae4d3a1e7.png

predsTrain = logreg.predict(gTrrandom)

729c89dfcef7193943eddcdbbe00f9c0.png

决策树

print("Train AUC:", metrics.roc\_auc\_score(ygTrds))

790b74440cfac646758afbc98dea3b4f.png

随机森林

print("Train AUC:", metrics.roc\_auc\_score(ygTr, predsTrain),
      "Valid AUC:", metrics.roc\_auc\_score(ygVd, preds))

ce019f2a928ce2d420eb6f265c5fb60b.png

KNN近邻

print("Train AUC:", metrics.roc\_auc\_score(ygTrm, predsTrain),
      "Valid AUC:", metrics.roc\_auc\_score(ygVal10, preds))

674d660b972fbc813de45f1dd6449285.png

高斯朴素贝叶斯

print("Train AUC:", metrics.roc\_auc\_score(ygTraom, predsTrain),
      "Valid AUC:", metrics.roc\_auc\_score(ygid, preds))

d40150f83b7e5d587f3dc64642311d58.png

过采样

我们尝试对变量 y=1 进行过采样

feates = datolist()
print(feures)
feaes.remove('y')

257b1992df447885fab2b0aba0bd0fc9.png

print(gTrainOSM.shape)
(31945, 39)
``````
smt = SMOT
(32345, 39)
``````
smt = SMOT
(32595, 39)
``````
ygTrain10OSM=gTrain10OSM\['y'\]
gTrain10OSM=gTrain10OSM.drop(columns=\['y'\])

逻辑回归

print("Train AUC:", metrics.roc\_auc\_score(ygTrin10SM, predsTrain),
      "Valid AUC:", metrics.roc\_auc\_score(ygValid, preds))

9dc141f0c5ac588e84ffe036b6447e56.png

决策树

dt2.fit(,ygTranOS)
predsTrain = dtpreict(TrainOSM)
preds = dt2.predict(gValid)

ffb7d9df70a5d2e8617aa53d570b03c7.png

随机森林

random_forest.fit(rainOSM, ygTranOS)
predsTrain = random_forest.prect(gTraiOSM)
p

8342bdb476b9c84724201965e15c2025.png

KNN近邻

classifier.fit(granOSM, yTanOSM)
predsTrain = classifier.predict(gTaiSM)
preds = classifier.predict(Vaid)

7eeb38e8fd76f3aa76adaf38bb8310a3.png

高斯朴素贝叶斯

gaussian.fit(gTriOM, ygrainM)
predsTrain = gaussian.predcti)

62b6899e2d01e2d40557d679dc76f62d.png

结论

我们看到欠采样和过采样变量 y 对 AUC 没有太大帮助。

数据获取

在下面公众号后台回复“银行数”,可获取完整数据。


2c641b0b25a603bb760584933a25053c.png

本文摘选PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SVM分析营销活动数据,点击“阅读原文”获取全文完整资料。

34df6c5a2efe1e9f35cb553d4ff54418.jpeg

本文中的银行数据分享到会员群,扫描下面二维码即可加群!

6ea6a44f1fb0665924a70040b417ccec.png

b5e2bb05da711680b8c6e37eaacf0036.jpeg

f80d0c99ec5768609f5a8169b4ec8c47.png

点击标题查阅往期内容

用PyTorch机器学习神经网络分类预测银行客户流失模型

R语言用FNN-LSTM假近邻长短期记忆人工神经网络模型进行时间序列深度学习预测4个案例

Python中TensorFlow的长短期记忆神经网络(LSTM)、指数移动平均法预测股票市场和可视化

R语言KERAS用RNN、双向RNNS递归神经网络、LSTM分析预测温度时间序列、 IMDB电影评分情感

Python用Keras神经网络序列模型回归拟合预测、准确度检查和结果可视化

Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析

R语言中的神经网络预测时间序列:多层感知器(MLP)和极限学习机(ELM)数据分析报告

R语言深度学习:用keras神经网络回归模型预测时间序列数据

Matlab用深度学习长短期记忆(LSTM)神经网络对文本数据进行分类

R语言KERAS深度学习CNN卷积神经网络分类识别手写数字图像数据(MNIST)

MATLAB中用BP神经网络预测人体脂肪百分比数据

Python中用PyTorch机器学习神经网络分类预测银行客户流失模型

R语言实现CNN(卷积神经网络)模型进行回归数据分析

Python使用神经网络进行简单文本分类

R语言用神经网络改进Nelson-Siegel模型拟合收益率曲线分析

R语言基于递归神经网络RNN的温度时间序列预测

R语言神经网络模型预测车辆数量时间序列

R语言中的BP神经网络模型分析学生成绩

matlab使用长短期记忆(LSTM)神经网络对序列数据进行分类

R语言实现拟合神经网络预测和结果可视化

用R语言实现神经网络预测股票实例

使用PYTHON中KERAS的LSTM递归神经网络进行时间序列预测

python用于NLP的seq2seq模型实例:用Keras实现神经网络机器翻译

用于NLP的Python:使用Keras的多标签文本LSTM神经网络分类

6f7f4279f9788b8d83ea3ad49fb44160.png

9cedb51253432a7726394383fa8c009b.jpeg

23c710308e722a4f04b90017566b4b5c.png

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐