0. 写在前面

作为一个重度社恐的老萌新,决定单枪匹马的来参加这个练习赛,也是我参加的第一个此类比赛。

本次练习赛虽然最终成绩真的很普通,欢迎提提高意见,非常感谢。

不过收获真的很多,尝试了很多没接触过的东西。

希望有同学看到这段话,带我打打更大比赛!我可以

1.问题描述

数据选自UCI机器学习库中的「银行营销数据集(Bank Marketing Data Set)」

这些数据与葡萄牙银行机构的营销活动相关。这些营销活动以电话为基础,一般,银行的客服人员需要联系客户至少一次,以此确认客户是否将认购该银行的产品(定期存款)。

因此,与该数据集对应的任务是「分类任务」,「分类目标」是预测客户是(' 1 ')或者否(' 0 ')购买该银行的产品。

2.字段描述

字段说明

NO 字段名称 数据类型 字段描述
1 ID Int 客户唯一标识
2 age Int 客户年龄
3 job String 客户的职业
4 marital String 婚姻状况
5 education String 受教育水平
6 default String 是否有违约记录
7 balance Int 每年账户的平均余额
8 housing String 是否有住房贷款
9 loan String 是否有个人贷款
10 contact String 与客户联系的沟通方式
11 day Int 最后一次联系的时间(几号)
12 month String 最后一次联系的时间(月份)
13 duration Int 最后一次联系的交流时长
14 campaign Int 在本次活动中,与该客户交流过的次数
15 pdays Int 距离上次活动最后一次联系该客户,过去了多久(999表示没有联系过)
16 previous Int 在本次活动之前,与该客户交流过的次数
17 poutcome String 上一次活动的结果
18 y Int 预测客户是否会订购定期存款业务

3.数据预处理

这部分内容比较冗长,虽然不是重点但仔细了解指标,有助于下一节的特征工程,对结果有很大帮助。

3.1数据概览

import numpy as np
import pandas as pd
#导入数据集
def load_data():home_path = r"..." #输入数据所在位置train_path = os.path.join(home_path, "train_set.csv")test_path = os.path.join(home_path, "test_set.csv")train_data = pd.read_csv(train_path)test_data = pd.read_csv(test_path)return train_data, test_datatrainData, testData = load_data()
print('train Data:{}   testData:{}'.format(trainData.shape, testData.shape))
print(trainData.describe())

训练集(25317, 18),测试集(10852, 17)

  age balance day duration campaign   pdays previous y
count 25317.000000 25317 25317 25317 25317 25317 25317 25317
mean 40.93538 1357.555 15.835289 257.7324 2.77205 40.24877 0.591737 0.116957
std 10.63429 2999.823 8.31948 256.9752 3.136097 100.2135 2.568313 0.321375
min 18 -8019 1 0 1 -1 0 0
25% 33 73 8 103 1 -1 0 0
50% 39 448 16 181 2 -1 0 0
75% 48 1435 21 317 3 -1 0 0
max 95 102127 31 3881 55 854 275 1

3.2缺失值处理

#缺失
#训练集
trainData.isnull().sum()#测试集
testData.isnull().sum()

结果表示 训练集与测试集均无缺失值

3.3 特征分布

目标分布:

import matplotlib.pyplot as plt
import seaborn as sns
#目标分布
plt.subplots(figsize=[6,6])
trainData['y'].value_counts().plot(kind='pie',autopct='%.1f%%')

88.3%的用户未办理业务,11.7%的用户办理了业务

下面来看看单指标对于目标y的分布情况

#单指标分布
#首先看分类变量
#job
f, ax = plt.subplots(1, 2, figsize=(10, 5))
trainData[['y', 'job']].groupby(['job']).mean().plot(kind='bar', ax=ax[0])
sns.countplot('job',hue='y',data=trainData,ax=ax[1])
ax[0].set_title('Rate vs job')
ax[1].set_title('number vs job')#其他分类变量套用即可

从以上的柱状图可以看出这些指标与能否成功办理业务的关系:

如无个人/住房贷款,无违约,显然更易成功订购定期存款业务

#再看连续变量
sns.FacetGrid(trainData, hue='y', aspect=2, size=5).map(sns.kdeplot, 'age', shade=True).add_legend()

可见,大约25岁以下客户办理成功率更高,这与前面职业为学生/婚姻状况为单身的成功率更高结论的一致

貌似月初月末有一点影响。看不出什么,日这个指标需与月结合起来形成日期一起看,单看日指标没有很大意义。而月之间有存在的明显的差异,且后面有pdays这个指标表示距离上次活动最后一次联系该客户,过去了多久,因此这个指标可能意义不大。

显然交流时长与y之间的关联性较强。

说明联系紧密的成功办理的可能性更高。

4 特征工程

尽量使用原特征,对二分类变量做序号编码,多分类变量做独热编码,连续变量尽量归一化,这里没有归一化。

from sklearn.model_selection import train_test_split
#将测试集和训练集合并
full = trainData.append(testData, ignore_index=True, sort=False)
full.tail()#哑原处理
data_columns=list(full.columns)
categoricalCol=['ID','job','marital','education','default','housing','loan','contact','month','poutcome']#分类变量名
continuousCol=list(set(data_columns).difference(categoricalCol))  #连续变量
continuousCol
continuousCol.pop(5)#删去y
#对分类变量分别进行序号编码和独热编码
default = pd.Series(np.where(full['default']=='yes', 1, 0), name='default')housing = pd.Series(np.where(full['housing']=='yes', 1, 0), name='housing')loan = pd.Series(np.where(full['loan']=='yes', 1, 0), name='loan')job= pd.get_dummies(full['job'],prefix='job')
marital= pd.get_dummies(full['marital'],prefix='marital')
education= pd.get_dummies(full['education'],prefix='education')
contact= pd.get_dummies(full['contact'],prefix='contact')
month= pd.get_dummies(full['month'],prefix='month')
poutcome= pd.get_dummies(full['poutcome'],prefix='poutcome')#拼回来
full1 = pd.concat([job,marital,education,default,contact,housing,loan,month,poutcome], axis=1)
full2=full[continuousCol].applymap(float) ##连续变量的值变为float格式
FULL=full1.join(full2)
FULL=FULL.join(full['y'])train_set = FULL[0:25317]
test_set = FULL[25317:]
test_set = test_set.drop('y',axis=1)#划分训练集和验证集
feature = train_set.drop('y',axis=1)
label = train_set['y']X_train,X_test,y_train,y_test=train_test_split(feature,label,test_size=0.25,random_state=0)

5.建立模型

在这里我尝试了各种模型,包括knn、逻辑回归、svm等等结果都很不好,然后开始尝试集成学习。

这里主要介绍我尝试gbdt时的过程

由于评分标准是auc,首先定义一个模型评估的函数

from sklearn.metrics import accuracy_score, roc_auc_score,roc_curve,auc
# 性能评估
def model_metrics(clf, X_train, X_test, y_train, y_test):# 预测训练集和测试集y_train_pred = clf.predict(X_train)y_test_pred = clf.predict(X_test)y_train_proba = clf.predict_proba(X_train)[:,1]y_test_proba = clf.predict_proba(X_test)[:,1]# AUC取值print('[auc值]', end = ' ')print('训练集:', '%.4f'%roc_auc_score(y_train, y_train_proba), end = ' ')print('测试集:', '%.4f'%roc_auc_score(y_test, y_test_proba))# ROC曲线fpr_train, tpr_train, thresholds_train = roc_curve(y_train, y_train_proba, pos_label = 1)fpr_test, tpr_test, thresholds_test = roc_curve(y_test, y_test_proba, pos_label = 1)label = ["Train - AUC:{:.4f}".format(auc(fpr_train, tpr_train)), "Test - AUC:{:.4f}".format(auc(fpr_test, tpr_test))]plt.plot(fpr_train,tpr_train)plt.plot(fpr_test,tpr_test)plt.plot([0, 1], [0, 1], 'd--')plt.xlabel('False Positive Rate')plt.ylabel('True Positive Rate')plt.legend(label, loc = 4)plt.title("ROC curve")
clf=ensemble.GradientBoostingClassifier()
clf.fit(X_train,y_train)
model_metrics(clf, X_train, X_test, y_train, y_test)

先是直接用gbdt的默认参数,auc等于

0.9249611515690814

然后进行调参

#大概是这样,前面发现learning_rate=0.29,n_estimators=96时得分最高X_train,X_test,y_train,y_test=train_test_split(feature,label,test_size=0.25,random_state=0)
model = ensemble.GradientBoostingClassifier(learning_rate=0.29,n_estimators=96)
#maxdepths=np.arange(1,20).tolist()
param_grid= {'max_depth':list(range(3,14,2)), 'min_samples_split':list(range(100,801,200))}kflod = StratifiedKFold(n_splits=10, shuffle = True,random_state=7)grid_search = GridSearchCV(model,param_grid,scoring = 'roc_auc',n_jobs = -1,cv = kflod)
grid_result = grid_search.fit(X_train, y_train) #运行网格搜索
print("Best: %f using %s" % (grid_result.best_score_,grid_search.best_params_))
#grid_scores_:给出不同参数情况下的评价结果。best_params_:描述了已取得最佳结果的参数的组合
#best_score_:成员提供优化过程期间观察到的最好的评分
#具有键作为列标题和值作为列的dict,可以导入到DataFrame中。
#注意,“params”键用于存储所有参数候选项的参数设置列表。
means = grid_result.cv_results_['mean_test_score']
params = grid_result.cv_results_['params']
for mean,param in zip(means,params):print("%f  with:   %r" % (mean,param))

尝试了很多次之后 将参数定为  learning_rate=0.29,n_estimators=96,max_depth=5,min_samples_split=700

此时

auc提高到了0.9326.

6.后记

我也尝试其他的集成算法,lgb的得分最高,可是参数调整了半天好像默认参数最高。

后来又尝试了一下用StandardScaler融合模型,结果成绩几乎没有提升,模型选的不好甚至还下降了。

但是发现直接取不同算法结果的算数平均值 有效果。

我还尝试了构建了新的特征,比如有个人贷款或有房贷的令为有贷款,也通过特征重要度删去一些非常不重要的变量,但是效果甚微。

另外本文中代码有多处借鉴并调整,感谢各位前人的分享。

【深度之眼】kesci二分类算法大赛之初体验相关推荐

  1. 深入解析GBDT二分类算法(附代码实现)

    目录: GBDT分类算法简介 GBDT二分类算法 2.1 逻辑回归的对数损失函数 2.2 GBDT二分类原理 GBDT二分类算法实例 手撕GBDT二分类算法 4.1 用Python3实现GBDT二分类 ...

  2. 深入理解GBDT二分类算法

    我的个人微信公众号: Microstrong 微信公众号ID: MicrostrongAI 微信公众号介绍: Microstrong(小强)同学主要研究机器学习.深度学习.计算机视觉.智能对话系统相关 ...

  3. python 二分类的实例_深入理解GBDT二分类算法

    我的个人微信公众号:Microstrong 微信公众号ID:MicrostrongAI 微信公众号介绍:Microstrong(小强)同学主要研究机器学习.深度学习.计算机视觉.智能对话系统相关内容, ...

  4. python复现感知机的二分类算法

    本博客复现感知机的二分类算法 import pandas as pd import numpy as npclass Perceptron:def __init__(self, w=None, b=0 ...

  5. 感知机(Perceptro)二分类算法原理学习小结记录

    感知机是非常古老的一个二分类算法,原理非常简单,直观地来说,对于平面上的两类数据点,找到一条直线来将其划分开来,对于空间中的点,用一个平面来将两部分完全划分开,这样的数据都是线性可分的,也就是在平面或 ...

  6. 「二分类算法」提供银行精准营销解决方案 代码存档

    「二分类算法」提供银行精准营销解决方案 代码存档 参考文章: (1)「二分类算法」提供银行精准营销解决方案 代码存档 (2)https://www.cnblogs.com/starcrm/p/1180 ...

  7. 基于deap脑电数据集的脑电情绪识别二分类算法(附代码)

    想尝试一下脑电情绪识别的各个二分类算法. 代码主要分为三部分:快速傅里叶变换处理(fft).数据预处理.以及各个模型处理. 采用的模型包括:决策树.SVM.KNN三个模型(模型采用的比较简单,可以直接 ...

  8. 「二分类算法」提供银行精准营销解决方案(各个模型汇总分析)baseline

    完整代码见 Github:「二分类算法」提供银行精准营销解决方案 赛事详情 1.比赛页面:「二分类算法」提供银行精准营销解决方案 2.数据与测评算法 训练集下载链接 测试集下载链接 字段说明 测评算法 ...

  9. Adaboost基本二分类算法

    最早类型的Adaboost是由Yoav Freund和Robert E.Schapire提出的,一种用于二分类的boosting集成学习方法.也是李航<统计学习方法>中所介绍的Adaboo ...

最新文章

  1. 2016年IoT和新的逃逸技术将会引领威胁态势
  2. C# 指定字符串截取方法
  3. cygwin编译verilator_Sublime text3 + Verilator 实现自动语法检错
  4. navicat mysql两张表建立联系_初识MySQL
  5. mysql子查询字符串位置_MySql基础-子查询
  6. ARKit从入门到精通(2)-ARKit工作原理及流程介绍
  7. CNN经典网络模型:LeNet,Alexnet,VGGNet,GoogleNet,ReSNet
  8. MFC如何使控件大小随着对话框大小自动调整
  9. Eclipse环境下面的配置(转载)
  10. Android开发笔记(六十六)自定义对话框
  11. 网页设计之字体和 CSS 调整
  12. 省市级联实现,并根据IP自动获取省市
  13. 洛谷P3403 跳楼机(最短路)
  14. android 各版本对应的API(sdk) Level以及中文名称
  15. 2.CPU体系架构-寄存器
  16. LiteIDE的sublime黑色 淡绿色 配色文件自定义版本
  17. acwing1113 红与黑
  18. 禁止触摸屏触控板手指缩放,需要这样处理
  19. 求n的阶乘的算法框图_递归算法是一种直接或者间接调用自身函数或者方法的算法...
  20. python实现二维码识别软件_用 Python 生成 识别二维码

热门文章

  1. Python解析、提取url关键字
  2. angular5项目下利用router navigate实现页面跳转
  3. MATLAB 自然样条函数(约束两端斜率)
  4. 【Struts2源码】@Inject查找并缓存注入器
  5. 如何在Mac上截屏?在Mac上截屏的几种不同方法
  6. DNS BIND之dnssec安全实例配置-根节点
  7. 基于同态加密和秘密共享的无第三方纵向逻辑回归
  8. 怎样查找mysql驱动。
  9. 企业级征信市场破局:阿里、借贷宝大数据“奠基”
  10. python将excel转csv乱码_python解决csv文件用excel打开乱码问题