银行电话营销定期存款认购预测

发布时间:2026/7/18 13:59:08

银行电话营销定期存款认购预测 一、项目背景与问题定义完整数据代码和报告https://mbd.pub/o/bread/YZaUlJxpaA1.1 业务问题电话营销的核心矛盾不是“是否能联系所有客户”而是有限坐席如何优先联系更可能认购的客户。若完全依靠人工经验名单质量难以稳定若只追求模型准确率又会因为未认购客户占比过高而得到虚假的乐观结论。因此本项目将模型定位为客户排序与资源分配工具。1.2 预测时点预测时点设置在本次外呼开始之前。客户年龄、职业、历史联系结果、宏观经济指标等可在此时获得而本次通话时长只能在电话结束后确定。所有字段都要通过“预测时点审查”不满足时点可用性的字段即使能够提升分数也不能进入部署模型。1.3 评价指标指标作用本案例中的意义ROC-AUC衡量整体排序能力观察模型区分认购与未认购客户的总体能力PR-AUC关注正类识别质量正类占比仅约 11%比准确率更有解释力召回率识别出的认购客户比例反映潜在客户遗漏程度精确率预测认购名单中的真实认购比例对应外呼名单的有效浓度F2更强调召回率的综合指标适合“漏掉潜在客户代价较高”的场景提升度/覆盖率评价概率排序的业务价值用于确定联系前 10%、20% 等名单规模二、数据来源与质量检查2.1 数据来源数据来自 UCI Machine Learning Repository 的 Bank Marketing 数据集具体使用 bank-additional-full.csv。该版本包含 41,188 条按时间排序的营销记录和 20 个输入变量记录来自葡萄牙某银行 2008 年 5 月至 2010 年 11 月的电话营销活动。数据集 DOI10.24432/C5K306许可协议为 CC BY 4.0。2.2 数据质量概览检查项目结果处理方式数据规模41,188 行 × 21 列保留全量记录显式缺失值0 个无需数值填补流水线仍保留稳健填补步骤完全重复记录12 条占比极低保留原始数据并在报告中说明目标正类4,640 条11.27%使用分层切分、类别权重和不平衡评价指标unknown 类别最高字段default占比 20.87%作为独立类别保留不擅自推断真实值预测时点风险duration 为本次通话结束后产生主模型剔除只用于泄漏对照2.3 字段分组字段组主要字段分析作用客户属性age、job、marital、education描述客户生命周期、职业与教育结构负债与信用default、housing、loan反映现有贷款和违约信息本轮联系contact、month、day_of_week、campaign描述触达渠道、时间和联系次数历史营销pdays、previous、poutcome反映过去触达与接受结果宏观环境emp.var.rate、cons.price.idx、cons.conf.idx、euribor3m、nr.employed刻画营销活动所处的经济环境泄漏字段duration仅在通话结束后可知不进入外呼前模型目标变量y是否认购定期存款三、探索性分析、建模与结果解释以下每张图均从“图形现象—原因与业务解释—对建模与决策的影响”三个层面展开。单变量图用于发现结构和风险不能替代多变量模型也不能直接证明因果关系。1. 目标变量分布定期存款认购结果target_counts df[y].value_counts().reindex([no,yes]) target_rate target_counts / len(df) fig, ax plt.subplots(figsize(8.5, 5.2)) bars ax.bar([未认购,已认购], target_counts.values, color[COLORS[0], COLORS[2]], width0.58) ax.set_title(图1 目标变量分布定期存款认购结果, fontsize15, pad12) ax.set_ylabel(客户数量) for b, n, r in zip(bars, target_counts.values, target_rate.values): ax.text(b.get_x()b.get_width()/2, b.get_height()500, f{n:,}\n{r:.1%}, hacenter, fontsize11) ax.set_ylim(0, target_counts.max()*1.18) plt.tight_layout(); plt.savefig(OUTPUT_DIR/01_目标变量分布.png, bbox_inchestight); plt.show() display(Markdown(f**图1分析** 全部 {len(df):,} 名客户中仅有 {target_counts[yes]:,} 人认购正类比例为 **{target_rate[yes]:.2%}**。这说明样本存在明显类别不平衡单纯使用准确率可能掩盖模型对潜在认购客户识别不足的问题。因此后续同时采用 ROC-AUC、PR-AUC、召回率、F1 与 F2 值并在逻辑回归和随机森林中引入类别权重。))41,188 条记录中未认购客户为 36,548 人认购客户为 4,640 人认购率仅 11.27%。两类样本数量差距接近 8:1类别不平衡十分明显。银行定期存款营销面对的是低转化率人群多数客户在一次营销活动中不会立即认购。该结构是业务现实而不是可以简单删除的“脏数据”。2. 不同认购结果客户的年龄分布plot_df df.copy() plot_df[认购结果] plot_df[y].map({no:未认购,yes:已认购}) fig, ax plt.subplots(figsize(9,5.5)) sns.histplot(dataplot_df, xage, hue认购结果, bins35, statdensity, common_normFalse, elementstep, fillTrue, alpha.28, palette[COLORS[0], COLORS[2]], axax) ax.set_title(图2 不同认购结果客户的年龄分布, fontsize15, pad12) ax.set_xlabel(年龄); ax.set_ylabel(密度) plt.tight_layout(); plt.savefig(OUTPUT_DIR/02_年龄分布.png, bbox_inchestight); plt.show() age_yes df.loc[df.yyes,age].mean(); age_no df.loc[df.yno,age].mean() senior_rate df.assign(age_grouppd.cut(df.age,[0,29,39,49,59,200], labels[29岁及以下,30-39岁,40-49岁,50-59岁,60岁及以上])).groupby(age_group, observedTrue)[y].apply(lambda s:(syes).mean()) display(Markdown(f**图2分析** 已认购客户平均年龄为 **{age_yes:.1f} 岁**未认购客户平均年龄为 **{age_no:.1f} 岁**。两类客户的主体仍集中在中青年区间但 60 岁以上客户的认购率达到 **{senior_rate.iloc[-1]:.1%}**明显高于整体水平。年龄与认购并非简单线性关系模型应保留非线性学习能力或通过分箱、树模型捕捉退休人群的差异。))认购与未认购客户都集中在 30—50 岁但认购客户在高龄区间的密度相对更高。已认购客户平均年龄约 40.9 岁未认购客户约 39.9 岁60 岁以上客户的认购率达到 39.6%。3. 不同职业客户的认购率学生客户认购率最高约 31.4%退休人员和失业人员也相对较高蓝领客户最低约 6.9%。职业之间不仅转化率不同样本规模也差异明显。4. 不同教育程度客户的认购率5. 各月份营销规模与认购率5 月和 7 月的联系规模较大但认购率并不高3 月认购率最高约 50.5%5 月最低仅约 6.4%。营销数量与转化效率明显不同步。6. 上一次营销结果与本次认购率7. 通话时长与认购率泄漏风险展示8. 三类分类模型在验证集上的性能比较fig,axplt.subplots(figsize(10,5.7));plotcompare[[ROC-AUC,PR-AUC,F1,召回率]].plot(kindbar,axax,color[COLORS[0],COLORS[1],COLORS[2],COLORS[3]],width.76) ax.set_title(图9 三类模型在验证集上的性能比较,fontsize15,pad12);ax.set_ylabel(指标值);ax.set_xlabel(模型);ax.set_ylim(0,1.03);ax.tick_params(axisx,rotation0) ax.legend(ncol4,loclower center,bbox_to_anchor(.5,-.24)) for container in ax.containers: ax.bar_label(container,fmt%.3f,fontsize8,padding2) plt.tight_layout();plt.savefig(OUTPUT_DIR/09_模型比较.png,bbox_inchestight);plt.show() best_namecompare.index[0] display(Markdown(f**图9分析** 由于正类比例较低模型选择以 PR-AUC 为主要依据。验证集上 **{best_name}** 的 PR-AUC 最高为 **{compare.loc[best_name,PR-AUC]:.4f}**对应 ROC-AUC 为 **{compare.loc[best_name,ROC-AUC]:.4f}**。逻辑回归提供较强可解释性树模型能够捕捉变量之间的非线性与交互。最终选择兼顾 PR-AUC、召回率和稳定性的模型并在验证集上进一步调整阈值。))随机森林在验证集上的 PR-AUC 最高为 0.4676ROC-AUC 为 0.8074逻辑回归和随机梯度分类的表现接近说明线性结构已经能捕捉大量有效信号。9. 分类阈值对模型指标的影响10. 最终模型测试集 ROC 曲线与 PR 曲线最终模型测试集 ROC-AUC 为 0.8009PR-AUC 为 0.4599。PR-AUC 明显高于正类基准比例 11.27%说明高分客户中认购者得到有效浓缩。11. 特征置换重要性12. 客户评分分位组的认购率与累计捕获率四、模型训练流程与结果汇总4.1 数据切分与预处理首先将 20% 数据作为独立测试集并按目标变量进行分层切分剩余训练数据再划出验证集用于模型比较和阈值选择。数值变量采用中位数填补与标准化类别变量采用众数填补和独热编码所有步骤放入 scikit-learn Pipeline 中避免训练集与测试集之间发生预处理信息泄漏。主模型剔除 duration。逻辑回归和随机梯度分类使用类别权重随机森林使用 balanced_subsample以提高对少数类的关注。逻辑回归的正则化强度 C 在 0.1、0.3、0.7、1.5 中通过三折分层交叉验证选择最优值为 0.7。4.2 验证集模型比较模型ROC-AUCPR-AUC准确率精确率召回率F1随机森林0.80740.46760.85660.40860.61190.4900逻辑回归0.79780.45090.82560.34890.63340.4500随机梯度分类0.79760.44380.84830.38860.60650.47374.3 最终测试集指标指标结果解释Accuracy0.8362总体分类正确比例受多数类占比影响较大Precision0.3698预测为认购的客户中真实认购所占比例Recall0.6444实际认购客户中被模型找出的比例F10.4699精确率与召回率的调和平均F20.5611更强调召回率适合筛选潜在客户ROC-AUC0.8009整体排序能力PR-AUC0.4599少数类名单质量的核心指标分类阈值0.505依据验证集 F2 选择五、业务落地建议具体细节见原文创造不易谢谢各位多多点赞收藏

相关新闻