【教学赛】金融数据分析赛题1:银行客户认购产品预测(0.9676)

news2024/11/27 16:33:09

 本文是对天池教学赛,银行客户认购产品预测的记录,教学赛网址如下:

【教学赛】金融数据分析赛题1:银行客户认购产品预测_学习赛_天池大赛-阿里云天池

 1. 读取数据

import pandas as pd

# 加载数据
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

2. 数据处理

2.1 合并数据

# 训练集和测试集合并, 以便于处理特征的数据
df = pd.concat([train, test], axis=0) #将训练数据和测试数据在行的方向拼接
df

得到的结果:

id	age	job	marital	education	default	housing	loan	contact	month	...	campaign	pdays	previous	poutcome	emp_var_rate	cons_price_index	cons_conf_index	lending_rate3m	nr_employed	subscribe
0	1	51	admin.	divorced	professional.course	no	yes	yes	cellular	aug	...	1	112	2	failure	1.4	90.81	-35.53	0.69	5219.74	no
1	2	50	services	married	high.school	unknown	yes	no	cellular	may	...	1	412	2	nonexistent	-1.8	96.33	-40.58	4.05	4974.79	yes
2	3	48	blue-collar	divorced	basic.9y	no	no	no	cellular	apr	...	0	1027	1	failure	-1.8	96.33	-44.74	1.50	5022.61	no
3	4	26	entrepreneur	single	high.school	yes	yes	yes	cellular	aug	...	26	998	0	nonexistent	1.4	97.08	-35.55	5.11	5222.87	yes
4	5	45	admin.	single	university.degree	no	no	no	cellular	nov	...	1	240	4	success	-3.4	89.82	-33.83	1.17	4884.70	no
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
7495	29996	49	admin.	unknown	university.degree	unknown	yes	yes	telephone	apr	...	50	302	1	failure	-1.8	95.77	-40.50	3.86	5058.64	NaN
7496	29997	34	blue-collar	married	basic.4y	no	no	no	cellular	jul	...	8	440	3	failure	1.4	90.59	-47.29	1.77	5156.70	NaN
7497	29998	50	retired	single	basic.4y	no	yes	no	cellular	jun	...	3	997	0	nonexistent	-2.9	97.42	-39.69	1.29	5116.80	NaN
7498	29999	31	technician	married	professional.course	no	no	no	cellular	aug	...	3	1028	0	nonexistent	1.4	96.90	-37.68	5.18	5144.45	NaN
7499	30000	46	admin.	divorced	university.degree	no	yes	no	cellular	aug	...	2	387	3	success	1.4	97.49	-31.54	3.79	5082.25	NaN
30000 rows × 22 columns

可见数据既有数字也有文字,需要将文字转换为数字

2.2 将非数字的特征转换为数字

# 首先选出所有的特征为object(非数字)的特征
cat_columns = df.select_dtypes(include='object').columns  #选择非数字的列,对其进行处理
df[cat_columns]
# 对非数字特征进行编码
from sklearn.preprocessing import LabelEncoder

job_le = LabelEncoder()
df['job'] = job_le.fit_transform(df['job'])
df['marital'] = df['marital'].map({'unknown':0, 'single':1, 'married':2, 'divorced':3})
df['education'] = df['education'].map({'unknown':0, 'basic.4y':1, 'basic.6y':2, 'basic.9y':3, 'high.school':4, 'university.degree':5, 'professional.course':6, 'illiterate':7})
df['housing'] = df['housing'].map({'unknown': 0, 'no': 1, 'yes': 2})
df['loan'] = df['loan'].map({'unknown': 0, 'no': 1, 'yes': 2})
df['contact'] = df['contact'].map({'cellular': 0, 'telephone': 1})
df['day_of_week'] = df['day_of_week'].map({'mon': 0, 'tue': 1, 'wed': 2, 'thu': 3, 'fri': 4})
df['poutcome'] = df['poutcome'].map({'nonexistent': 0, 'failure': 1, 'success': 2})
df['default'] = df['default'].map({'unknown': 0, 'no': 1, 'yes': 2})
df['month'] = df['month'].map({'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, 'jul': 7, 'aug': 8, \
                 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12})
df['subscribe'] = df['subscribe'].map({'no': 0, 'yes': 1})

2.3 切分数据

# 将数据集重新划分为训练集和测试集   通过subscribe是不是空来判断
train = df[df['subscribe'].notnull()]
test = df[df['subscribe'].isnull()]

# 查看训练集中,标签为0和1的比例,可以看出0和1不均衡,0是1的6.6倍
train['subscribe'].value_counts()

得到

0.0    19548
1.0     2952
Name: subscribe, dtype: int64

2.4 分析数据

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

warnings.filterwarnings('ignore')
%matplotlib inline
num_features = [x for x in train.columns if x not in cat_columns and x!='id']

fig = plt.figure(figsize=(80,60))

for i in range(len(num_features)):
    plt.subplot(7,2,i+1)
    sns.boxplot(train[num_features[i]])
    plt.ylabel(num_features[i], fontsize=36)
plt.show()

 存在离群点,对离群点进行处理

2.5 处理离群点

for colum in num_features:
    temp = train[colum]
    q1 = temp.quantile(0.25)
    q2 = temp.quantile(0.75)
    delta = (q2-q1) * 10
    train[colum] = np.clip(temp, q1-delta, q2+delta)
## 将超过10倍的值,进行处理

2.6 其他处理

进行数据均衡和特征选择,但是做完处理后都导致了分类效果变差,此处省略。但是把原码贴出来,供参考。

'''# 采用SMOTE进行过采样,虽然训练的效果好了,但是对于最终的分类效果反而降低了,此处先不采用过采样
from imblearn.over_sampling import SMOTE
from imblearn.over_sampling import ADASYN

#smo = SMOTE(random_state=0, k_neighbors=10)
adasyn = ADASYN()
X_smo, y_smo = adasyn.fit_resample(train.iloc[:,:-1], train.iloc[:,-1])
train_smo = pd.concat([X_smo, y_smo], axis=1)

train_smo['subscribe'].value_counts()'''
'''# 特征选择方法采用SelectFromModel,Model选择树模型
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel

# 提取出训练数据和标签
train_X = train.iloc[:,:-1]
train_y = train.iloc[:,-1]

# clf_ect是模型名,FeaSel为特征选择模型
clf_etc = ExtraTreesClassifier(n_estimators=50)
clf_etc = clf_etc.fit(train_X, train_y)
FeaSel = SelectFromModel(clf_etc, prefit=True)
train_sel = FeaSel.transform(train_X)
test_sel = FeaSel.transform(test.iloc[:,:-1])

# 提取特征名,并把特征名写回原始数据
train_new = pd.DataFrame(train_sel)
feature_idx = FeaSel.get_support() #提取选择的列名
train_new.columns = train_X.columns[feature_idx]  #将列名写回选择后的数据

train_new = pd.concat([train_new, train_y],axis=1)
test_new = pd.DataFrame(test_sel)
test_new.columns = train_X.columns[feature_idx]'''

此部门内容可能存在变量命名方面的问题。 

2.7 数据保存

train_new = train
test_new = test

# 将处理完的数据写回到train_new和test_new进行保存
train_new.to_csv('train_new.csv', index=False)
test_new.to_csv('test_new.csv', index=False)

3. 模型训练

3.1 导入包和数据 

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import AdaBoostClassifier
from xgboost import XGBRFClassifier
from lightgbm import LGBMClassifier
from sklearn.model_selection import cross_val_score
import time

clf_lr = LogisticRegression(random_state=0, solver='lbfgs', multi_class='multinomial')
clf_dt = DecisionTreeClassifier()
clf_rf = RandomForestClassifier()
clf_gb = GradientBoostingClassifier()
clf_adab = AdaBoostClassifier()
clf_xgbrf = XGBRFClassifier()
clf_lgb = LGBMClassifier()

from sklearn.model_selection import train_test_split
train_new = pd.read_csv('train_new.csv')
test_new = pd.read_csv('test_new.csv')
feature_columns = [col for col in train_new.columns if col not in ['subscribe']]
train_data = train_new[feature_columns]
target_data = train_new['subscribe']

3.2 模型调参 

from lightgbm import LGBMClassifier
from sklearn.metrics import classification_report
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(train_data, target_data, test_size=0.2,shuffle=True, random_state=2023)
#X_test, X_valid, y_test, y_valid = train_test_split(X_test, y_test, test_size=0.5,shuffle=True,random_state=2023)

n_estimators = [300]
learning_rate = [0.02]#中0.2最优
subsample = [0.6]
colsample_bytree = [0.7]   ##在[0.5, 0.6, 0.7]中0.6最优
max_depth = [9, 11, 13] ##在[7, 9, 11, 13]中11最优
is_unbalance = [False]
early_stopping_rounds = [300]
num_boost_round = [5000]
metric = ['binary_logloss']
feature_fraction = [0.6, 0.75, 0.9]
bagging_fraction = [0.6, 0.75, 0.9]
bagging_freq = [2, 4, 5, 8]
lambda_l1 = [0, 0.1, 0.4, 0.5]
lambda_l2 =  [0, 10, 15, 35]
cat_smooth = [1, 10, 15, 20]


param = {'n_estimators':n_estimators,
         'learning_rate':learning_rate,
         'subsample':subsample,
         'colsample_bytree':colsample_bytree,
         'max_depth':max_depth,
         'is_unbalance':is_unbalance,
         'early_stopping_rounds':early_stopping_rounds,
         'num_boost_round':num_boost_round,
         'metric':metric,
         'feature_fraction':feature_fraction,
         'bagging_fraction':bagging_fraction,
         'lambda_l1':lambda_l1,
         'lambda_l2':lambda_l2,
         'cat_smooth':cat_smooth}

model = LGBMClassifier()

clf = GridSearchCV(model, param, cv=3, scoring='accuracy', verbose=1, n_jobs=-1)
clf.fit(X_train, y_train, eval_set=[(X_train, y_train),(X_test, y_test)])

print(clf.best_params_, clf.best_score_)

里面只有1个值的,是已经通过GridSearchCV找到的最优优值了,程序显示的是最后的6个参数的寻优,都放到一起训练时间太长了,所以选择分开寻找。

得到的结果:

Early stopping, best iteration is:
[287]	training's binary_logloss: 0.22302	valid_1's binary_logloss: 0.253303
{'bagging_fraction': 0.6, 'cat_smooth': 1, 'colsample_bytree': 0.7, 'early_stopping_rounds': 300, 'feature_fraction': 0.75, 'is_unbalance': False, 'lambda_l1': 0.4, 'lambda_l2': 10, 'learning_rate': 0.02, 'max_depth': 11, 'metric': 'binary_logloss', 'n_estimators': 300, 'num_boost_round': 5000, 'subsample': 0.6} 0.8853333333333334

3.3 预测结果

y_true, y_pred = y_test, clf.predict(X_test)
accuracy = accuracy_score(y_true,y_pred)
print(classification_report(y_true, y_pred))
print('Accuracy',accuracy)

结果

precision    recall  f1-score   support

         0.0       0.91      0.97      0.94      3933
         1.0       0.60      0.32      0.42       567

    accuracy                           0.89      4500
   macro avg       0.75      0.64      0.68      4500
weighted avg       0.87      0.89      0.87      4500

Accuracy 0.8875555555555555

查看混淆矩阵 

from sklearn import metrics
confusion_matrix_result = metrics.confusion_matrix(y_true, y_pred)
plt.figure(figsize=(8,6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('predict')
plt.ylabel('true')
plt.show()

 4. 输出结果

test_x = test[feature_columns]
pred_test = clf.predict(test_x)
result = pd.read_csv('./submission.csv')
subscribe_map ={1: 'yes', 0: 'no'}
result['subscribe'] = [subscribe_map[x] for x in pred_test]
result.to_csv('./baseline_lgb1.csv', index=False)
result['subscribe'].value_counts()

结果:

no     6987
yes     513
Name: subscribe, dtype: int64

5. 提交结果

 6. 总结

本人的方法只获得了0.9676的结果,希望您能在本人的程序基础上进行改进,以得到更佳的效果。如果有了更好的方法,欢迎在留言区告诉我,相互讨论。

改进的思路:

1. 数据处理方面,本人在进行数据均衡时,训练的效果很好,但是最终的效果较差,应该是数据过拟合了;另外在数据的离群点处理方面也可以做更进一步的考虑;

2.方法的改进,本人对比了lr, dt, rf, gb, adab, xgbrf, lgb最终lgb的效果最好,所以最终选择lgb进行调参,可以考虑采用多种方法的组合,进行训练;

3.在lgb的基础上进行调参,这个是最没有科技含量的。不过花时间应该会得到比我的结果更好的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P5587 打字练习————C++

题目 打字练习 题目描述 R 君在练习打字。 有这样一个打字练习网站,给定一个范文和输入框,会根据你的输入计算准确率和打字速度。可以输入的字符有小写字母、空格和 .(英文句号),输入字符后,光标也会跟…

c语言小练pintia11-20

11.计算平均分已知某位学生的数学、英语和计算机课程的成绩分别是87分、72分和93分,求该生3门课程的平均成绩(结果按整型输出)。输入格式:本题无输入输出格式:按照下列格式输出结果:math 87, eng 72, com…

深耕地市区县市场,新华三智行中国走新路

2022年就这样结束了,但是企业数字化的进程从未结束。回顾这一年,对于任何企业而言,数字化优先的战略仍然在继续。不仅如此,数字化走向地市区县市场,带来了更多的机遇和发展,让我们看到了中国的数字经济还有…

Flurry iOS端调研和使用

Flurry iOS端调研使用 flurry官方资料较少,且只有英文文档没有代码demo。公司项目确定要用Flurry,所以深入调研,顺便记录过程。有需要的小伙伴也可以顺便参考 一.创建应用拿api_key 官网:https://www.flurry.com/ 用邮箱去官网…

【目标检测】55、YOLOv8 | YOLOv5 团队 Ultralytics 再次出手,又实现了 SOTA

文章目录一、YOLO 系列算法的简单回顾二、YOLOv8 简介2.1 安装和简单使用2.2 Ultralytics HUB2.2.1 Upload Dataset2.3 YOLOv8 主要改动三、YOLOv8 细节详述论文:暂无 官方文档:https://docs.ultralytics.com/ 代码:https://github.com/ult…

【算法数据结构初阶篇】:链表问题

一、反转单双链表 一、数据结构图 二、代码演示 public class Code01_ReverseList {public static class Node {public int value;public Node next;public Node(int data) {value data;}}public static class DoubleNode {public int value;public DoubleNode last;public …

Spring Cloud Gateway从注册中心自动注册配置路由信息

环境信息Spring Boot:2.0.8.RELEASESpring Boot内置的tomcat:tomcat-embed-core 8.5.37Spring Cloud Gateway:2.0.4.RELEASENacos:2.0.4.RELEASE需求Spring Cloud Gateway注册到注册中心(这里是Nacos,其它注…

Spring学习系列(二)

Spring_特殊值的注入问题和各种类型的自动装配1.set两种方式的区别第4中赋值方式:自动装配(只适用于ref类型)使用注解定义bean1.set两种方式的区别 (1)把值写到value属性里面,必须加引号,写到子…

【学习】计算机系统硬件和数据结构

学习内容描述: 1、CPU包含哪些部分? 2、数据结构基础知识。 重点知识: 1、CPU(中央处理器,Central Processing Unit) 主要包括运算器、控制器两大部件;内部结构包含控制单元、运算单元、存储单元和时钟等几个主要部…

虚拟直播(虚拟场景直播)要怎么做?

阿酷TONY / 2022-11-21 / 长沙 绿幕抠像 虚拟场景(三维场景)实时渲染,来一场虚拟直播。 附案例效果:PC端案例、移动端案例效果。 目录 1. 绿幕虚拟直播间 2. 虚拟场景(炫酷舞台) 3. 案例:PC端 4. 案例&#xff1a…

光纤内窥镜物镜光学设计

光纤内窥镜物镜光学设计 工作原理 典型的光纤传像束内窥镜主要由前置物镜、光纤传像束、目镜/耦接镜、 探测器等组成,如图1所示。通过物镜把目标成像于光纤传像束的前端面上,该端面上的图像被离散分布的大量光纤采样,每根光纤都有良好的光学…

[极客大挑战 2019]Upload

目录 解题步骤 常见的绕过思路 解题步骤 直接上传shell 回显:Not image! bp抓包 修改类型 Content-Type: application/octet-stream改为Content-Type: image/jpg 回显:NOT!php! 修改后缀为phtml 回显:NO! HACKER! your file inc…

SAP MM 物料分类账的启用配置

一、前言 物料账就是一本账,管理物料的数量和价值。 通常物料有两种计价方法: 移动平均价V(移动加权平均) 标准价S 移动平均价的优点:能够及时响应市场原材料价格的波动。 价差科目(总账科目)…

MyBatis-Plus基本操作

依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version> </dependency>基础操作 DAO层 public interface UserMapper extends BaseMapper<User…

nohup + 命令实现后台不挂断地运行程序

nohup&#xff1a; nohup&#xff1a;不挂断地运行程序&#xff0c;就是即便关闭终端的窗口&#xff0c;程序还会继续执行。 $ nohup python merge_reasons.py可以看到终端仍在被占用&#xff0c;同级目录下生成了一个nohup.out文件&#xff0c;本来输出到终端的信息&#xf…

python人工智能数据算法(下)

文章目录差分法逼近微分背景引入差分法简介差分的不同形式及其代码实现蒙特卡罗方法背景引入蒙特卡罗方法原理蒙特卡罗方法应用计算圆周率计算定积分梯度下降算法算法简介方向导数与梯度梯度下降基于梯度下降算法的线性回归算法总结差分法逼近微分 背景引入 几乎所有的机器学…

我收集的PDF电子书

刚出来&#xff0c;要整理一下自己的资源了&#xff0c;好多都没有了&#xff0c;需要下载的自行联系niunanniunan.net 目录 软件工程 构建之法&#xff08;第1版&#xff09; 实现领域驱动设计 领域驱动设计&#xff1a;软件核心复杂性应对之道 人月神话 算法 算法基础…

C语言文件操作(一)

我们之前写程序&#xff0c;得到运行结果&#xff0c;退出运行&#xff0c;运行结果就不见了&#xff0c;因为运行的结果放到了内存中&#xff0c;退出程序的时候数据就会消失&#xff0c;等下一次运行又要重新输入数据&#xff0c;这样就显得很麻烦。那么我们如何保存之前的运…

Opengl ES之RGB转NV21

前言 在上一篇理论文章中我们介绍了YUV到RGB之间转换的几种公式与一些优化算法&#xff0c;今天我们再来介绍一下RGB到YUV的转换&#xff0c;顺便使用Opengl ES做个实践&#xff0c;将一张RGB的图片通过Shader 的方式转换YUV格式图&#xff0c;然后保存到本地。 可能有的童鞋…

SSL协议未开启是什么意思?

SSL协议未开启是指服务器中的服务没有开启或者没有SSL模块。在互联网中&#xff0c;数据交互传输基于http明文协议&#xff0c;随着互联网的不断发展&#xff0c;http协议展现出它的缺陷&#xff0c;通过http协议传输的数据容易被攻击者窃取、篡改或仿冒。为适应新形势下的网络…