分类建模实战:交叉验证调参、下采样与 SMOTE 过采样解决样本失衡问题
前言在做分类任务时我们经常会遇到两个头疼的问题一是模型参数怎么调才靠谱二是数据集类别极度不平衡怎么办。今天就通过贷款资格检测这个经典数据集把交叉验证调参、下采样和过采样三种方法从头到尾走一遍。在银行信贷风控场景中最典型的问题就是样本不平衡绝大多数申请人会正常还款真正违约的用户只占极小比例。直接用原始数据训练模型往往整体准确率能到 99%但对违约样本的识别能力几乎为零完全达不到风控预警的要求。本文基于某银行脱敏后的贷款申请数据集从基础的交叉验证调参讲起再到下采样、SMOTE 过采样两种不平衡处理方案一步步落地实现。所有代码均附带详细注释可直接复现运行。一、交叉验证调参我们平时把数据切成训练集和测试集用训练集训模型、测试集看效果这种方法有个问题单次划分的结果偶然性很大换个随机种子可能准确率就变了。交叉验证的思路很简单把训练集分成 K 份轮流用 K-1 份训练、剩下 1 份验证重复 K 次后取平均得分。这样得到的模型性能评估更稳定调参也更可信。1.2 完整代码与逐段讲解① 导入工具包与混淆矩阵绘图函数import pandas as pd import numpy as np from sklearn.metrics import confusion_matrix import matplotlib.pyplot as plt # 混淆矩阵可视化函数 def cm_plot(y, yp): cm confusion_matrix(y, yp) plt.matshow(cm, cmapplt.cm.Blues) plt.colorbar() for x in range(len(cm)): for y in range(len(cm)): plt.annotate(cm[x, y], xy(y, x), horizontalalignmentcenter, verticalalignmentcenter) plt.ylabel(True label) plt.xlabel(Predicted label) return plt这里封装了一个混淆矩阵绘图函数后面三个 demo 都会用到作用是把预测结果直观地展示成热力图每个格子里标上具体样本数。② 数据读取与预处理# 读取数据 data pd.read_csv(creditcard.csv) # 对 Amount 字段做标准化 from sklearn.preprocessing import StandardScaler scaler StandardScaler() data[Amount] scaler.fit_transform(data[[Amount]]) # 删除 Time 列对分类无帮助 data data.drop([Time], axis1) # 划分特征与标签 x data.drop([Class], axis1) y data[Class] # 划分训练集和测试集 7:3 from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test train_test_split( x, y, test_size0.3, random_state0 )知识点StandardScaler把数据缩放到均值为 0、方差为 1逻辑回归对特征尺度敏感必须做标准化。Time列是交易发生的时间戳对欺诈检测没有直接意义直接删掉。random_state0固定随机种子保证每次运行划分结果一致方便复现。③ 交叉验证调参核心部分from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score scores [] c_param_range [0.01, 0.1, 1, 10, 100] for i in c_param_range: lr LogisticRegression(Ci, solverlbfgs, max_iter1000) # 8折交叉验证评估指标为准确率 score cross_val_score(lr, x_train, y_train, cv8, scoringaccuracy) score_mean sum(score) / len(score) scores.append(score_mean) print(score_mean) # 选出最优的 C 值 best_c c_param_range[np.argmax(scores)] print(f最优惩罚因子为{best_c})关键知识点C 参数逻辑回归中的正则化系数。C 越小正则化越强模型越简单越不容易过拟合C 越大正则化越弱模型越复杂。cv8表示 8 折交叉验证把训练集切成 8 份跑 8 次取平均。scoringaccuracy用准确率作为评估指标。最后用np.argmax(scores)找到得分最高对应的 C 值④ 模型训练与结果评估# 用最优参数训练最终模型 lr LogisticRegression(Cbest_c, max_iter1000) lr.fit(x_train, y_train) from sklearn import metrics # 训练集表现 train_predicted lr.predict(x_train) print(metrics.classification_report(y_train, train_predicted)) cm_plot(y_train, train_predicted).show() # 测试集表现 test_predicted lr.predict(x_test) print(metrics.classification_report(y_test, test_predicted, digits6)) cm_plot(y_test, test_predicted).show()classification_report会输出精确率、召回率、F1 值等指标。跑完你会发现整体准确率特别高99%但少数类老赖的召回率其实很低 —— 这就是类别不平衡带来的问题也是后面两个 demo 要解决的。二、下采样处理类别不平衡2.1 什么是下采样银行贷款数据集中正常贷款占 99% 以上老赖贷款只有不到 1%模型哪怕全预测为正常也能有 99% 的准确率但毫无实际意义。下采样Undersampling的做法是从数量多的类别里随机抽取一部分让正负样本数量相等。简单粗暴但缺点是会丢失大量多数类信息。2.2 核心代码① 下采样实现# 先把标签拼回训练集方便采样 x_train[Class] y_train data_train x_train # 分离正负样本 positive_eg data_train[data_train[Class] 0] # 正常交易 negative_eg data_train[data_train[Class] 1] # 欺诈交易 # 从多数类中随机抽取与少数类数量相同的样本 positive_eg positive_eg.sample(len(negative_eg)) # 拼接得到平衡数据集 data_c pd.concat([positive_eg, negative_eg]) x data_c.drop([Class], axis1) y data_c[Class]核心就是sample(len(negative_eg))这一行从正常交易里随机抽出和欺诈交易一样多的样本实现 1:1 平衡。② 交叉验证调参 训练评估from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score scores [] c_param_range [0.01, 0.1, 1, 10, 100] for i in c_param_range: lr LogisticRegression(Ci, solverlbfgs, max_iter2000) score cross_val_score(lr, x, y, cv8) score_mean sum(score) / len(score) scores.append(score_mean) print(score_mean) best_c c_param_range[np.argmax(scores)] print(f最优惩罚因子为{best_c}) # 训练最终模型 lr LogisticRegression(Cbest_c, solverlbfgs, max_iter2000) lr.fit(x, y)注意交叉验证是在下采样后的平衡数据集上做的但最终评估一定要在原始测试集上跑这样才能反映真实场景的效果。from sklearn import metrics # 在原始训练集上评估 train_predicted lr.predict(x_train.drop([Class], axis1)) print(metrics.classification_report(y_train, train_predicted)) cm_plot(y_train, train_predicted).show() # 在原始测试集上评估 test_predicted lr.predict(x_test) print(metrics.classification_report(y_test, test_predicted)) cm_plot(y_test, test_predicted).show()下采样后你会发现整体准确率下降了但老赖贷款的召回率明显提升了 —— 这才是我们真正关心的指标毕竟漏掉一笔老赖贷款的代价远大于误判一笔正常交易。三、SMOTE 过采样demo03 核心讲解3.1 什么是过采样下采样是减少多数类过采样Oversampling则是增加少数类。最简单的过采样是直接复制少数类样本但容易过拟合。SMOTESynthetic Minority Oversampling Technique是更智能的做法在少数类样本之间插值人工合成新的少数类样本既平衡了数据集又不容易过拟合。3.2 核心代码① SMOTE 过采样实现from imblearn.over_sampling import SMOTE oversample SMOTE(random_state0) os_x_train, os_y_train oversample.fit_resample(x_train, y_train)就这三行代码imblearn库直接帮你完成 SMOTE 算法输出的os_x_train和os_y_train就是平衡后的训练集正负样本 1:1。使用前需要先安装pip install imbalanced-learn② 交叉验证调参 训练评估from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score scores [] c_param_range [0.01, 0.1, 1, 10, 100] for i in c_param_range: lr LogisticRegression(Ci, solverlbfgs, max_iter1000) score cross_val_score(lr, os_x_train, os_y_train, cv5) score_mean sum(score) / len(score) scores.append(score_mean) print(score_mean) best_c c_param_range[np.argmax(scores)] print(f最优惩罚因子为{best_c}) lr LogisticRegression(Cbest_c, solverlbfgs, max_iter1000) lr.fit(os_x_train, os_y_train)同样评估要在原始测试集上进行from sklearn import metrics train_predicted lr.predict(x_train) print(metrics.classification_report(y_train, train_predicted)) cm_plot(y_train, train_predicted).show() test_predicted lr.predict(x_test) print(metrics.classification_report(y_test, test_predicted)) cm_plot(y_test, test_predicted).show()对比下采样和过采样的结果SMOTE 通常在保留数据信息上更有优势实际工业界用得也更多。四、小案例寝室分配数据把同样的流程套用到寝室分配数据集上整体流程和前面完全一致读取数据 → 标准化 → 划分训练测试集 → SMOTE 过采样 → 交叉验证调参 → 评估。唯一区别是数据格式不同用np.loadtxt读取 txt 文件核心逻辑和前面一模一样。五、方法对比与总结最后把三种方法的核心要点整理一下⚠️ 提一下采样操作只能在训练集上做测试集必须保持原始分布不动否则评估结果没有参考价值。

相关新闻

05:MITM 的五脏六腑——中间人的里里外外

05:MITM 的五脏六腑——中间人的里里外外

大家好,我是毛衣哥。前四期铺垫了那么多,这一期终于到实战环节了。我们把中间人拆开,看看它肚子里到底塞了什么——堵路、分身、造假、偷看、传话,五步走完,你也能当个"白帽中间人"。前四篇我们把 HTTPS 的加…

2026/9/20 18:14:33 阅读更多 →
3步快速上手GraphvizOnline:在线图表编辑完整指南

3步快速上手GraphvizOnline:在线图表编辑完整指南

3步快速上手GraphvizOnline:在线图表编辑完整指南 【免费下载链接】GraphvizOnline Lets Graphviz it online 项目地址: https://gitcode.com/gh_mirrors/gr/GraphvizOnline 你是否曾为绘制复杂的流程图、组织结构图或网络拓扑图而烦恼?GraphvizO…

2026/10/10 2:48:31 阅读更多 →
51单片机矩阵键盘线反转法:高效IO扩展与按键识别实战

51单片机矩阵键盘线反转法:高效IO扩展与按键识别实战

1. 项目概述:从独立按键到矩阵键盘的必然选择在嵌入式开发,尤其是基于51单片机的项目中,人机交互是绕不开的一环。早期做项目,需要几个按键,就直接用几个IO口接上拉电阻和按键,这就是独立按键。但当你的需求…

2026/10/10 3:31:18 阅读更多 →

最新新闻

多智能体协作流式输出归因(Member-Attributed Streaming):让 leader 的 chunk 流携带每个团队成员的身份与角色

多智能体协作流式输出归因(Member-Attributed Streaming):让 leader 的 chunk 流携带每个团队成员的身份与角色

人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习 【免费下载链接】agent-core openJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力 项目地址: https://gitcode.com/openJiuwen/agent-core 点击查看 免费下载 导读 在 ope…

2026/10/12 3:44:14 阅读更多 →
Megatron-LM BERT 大规模预训练实战:340M/4B/20B 配置全解析与源码级实现原理

Megatron-LM BERT 大规模预训练实战:340M/4B/20B 配置全解析与源码级实现原理

人工智能大模型强化学习AI Agent微调 【免费下载链接】OpenClaw-RL OpenClaw-RL: Train any agent simply by talking 项目地址: https://gitcode.com/gh_mirrors/op/OpenClaw-RL 点击查看 免费下载 导读 本文围绕 Megatron-LM 仓库中 examples/bert 目录提供的 B…

2026/10/12 3:44:14 阅读更多 →
OWASP Top 10 仓库多版本重组:2021 与 2025 分离为独立 MkDocs 站点并保持 URL 向后兼容

OWASP Top 10 仓库多版本重组:2021 与 2025 分离为独立 MkDocs 站点并保持 URL 向后兼容

应用安全 【免费下载链接】Top10 Official OWASP Top 10 Document Repository 项目地址: https://gitcode.com/gh_mirrors/top/Top10 点击查看 免费下载 本文基于 OWASP Top 10 官方文档仓库(Top10)中的 REORGANIZATION-2025.md 展开&#x…

2026/10/12 3:44:14 阅读更多 →
SpringBoot+Vue+MySQL医疗报销系统毕业设计:全栈实现与部署详解

SpringBoot+Vue+MySQL医疗报销系统毕业设计:全栈实现与部署详解

毕业设计选医疗报销系统这个方向的人不少,但真正能把源码、数据库、论文、部署文档一整套整理干净的,其实不多。我之前帮人带过几个类似项目,也见过不少同学最后卡在“代码能跑但讲不清”或者“功能做完了但论文不知道写什么”的状态。这套Sp…

2026/10/12 3:44:14 阅读更多 →
三步估算显存需求:你的显卡到底能跑多大的大模型?

三步估算显存需求:你的显卡到底能跑多大的大模型?

前天有个朋友在群里说,他用8G显存的显卡,把一个十几亿参数规模的模型给跑起来了。我第一反应不是“厉害”,而是“能跑,但能跑多远”。果然他又补了一句:上下文一超过一千字就不行,再长一点直接报错退出。这…

2026/10/12 3:44:13 阅读更多 →
具身智能创新原理(40):基于TVA的潜在动力学鲁棒化与语义表征对齐策略

具身智能创新原理(40):基于TVA的潜在动力学鲁棒化与语义表征对齐策略

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习(DRL)、卷积…

2026/10/12 3:43:13 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →