尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于机器学习的银行客户认购预测与模型落地实践
简介面向计算机相关专业毕业设计、课程设计及期末大作业的机器学习实战项目以银行客户认购产品预测为场景完整覆盖数据探索、特征分析、模型训练与预测提交流程。资源包含全部源码、客户数据集、预训练模型文件与可视化图表项目经导师指导并认可调试通过可确保运行。压缩包共65个文件大小约9.58MB其中5个Python脚本负责分类编码、树模型转换及自动化学习3个Jupyter Notebook分版本展示建模迭代过程5个CSV文件存储训练与测试数据2个pickle文件保存预处理管道和最优模型另有字段说明Excel、配置JSON、文档及43张分布图表目录按数据、模型、日志、图表等模块划分结构清晰。已有572人学习下载适合正在准备毕设或希望以真实项目提升建模能力的学习者。借助Notebook逐行笔记、特征图表和工具脚本可理解银行营销数据中用户特征与认购结果的关系快速复现项目或在此基础上修改用于其他分类预测任务。1. 银行客户认购预测本质是营销响应二分类问题银行网点或呼叫中心里“客户为什么在电话里听完产品介绍却迟迟不点头”是每一轮精准营销都要面对的老问题。这个标题里的“银行客户认购产品预测”在业务侧通常叫营销响应预测在算法侧就是一个典型的监督学习二分类任务拿客户的年龄、职业、账户余额、上一次联系结果等历史行为作特征去预测“这次推荐之后客户是否会发生认购”。预测出的概率不是论文里的装饰而是外呼名单的排序依据——把概率最高的那批人排在最前面接通转化率会有肉眼可见的变化。整套链路说穿了就三步清理一份带标签的历史数据集用 Python 喂给机器学习分类器做训练最后把训练结果固化成一枚可重复调用的模型文件。本文按这条链路把从 CSV 到模型落地的每个细节过一遍。2. 先摸清银行客户认购数据集字段含义、缺失值与目标分布2.1 拿到压缩包后先把项目结构调整成可复现的样子一个毕业设计压缩包里无非是源码、数据集、模型文件三样东西但直接在根目录堆脚本会把训练、预测、配置全搅在一起。我一般会按用途拆成四块即使项目原本不是这个结构跑通后也建议改成这样. ├── data/ │ ├── raw/ # 原始 CSV只读不写 │ └── processed/ # 清洗、特征工程后的中间结果 ├── src/ │ ├── preprocess.py # 数据清洗与特征工程 │ ├── train.py # 模型训练与交叉验证 │ └── predict.py # 加载模型并输出预测结果 ├── models/ # joblib / pkl 模型文件 └── notebooks/ # 探索性分析EDA这样拆的理由很直接data/raw保持原始数据集不变方便随时回滚重跑processed目录缓存中间结果避免每次调参都重新做一遍特征变换models单独建目录是因为后面要频繁保存、加载模型文件路径一旦固定训练和预测脚本就不用互相改来改去。源码目录拆成preprocess、train、predict三个脚本正好对应数据进、模型出、预测出的三趟流程之后替换算法或者换数据集时只需要改其中一层。2.2 读取 CSV 并逐字段检查类型银行营销数据集中最常见的是 UCI Bank Marketing 数据集公开免费字段设计非常接近真实银行的外呼场景。下载后先用 pandas 把数据读进来看一眼形状、字段类型和前几行import pandas as pd df pd.read_csv(data/raw/bank.csv, sep;) print(df.shape) print(df.dtypes) print(df.head())输出确认无误后逐个字段过一遍业务含义。表里这些字段是这套任务的核心也是后面特征工程的直接对象字段类型业务含义处理注意点age数值客户年龄集中在 30~60 岁存在个别异常值job分类型职业含 unknown 值需要归并或单独成类marital分类型婚姻状况类别少直接编码即可education分类型学历有等级关系可考虑顺序编码default二分类是否有信用违约类别极不均衡绝大多数为 nobalance数值年均账户余额右偏明显个别值为负数housing二分类是否有房贷含 unknownloan二分类是否有个人贷款含 unknowncontact分类型联系方式cellular / telephone / unknownday_of_week分类型周几联系可作为周期变量处理month分类型几月联系有明显的季节效应duration数值上次通话时长秒整个数据集里最大的坑后文单独讲campaign数值本次营销中的联系次数数值小但分布极不均匀pdays数值上次联系后经过的天数-1 表示此前从未联系过previous数值之前的联系次数与 pdays 搭配使用poutcome分类型上次营销的结果与 pdays、previous 高度相关y二分类本次是否认购目标变量yes / no字段逐一看完马上检查缺失值。注意这里说的缺失不完全等于 pandas 里的 NaN很多银行营销数据集中“缺失”是以字符串unknown形式存在的这种光靠isna()查不出来。先跑一段基础检查print(df.isna().sum().sum()) for col in df.columns: if df[col].dtype object: unknown_cnt (df[col] unknown).sum() if unknown_cnt 0: print(f{col}: {unknown_cnt})isna()结果通常为 0但不代表没有缺失job、education、contact里的unknown会在特征工程阶段被单独处理或者当作一个独立类别保留这取决于后续选择的机器学习模型。2.3 目标分布类别不平衡是第一个要正视的事实看目标变量y的分布这一步会直接影响评估指标和模型策略print(df[y].value_counts(normalizeTrue))在常见的 UCI Bank Marketing 数据集上输出大概是no占 88%~90%yes占 10%~12%。这意味着无脑预测所有客户“不认购”准确率也能到九成上下。但这种“准”毫无业务价值银行要的就是那 10% 的潜在认购者。不平衡带来的连锁反应有三个准确率不再可信需要用 AUC、KS 等指标评估少数类样本量少训练时容易被模型忽略需要配合class_weight或上采样最终决策不能固定用 0.5 作为分类阈值要根据业务可接受的成本去调。这些都会在模型训练章节逐一展开。3. 特征工程与数据清洗把原始字段变成模型能学懂的样子3.1 分类变量编码One-Hot 还是顺序编码特征工程第一步是处理分类变量。常见的做法是直接pd.get_dummies()但在真实项目里我更推荐用 scikit-learn 的ColumnTransformer它能把预处理流程跟模型绑定在一个 Pipeline 里预测新数据时不漏项、不错位from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder categorical_cols [ job, marital, education, default, housing, loan, contact, month, day_of_week, poutcome ] preprocessor ColumnTransformer( transformers[ (cat, OneHotEncoder( handle_unknownignore, sparse_outputFalse ), categorical_cols) ], remainderpassthrough )handle_unknownignore的作用是如果线上预测时出现训练集里没见过的类别One-Hot 编码器不会报错而是把这一项全部置 0。对银行数据来说这点尤其重要新客户可能来自一个历史数据中未出现过的职业分类ignore能保证推理不中断。education这种情况比较特殊它有初中、高中、大学、研究生这样的递进关系。直接用 One-Hot 会丢掉学历等级的排序信息如果想保留可以手动映射成有序数字unknown - 0, primary - 1, secondary - 2, tertiary - 3。其他字段都是无序类别用 One-Hot 更安全。month虽然也是字符串但它是循环变量12 月之后是 1 月可以考虑切成季节特征或做 sin/cos 转换实际效果因数据集而异建议两个版本都跑一遍对比别凭感觉定。3.2 数值字段清洗异常值、右偏分布与 pdays 的 -1数值字段里最需要动手的是balance和pdays。balance右偏严重少数高净值客户的余额可能达到几十万甚至上百万直接喂给逻辑回归会把梯度带偏。常见的做法是先把负数处理掉再做对数变换import numpy as np df[balance_sign] np.sign(df[balance]) # -1 / 0 / 1 df[balance_log] np.log1p(np.abs(df[balance])) # 压缩右偏 df[never_contacted] (df[pdays] -1).astype(int) # 是否从未被联系过 df[pdays_safe] df[pdays].clip(lower0) # -1 归零避免污染距离计算np.log1p对 0 很友好log1p(0) 0不会出现 log 无穷或 undefined。balance_sign把正负方向单独切出来作为一个特征因为对银行场景来说余额为负和高额为正代表完全不同的人群单纯压数值会抹掉这个区别。pdays的-1是一个特殊标记代表该客户在此之前从未被任何营销活动联系过。如果直接把 -1 当作数值喂给模型模型会学到“-1 代表距离”这完全没有意义。所以拆成两个特征never_contacted标记是否从未联系过pdays_safe只在真正联系过的情况下才有数值。这种手动拆分比让模型自己去猜更可靠也在模型输出时更便于解释。3.3 duration 字段用了它离线指标好看上线就失效duration是整个银行认购预测里最具迷惑性的字段。它表示上次通话的时长和y的相关性极高——通话时间长说明客户没挂电话甚至主动聊了很多认购概率自然高。单独拿duration做特征AUC 随便都能提升几个点。但在真实业务中预测的时点是“这次外呼之前”根本不知道这次通话会持续多久。把duration放进模型等于用未来信息预测未来离线指标虚高上线后完全不成立。我一般建议同时维护两套特征集# 含 duration 的特征集用于复现论文 / 毕业设计指标 features_with_duration df.drop(columns[y]) # 不含 duration 的特征集用于真实业务落地 features_deployed df.drop(columns[y, duration])如果毕业设计要求报告模型效果可以两套都报注明哪套是生产可用的。面试或答辩时主动把duration的问题讲清楚往往比多刷 0.02 的 AUC 更能说明你理解业务。处理完上述清洗后把processed结果保存成中间文件后续训练脚本直接读取不必每次重跑特征工程。4. 机器学习模型训练从逻辑回归基线到集成模型调参4.1 划分策略分层抽样与交叉验证不能省数据量通常只有 4 万行左右且类别不平衡训练集划分必须用分层抽样。普通train_test_split随机切分可能导致测试集中yes样本比例失衡stratifyy能保证训练集和测试集中正负样本比例与原数据集一致from sklearn.model_selection import train_test_split X df_processed.drop(columns[y]) y df_processed[y].map({yes: 1, no: 0}) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, stratifyy, random_state42 )交叉验证也建议用StratifiedKFold而不是普通KFold原因相同。银行认购数据集样本量不大留一法太重5 折分层交叉验证是性价比最高的选择。交叉验证的分数比单次划分更稳定也能看出模型在不同数据子集上的波动泛化能力比单次测试集分数更有说服力。4.2 模型选型逻辑回归打底机器学习分类器逐级进阶这种表格型分类任务从简单模型到复杂模型循序渐进是最稳妥的路径。先上逻辑回归好处是训练快、可解释性强、给后续模型提供基线再上随机森林和 LightGBM看能否在 AUC 上有实质提升。三个模型的关键参数和易踩坑点整理如下模型优势关键参数最常踩的坑LogisticRegression可解释性强特征系数直接可读C、penalty、class_weight数值特征不做标准化梯度收敛慢RandomForest非线性、对异常值鲁棒n_estimators、max_depth、min_samples_leaf树太深过拟合训练慢LightGBM训练快、准确率高num_leaves、learning_rate、n_estimators小数据集上易过拟合逻辑回归代码用 Pipeline 把标准化和分类器串起来from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression lr_pipeline Pipeline([ (preprocess, preprocessor), (scaler, StandardScaler()), (clf, LogisticRegression( C0.5, max_iter2000, class_weightbalanced, random_state42 )) ]) lr_pipeline.fit(X_train, y_train)class_weightbalanced让模型在训练时自动加大少数类的权重缓解类别不平衡。C0.5是正则化强度的逆C 越小正则越强在特征维度偏高的 One-Hot 场景下先收紧一点比较稳妥。StandardScaler只有一个作用逻辑回归靠梯度下降求解特征尺度不一致会让收敛变慢标准化后训练更稳定。随机森林的写法类似替换分类器即可from sklearn.ensemble import RandomForestClassifier rf_pipeline Pipeline([ (preprocess, preprocessor), (clf, RandomForestClassifier( n_estimators300, max_depth12, min_samples_leaf20, class_weightbalanced, n_jobs-1, random_state42 )) ]) rf_pipeline.fit(X_train, y_train)min_samples_leaf20是随机森林里最值得调的参数之一它强制每个叶子节点至少包含 20 个样本能显著抑制过拟合尤其在类别不平衡时避免模型学到个别样本的噪声。max_depth12对 4 万行数据来说足够深越界容易死记训练集。树模型对特征尺度不敏感所以 Pipeline 里没有加StandardScaler。4.3 类别不平衡下怎么评估AUC 和 KS 值比准确率可信三个模型都训练完之后统一用测试集评估。核心指标是 ROC-AUC它只关心正负样本预测分数的排序关系对不平衡数据不敏感。accuracy在这类任务上基本没有参考价值from sklearn.metrics import roc_auc_score, roc_curve, precision_recall_curve y_proba rf_pipeline.predict_proba(X_test)[:, 1] auc_score roc_auc_score(y_test, y_proba) print(fAUC: {auc_score:.4f}) # KS 值累计正负样本分布的最大间距 fpr, tpr, _ roc_curve(y_test, y_proba) ks max(tpr - fpr) print(fKS: {ks:.4f})AUC 在 0.5 到 1 之间0.5 相当于随机猜0.7 以上有可用价值0.8 左右已经是不错的营销模型水平。KS 的取值逻辑与 AUC 类似超过 0.3 说明模型有区分能力金融风控领域更习惯用 KS。确定最终阈值时不要用默认的 0.5。银行场景里外呼一个客户的成本很低错过一个高意向客户的损失更高所以阈值应该往低调。用约登指数Youdens Index可以方便地找到 ROC 曲线上最优点optimal_idx np.argmax(tpr - fpr) optimal_threshold thresholds[optimal_idx] print(f最优阈值: {optimal_threshold:.4f})tpr - fpr最大化对应的阈值就是让“抓到更多正样本”和“别误杀太多负样本”之间达到平衡的分界点。毕业设计里报告这个阈值并说明业务成本如何影响阈值选择比只报一个 AUC 分数扎实得多。5. 模型文件的保存与加载把预测能力封装成可交付的产物5.1 用 joblib 保存模型文件推理时只加载一个文件训练完成不是终点模型要能被反复调用才算完整交付。scikit-learn 生态里保存模型文件首选joblib而不是pickle它对 numpy 数组的序列化做了优化保存大模型时更快、文件更小且与 Pipeline 对象兼容性更好import joblib joblib.dump(rf_pipeline, models/bank_model.joblib)预测时只需要一行加载loaded_model joblib.load(models/bank_model.joblib) new_proba loaded_model.predict_proba(new_data)[:, 1]注意整个预处理逻辑已经内嵌在 Pipeline 里加载完直接对原始 CSV 数据调用predict_proba就行不需要重新写一遍 One-Hot 编码和数值变换。这也是当初用ColumnTransformer和 Pipeline 的回报——模型文件自带了全部预处理知识交付出去的是一个完整可复现的预测组件而不是散落一地的中间步骤。5.2 把预测概率转化成外呼优先级概率并不直接等于业务决策。银行外呼资源有限与其给客户经理一个“买/不买”的死判断不如把客户按预测概率分成五个档位df_result[prob] new_proba df_result[priority] pd.qcut( df_result[prob], q5, labels[E, D, C, B, A] )pd.qcut按分位数切分保证每个档位人数大致相等。A 档是概率最高的 20% 客户优先外呼E 档基本可以放弃电话营销转为短信触达或其他低成本渠道。这种做法比单一阈值灵活得多也更接近银行真实运营习惯。5.3 特征重要性与上线后的数据漂移监测随机森林训练完后feature_importances_可以直接打印查看哪些字段对预测贡献最大importances rf_pipeline.named_steps[clf].feature_importances_ feat_names rf_pipeline.named_steps[preprocess].get_feature_names_out() for name, imp in sorted(zip(feat_names, importances), keylambda x: -x[1])[:10]: print(f{name}: {imp:.4f})特征重要性既用来做业务解释也用来做上线后的监控。如果线上数据分布发生变化比如渠道从电话外呼变为 App 推送contact_cellular的重要性会骤降模型需要重训。监控办法很简单定期统计线上各特征的分布和训练集分布做对比差异超过阈值就触发告警。模型文件不是项目的终点它只是开始被使用的起点。本文还有配套的精品资源点击获取
RELATED

相关推荐

书霸AI期刊论文:官网www.shubaai.com

书霸AI期刊论文:官网www.shubaai.com

过去,很多人理解AI论文工具,往往停留在“输入题目,生成一篇文章”。但从书霸AI写作的期刊论文功能来看,论文辅助正在发生一个明显变化:AI不再只是负责扩写文字,而是逐渐进入研究流程,成为选题梳…

📅 2026/9/16 12:53:18
ECDSA签名算法深入解析:从曲线参数到跨库验签实战

ECDSA签名算法深入解析:从曲线参数到跨库验签实战

简介:这是一份面向C开发者和密码学学习者的ECDSA签名算法示例包,基于Crypto库实现椭圆曲线数字签名流程,涵盖密钥生成、签名与验证的完整工程文件。资源共39个文件,压缩包大小约8.91MB,主要包含cpp与h源码、Visual Stu…

📅 2026/9/16 12:53:18
Joplin 插件清单新元数据指南:用 icons、categories、screenshots 与 promo_tile 打造高质量插件展示页

Joplin 插件清单新元数据指南:用 icons、categories、screenshots 与 promo_tile 打造高质量插件展示页

Joplin 插件清单新元数据指南:用 icons、categories、screenshots 与 promo_tile 打造高质量插件展示页 【免费下载链接】joplin Joplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS. 项目地址: h…

📅 2026/9/16 12:53:18
MORE NEWS

更多资讯

📰

STM32F767与lwIP网络移植全解析:从HAL库ETH到TCP调优

简介:面向STM32F7系列单片机开发者,这套资料以STM32F767为例,演示基于HAL库的TCP网络通信实现。内容覆盖以太网MAC/PHY硬件初始化、lwIP协议栈移植、TCP套接字创建与收发数据等关键环节,并配有Lan8720等常见PHY芯片的配置思路&…

📰

Karpenter 监控 Amazon EC2 API 用量与节流实践指南

Karpenter 监控 Amazon EC2 API 用量与节流实践指南 【免费下载链接】karpenter-provider-aws Karpenter is a Kubernetes Node Autoscaler built for flexibility, performance, and simplicity. 项目地址: https://gitcode.com/GitHub_Trending/ka/karpenter-provider-aws …

📰

LifeOS WriteStory 技能中的 Storr 叙事科学框架:神圣缺陷、控制理论与戏剧性问题的完整实战指南

LifeOS WriteStory 技能中的 Storr 叙事科学框架:神圣缺陷、控制理论与戏剧性问题的完整实战指南 【免费下载链接】LifeOS ⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in lif…

📰

Marin评估系统架构完全设计:从45份Serving配置到数据迁移机制

Marin评估系统架构完全设计:从45份Serving配置到数据迁移机制 【免费下载链接】marin Open-source framework for the research and development of foundation models. 项目地址: https://gitcode.com/GitHub_Trending/ma/marin Marin 是一个面向基础模型研…

📰

Shaka Player 模糊语言匹配(Fuzzy Locale Matching)机制解析:从设计策略到源码实现

Shaka Player 模糊语言匹配(Fuzzy Locale Matching)机制解析:从设计策略到源码实现 【免费下载链接】shaka-player JavaScript player library / DASH & HLS client / MSE-EME player 项目地址: https://gitcode.com/GitHub_Trending/s…

📰

STC15单片机超声波测距OLED显示实战:从原理到原理图设计

简介:这份面向STC15单片机初学者的超声波测距项目,集成了测距算法、OLED显示与硬件原理图,适用于嵌入式课程设计、竞赛备赛或实际避障模块开发,也可作为毕业设计参考。方案基于IAP15系列8051内核MCU,通过HC-SR04类超声…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬