机器学习实战:银行客户是否认购定期存款

news2024/12/25 6:08:28

项目结构与步骤

1. 项目概述

  • 项目名称:葡萄牙银行电话营销活动分析与定期存款认购预测
  • 目标:通过分析银行的电话营销数据,构建模型预测客户是否会认购定期存款。
  • 数据来源:葡萄牙银行营销活动数据集
  • 关键挑战:数据不平衡,数据中认购定期存款的客户较少。

2. 问题定义

  • 业务问题:提高银行电话营销活动的成功率,优化客户名单,减少不必要的联系,提高存款认购率。
  • 任务:分类问题,预测目标变量 y(客户是否认购定期存款)。

3. 变量说明与分析

# 数据来源于国外的数据库


分析过程

1、导数数据,看一下并一下数据的相关信息,检测有没有缺失值。

import pandas as pd
data0 = pd.read_csv("bank.csv")
# 数据分析前最好拷贝一份数据
data = data.copy()
print(data.info())

就结果来看,一个4521条数据,16个特征变量,一个目标变量y,每一特征列都没有缺失值。数据量不算很大(<1w条,小规模数据集),如果对精度有要求,可以直接用CatBoost模型,但是训练速度较慢。

2、我们输出最后10行看看数据大概长什么样。

3、发现类别特征为英文文本(比如job),二分类特征(比如default)也为英文文本("Yes" or "No"),因此我们要对这些变量进行编码,转换成计算机能处理的数值型变量。

# 将部分二元分类特征转换为数值(yes -> 1, no -> 0)
binary_columns = ['default', 'housing', 'loan', 'y']
for col in binary_columns:
    data[col] = data[col].map({"yes": 1, "no": 0})

# 对类别特征进行独热编码
data = pd.get_dummies(data, columns=['job', 'marital', 'education', 'contact', 'poutcome'], drop_first=True)

# 将月份映射为数值
month_mapping = {
    "jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6, "jul": 7,
    "aug": 8, "sep": 9, "oct": 10, "nov": 11, "dec": 12
}
data['month'] = data['month'].map(month_mapping)

# 分离特征和目标变量
X = data.drop("y", axis=1)
y = data['y']

4、由于数据集目标变量y类别不平衡,会影响模型效果,我们先处理类别不平衡,这里我们使用欠采样(减少多数类数据)来处理。

from imblearn.under_sampling import RandomUnderSampler

# 处理类别不平衡问题(欠采样)
rus = RandomUnderSampler(random_state=40)
X, y = rus.fit_resample(X, y)

# 检查一下是否平衡
print(y.value_counts())
# 输出后10条数据,检查一下类别变量是否都成功编码
print(X.tail(10))

类别平衡了,编码也没问题。

5、这里我们用普通决策树分类器、随机森林、GBDT、CatBoost练练手。

我们先使用决策树分类器(CART算法)训练模型,并利用网格搜索 + 交叉验证来优化超参数。根据我们的任务需求,我们模型预测准确度要尽可能高,因此我们用准确的来评估模型。

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score
import time

# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y)

# 决策树分类器 + 超参数网格搜索
dt = DecisionTreeClassifier(random_state=40)

param_grid = {
    'criterion': ['gini', 'entropy'],  # 分裂标准
    'max_depth': [None, 9, 10, 11],  # 树的最大深度
    'min_samples_split': [2, 4, 5, 7, 10],  # 节点分裂的最小样本数
    'min_samples_leaf': [1, 2, 3, 4, 5, 10],    # 叶节点的最小样本数
}

# 开始计时
start_time = time.time()

# 网格搜索 + 5折交叉验证
grid_search = GridSearchCV(estimator=dt, param_grid=param_grid, scoring='accuracy', cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)

# 输出最佳参数和模型
best_params = grid_search.best_params_
best_model = grid_search.best_estimator_

# 预测和评估
y_pred = best_model.predict(X_test)
end_time = time.time()

# 打印结果
print("最佳参数:", best_params)
print("训练时间: {:.2f}秒".format(end_time - start_time))
print("测试集准确率:", accuracy_score(y_test, y_pred))

单颗决策树,得出最好的模型准确率80%,效果还可以,我们希望可以更高一些。

6、我们这次选用随机森林来预测。

import time
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score

# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)

start_time = time.time()

# 模型构建
rf = RandomForestClassifier(random_state=42)

# 设置超参数搜索网格
param_grid = {
    'n_estimators': [34, 36, 38, 40, 42],
    'max_depth': [18, 20, 22, 24, 26],
    'min_samples_split': [8, 10, 12, 15, 18],
    'min_samples_leaf': [2, 3, 4, 5, 6],
    'bootstrap': [True, False]
}

# 超参数调优
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, scoring='accuracy', cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)

# 模型评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
end_time = time.time() 
training_time = end_time - start_time

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"训练时间: {training_time:.2f} 秒")
print("最优参数:", grid_search.best_params_)
print("测试集准确率:", accuracy)

随机森林模型准确率在85%左右,提高了很大,效果已经很好了。

8、不妨再试试GBDT模型。

import time
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score


# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)

start_time = time.time()
# 定义 GBDT 模型
gbdt_model = GradientBoostingClassifier(random_state=42)

# 设置超参数搜索网格
param_grid = {
    'n_estimators': [100, 200, 250],        # 弱学习器(树)的数量
    'learning_rate': [0.01, 0.05, 0.1],    # 学习率
    'max_depth': [3, 4, 5],                # 每棵树的深度
    'min_samples_split': [5,10, 15],     # 内部节点划分的最小样本数
    'min_samples_leaf': [1, 3, 5],         # 叶节点的最小样本数
}

# 使用 GridSearchCV 进行超参数调优
grid_search = GridSearchCV(estimator=gbdt_model, param_grid=param_grid, scoring='accuracy', cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)


# 模型评估、预测
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
end_time = time.time() 

# 输出最优参数
print("最优参数:", grid_search.best_params_)
print("测试集准确率:", accuracy)
training_time = end_time - start_time
print(f"训练时间: {training_time:.2f} 秒")

效果跟随机森林差不多。

9、由于数据集中,类别特征较多,非常适合使用CatBoost模型。对于catboost而言,不用对类别进行独热编码,只要进行简单的标签编码即可。

import time
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from imblearn.under_sampling import RandomUnderSampler
from catboost import CatBoostClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, precision_score

# 数据加载
data = pd.read_csv("bank.csv").copy()

# 将部分二元分类特征转换为数值(yes -> 1, no -> 0)
binary_columns = ['default', 'housing', 'loan', 'y']
for col in binary_columns:
    data[col] = data[col].map({"yes": 1, "no": 0})

# 使用 LabelEncoder 对类别特征进行标签编码
label_columns = ['job', 'marital', 'education', 'contact', 'poutcome', 'month']
label_encoders = {}

for col in label_columns:
    le = LabelEncoder()
    data[col] = le.fit_transform(data[col])
    label_encoders[col] = le  # 保存每个列的编码器(如果需要解码)

# 分离特征和目标变量
X = data.drop("y", axis=1)
y = data['y']

# 处理类别不平衡问题(欠采样)
rus = RandomUnderSampler(random_state=40)
X, y = rus.fit_resample(X, y)

# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)

# 定义 CatBoost 模型
start_time = time.time()
catboost_model = CatBoostClassifier(verbose=0, random_state=42)

# 设置超参数搜索网格
# 这是我多次测试的数据,已经是经过压缩的,所以只有一个参数
param_grid = {
    'iterations': [285,290,295],
    'depth': [6],
    'learning_rate': [0.05],
    'l2_leaf_reg': [6]
}

# 使用 GridSearchCV 进行超参数调优
grid_search = GridSearchCV(estimator=catboost_model, param_grid=param_grid, scoring='accuracy', cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)

# 模型评估、预测
best_model = grid_search.best_estimator_
best_params = grid_search.best_params_
y_pred = best_model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
end_time = time.time()

print("最佳参数:", best_params)
print("训练时间: {:.2f}秒".format(end_time - start_time))
print("测试集准确率:", accuracy_score(y_test, y_pred))

# 文章哪里可以改进的,或者哪里做的不好的,欢迎大家讨论分享,希望能指点我!

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

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

相关文章

服务器数据恢复—raid5阵列热备盘上线失败导致EXT3文件系统不可用的数据恢复案例

服务器数据恢复环境&#xff1a; 两组分别由4块SAS硬盘组建的raid5阵列&#xff0c;两组阵列划分的LUN组成LVM架构&#xff0c;格式化为EXT3文件系统。 服务器故障&#xff1a; 一组raid5阵列中的一块硬盘离线。热备盘自动上线替换离线硬盘&#xff0c;但在热备盘上线同步数据…

C++vector

Cvector是标准库中的一员&#xff0c;vector直译过来是“向量”、“矢量”的意思&#xff0c;在C中&#xff0c;是一个动态的数组容器&#xff0c;可以动态的开辟空间&#xff0c;自动实现内存的管理&#xff0c;不需要我们手动操作&#xff0c;在标准库中&#xff0c;写作一个…

“漫步北京”小程序及“气象景观数字化服务平台”上线啦

随着科技的飞速发展&#xff0c;智慧旅游已成为现代旅游业的重要趋势。近日&#xff0c;北京万云科技有限公司联合北京市气象服务中心&#xff0c;打造的“气象景观数字化服务平台“和“漫步北京“小程序已经上线&#xff0c;作为智慧旅游的典型代表&#xff0c;以其丰富的功能…

LlamaIndex+本地部署InternLM实践

LlamaIndex本地部署InternLM实践 XTuner是一个调整模型参数的小工具,通过对于给定的大模型输入有限的参数来调整同类型问题的结果输出 ‌LlamaIndex‌是一个将大语言模型&#xff08;LLMs&#xff09;和外部数据连接在一起的工具&#xff0c;主要用于增强大模型的知识获取能力…

【阵列信号处理】相干信号和非相干信号生成

文章目录 一、总结二、知识点相干&#xff08;coherent&#xff09;和非相干&#xff08;incoherent&#xff09;信号相干信号生成代码 相关信号&#xff08;correlated signal&#xff09;相关信号生成代码 正交信号定义 本文记录博主的科研日记。如果对博主的其他文章感兴趣&…

vue3项目部署在阿里云轻量应用服务器上

文章目录 概要整体部署流程技术细节小结 概要 vue3前端项目部署在阿里云轻量服务器 整体部署流程 首先有一个Vue3前端项目和阿里云应用服务器 确保环境准备 如果是新的服务器&#xff0c;在服务器内运行以下命令更新软件包 sudo apt update && sudo apt upgrade -y …

东土科技孵化的“网联汽车高速通信技术”前沿产品亮相2024WICV大会

2024世界智能网联汽车大会&#xff08;WICV&#xff09;于近日在北京召开。本次大会发布了由中国汽车工程学会组织全球200余位专家&#xff0c;联合评审遴选出未来十年对于智能网联汽车发展具有重要影响的十大技术趋势&#xff0c;包括“面向高级别自动驾驶的超级人工智能”“网…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…

关于相机选型的一些参数说明

上一篇&#xff1a;关于相机的一些参数计算&#xff08;靶面、视野等&#xff09; 目录 1.卷帘快门和全局快门1.1 卷帘快门1.2 全局快门PS&#xff1a;视觉伺服与快门选择 2.黑白和彩色3.CCD和CMOS3.1 CCD3.2 CMOSCCD VS CMOS 4.面阵和线扫4.1 面阵4.2 线扫4.3 面阵 VS 线扫 5.…

C 语言复习总结记录二

C 语言复习总结记录二 一 控制语句 1、语句的分类 表达式语句函数调用语句复合语句控制语句空语句 控制语句 控制程序的执行流程&#xff0c;实现程序的各种结构方式 C 语言支持三种结构 &#xff1a;顺序结构、选择结构、循环结构&#xff0c;由特定的语句定义符组成C语言…

【mongodb】社区版8:改变配置bindip和授权

更改配置 sudo systemctl restart mongod (base) root@k8s-master-pfsrv:/home/zhangbin# sudo tail -n 20 /var/log/mongodb/mongod.log 日志感觉是成功了:{"t":{"$date":"2024-11-19T19:57:47.076+08:00"

28.UE5游戏框架,事件分发器,蓝图接口

3-3 虚幻游戏框架拆解&#xff0c;游戏规则基础_哔哩哔哩_bilibili 目录 1.游戏架构 2.事件分发器 2.1UI控件中的事件分发器 2.2Actor蓝图中的事件分发器 2.2.1动态决定Actor的分发事件 2.2.2父类中定义事件分发器&#xff0c;子类实现事件分发器 2.3组件蓝图中实现事件…

P1 练习卷(C++4道题)

1.纷繁世界 内存限制&#xff1a;256MB 时间限制&#xff1a;1s 问题描述 这是一个纷繁复杂的世界。 某一天清晨你起床很迟&#xff0c;没有吃上早饭。于是你骑着自行车去超市&#xff0c;但是你又发现商店的工作人员已经重新贴上了价格标签&#xff0c;零食价格都涨了50%。你…

挂壁式空气净化器哪个品牌的质量好?排名top3优秀产品测评分析

随着挂壁式空气净化器市场的不断扩大&#xff0c;各类品牌与型号琳琅满目。但遗憾的是&#xff0c;一些跨界网红品牌过于追求短期效益&#xff0c;导致产品在净化效果与去除异味方面表现平平&#xff0c;使用体验不佳&#xff0c;甚至可能带来二次污染风险&#xff0c;影响人体…

贴代码框架PasteForm特性介绍之image

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…

C++异常: cv::Exception 解决

原因是C中文件路径错误&#xff0c;\ 号在字符串中表示转义字符&#xff0c;"C:\Users\14421\Desktop\123.png" "C:Usersd21DesktopS.png" &#xff0c;所以应该改为 C:\\Users\\14421\\Desktop\\123.png 或者 C:/Users/14421/Desktop/123.png 即可解决问…

libphone desktop编译

linphone-desktop 在ubuntu20.04 下编译 linphone 介绍 Linphone是一款遵循GPL的开源网络视频电话系统&#xff0c;支持多种平台如Windows、Linux、Android等。它基于SIP协议&#xff0c;提供语音、视频通话及即时文本消息功能。核心功能包括SIP用户代理、音频视频Codec支持、…

高精度计算题目合集

高精度计算题目合集 1168&#xff1a;大整数加法 1168&#xff1a;大整数加法 1168&#xff1a;大整数加法 高精度加法原理&#xff1a; a&#xff0c;b&#xff0c;c 都可以用数组表示。这些都是基于c语言的算术运算符形成的运算。 c 3 ( c 1 c 2 ) % 10 c_3(c_1c_2)\%1…

【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)

本期目录 1 爬取思路 2 爬虫过程 2.1 网址 2.2 查看网页代码 3 爬取数据 3.1 导入包 3.2 爬取代码 01 爬取思路 \*- 第一步&#xff0c;获取页面内容\*- 第二步&#xff1a;解析并获取单个项目链接 \*- 第三步&#xff1a;获取子页面内容 \*- 第四步&#xff1a;解析…

【bug】使用transformers训练二分类任务时,训练损失异常大

使用transformers训练二分类任务时&#xff0c;训练损失异常大 问题分析 问题 training_loss异常大&#xff0c;在二分类损失中&#xff0c;收敛在1~2附近&#xff0c;而eval_loss却正常&#xff08;小于0.5&#xff09; 分析 参考&#xff1a; Bug in gradient accumulation…