首页/新闻资讯/正文详情

MATLAB版SMOTE实战:解决不平衡数据分类的过采样方案

发布时间:2026/11/6 8:02:34 来源:云帆数科 栏目:资讯中心
MATLAB版SMOTE实战:解决不平衡数据分类的过采样方案
简介这份资源是面向机器学习初学者与数据挖掘工程师的SMOTE算法MATLAB实现包用于解决训练集中少数类样本过少导致模型偏向多数类、识别能力下降的不平衡数据问题。压缩包共5个文件约3KB以2个.m源码文件为核心分别承载SMOTE算法主体实现与调用测试示例另附LICENCE.txt授权说明及.gitignore、.gitattributes等版本管理配置体量轻便、便于直接嵌入现有工程。已有1324人学习下载说明其在中文社区具备一定参考价值。读者可从中获得可运行的合成少数类过采样代码结合K近邻搜索与线性插值思路理解新样本生成过程并借助测试脚本快速验证数据平衡前后的模型表现为SVM、决策树、随机森林等分类任务提供预处理参考同时可在此基础上调整K值与采样比例探索与Tomek链接等方法的组合使用。1. 少数类样本不够用我用一份 MATLAB 版 SMOTE 把不平衡数据跑通了手上有一批设备故障记录正常样本几千条故障样本只有几十条。直接丢进分类器训练模型把所有样本都判成“正常”准确率还挺好看但真正要抓的故障一个没抓到。这种类别不平衡的场景做工业检测、医疗辅助诊断、风控建模的开发者都绕不开。SMOTE 就是用来给少数类“造样本”的经典手段在少数类样本之间做随机线性插值合成新的少数类点让分类器不再一边倒。这份 MATLAB 版本的 SMOTE 实现适合两类人一类是刚接触不平衡数据、想在 MATLAB 里快速跑通流程的新手另一类是已有自己的分类脚本想把过采样环节嵌进去做二次开发的熟手。下面我按“它怎么组织、怎么跑、怎么改”的顺序把这份源码拆开讲。2. 项目结构与算法骨架SMOTE 在 MATLAB 里是怎么落地的2.1 目录与文件组织这份资源是一个围绕 SMOTE 算法组织的 MATLAB 工程核心不是一个大而全的框架而是“算法函数 演示脚本 数据”的轻量组合。常见做法是下面这种结构我按实际拆包时最可能见到的形态说明smote_matlab/ ├── SMOTE.m % 核心过采样函数 ├── main_demo.m % 演示脚本加载数据、调用SMOTE、训练分类器 ├── data/ │ └── imbalance_data.mat % 不平衡样本集特征 标签 ├── utils/ │ ├── knn_search.m % 近邻查找也可直接用内置knnsearch │ └── plot_result.m % 可视化原始/合成样本分布 └── README.mdSMOTE.m是算法主体main_demo.m是入口data/放样本utils/放辅助函数。这种拆法的好处是算法和演示解耦你想把 SMOTE 用到自己的项目里只需要拷SMOTE.m和它依赖的近邻函数不用把整个演示脚本拖进去。新手先跑main_demo.m看效果熟手直接读SMOTE.m改参数。2.2 SMOTE 的核心逻辑SMOTE 的思路不复杂但几个参数决定了合成样本的质量。核心流程是对每个少数类样本找它的 k 个最近邻同样是少数类随机选一个邻居在两点连线上随机取一个插值点。用公式说就是x_new x_i rand * (x_neighbor - x_i)rand是 0 到 1 之间的随机数。这样合成出来的点既靠近原始少数类分布又不会简单复制原样本。下面是我按这份工程风格重写的核心函数骨架参数和注释都标清楚方便你对照源码读function [X_new, y_new] SMOTE(X, y, k, N) % SMOTE 对少数类做过采样 % 输入: % X - 特征矩阵, 每行一个样本, 每列一个特征 % y - 标签向量 (列向量) % k - 近邻个数, 常用 5 % N - 过采样倍率, 合成样本数 少数类样本数 * N % 输出: % X_new - 合成后的特征矩阵 % y_new - 合成后的标签向量 minority_idx find(y min(y)); % 定位少数类 X_min X(minority_idx, :); n_min size(X_min, 1); X_syn zeros(n_min * N, size(X, 2)); % 预分配合成样本空间 cnt 0; for i 1:n_min % 在少数类内部找 k 近邻排除自身 dist pdist2(X_min(i,:), X_min, euclidean); [~, idx] sort(dist); neighbor_idx idx(2:k1); % 跳过第1个自己 for n 1:N nn neighbor_idx(randi(k)); % 随机选一个近邻 gap rand; % 插值系数 cnt cnt 1; X_syn(cnt,:) X_min(i,:) gap * (X_min(nn,:) - X_min(i,:)); end end X_new [X; X_syn]; y_new [y; repmat(min(y), n_min * N, 1)]; end逐段说下逻辑。minority_idx find(y min(y))用标签最小值定位少数类这是演示代码里最常见的简化写法前提是标签用 0/1 或 1/2 这种整数编码。pdist2算欧氏距离矩阵sort后取第 2 到 k1 个作为近邻跳过自己。内层循环里randi(k)随机挑邻居rand生成插值系数两个随机性叠加保证每次合成的点都不一样。最后把合成样本拼回原矩阵标签用repmat复制少数类标签。参数上k一般取 5太小合成点容易贴着原样本、多样性不足太大可能跨到类别边界外。N是倍率少数类几十条、多数类几千条时N取到让两类接近 1:1 或 1:2 就行别盲目拉平合成太多会引入噪声。这里有个血泪经验N设太大合成样本会把少数类的决策边界撑得很宽分类器反而在真实测试集上翻车。2.3 演示脚本怎么串起来main_demo.m的职责是把“加载数据 → 过采样 → 训练 → 评估”串成一条线。典型写法如下% main_demo.m load(data/imbalance_data.mat); % 载入 X 和 y fprintf(原始分布: 多数类 %d, 少数类 %d\n, ... sum(ymax(y)), sum(ymin(y))); [X_bal, y_bal] SMOTE(X, y, 5, 10); % k5, 倍率10 fprintf(过采样后: 多数类 %d, 少数类 %d\n, ... sum(y_balmax(y_bal)), sum(y_balmin(y_bal))); % 用简单的决策树做基线分类 mdl fitctree(X_bal, y_bal); pred predict(mdl, X); acc mean(pred y); fprintf(训练集准确率: %.2f%%\n, acc*100);这段脚本的价值在于给你一个可对照的基线。先看原始分布打印出来多悬殊再看过采样后的分布最后用fitctree快速验证。注意这里评估用的是原始X不是合成后的X_bal因为合成样本只该进训练集不能污染评估。这一点新手很容易搞错把合成样本也拿去算准确率数字虚高实际部署就露馅。3. 跑起来从零到看见合成样本分布3.1 环境准备与数据格式MATLAB 版本没有额外的工具箱硬依赖pdist2在 Statistics and Machine Learning Toolbox 里fitctree也在同一个工具箱。如果你装的是完整版 MATLAB基本开箱即用如果只装了基础版pdist2可能报未定义那就换成手写欧氏距离或者用knnsearch替代。数据格式上imbalance_data.mat里通常是两个变量X是n×d的数值矩阵y是n×1的标签列。加载前先确认维度对得上size(X,1)要等于length(y)否则后面索引会错位。跑之前建议先做一次数据检查把下面几行加在main_demo.m开头assert(size(X,1) length(y), X 和 y 样本数不一致); assert(all(isfinite(X(:))), X 中存在 NaN 或 Inf); fprintf(特征维度: %d, 样本总数: %d\n, size(X,2), size(X,1));assert这两行是我每次接新数据必加的NaN 和维度错位是最常见的翻车点早报错比跑到一半崩强。3.2 运行演示并观察结果在 MATLAB 里把当前目录切到工程根目录命令行输入main_demo回车。正常的话你会看到三行输出原始分布、过采样后分布、训练集准确率。如果plot_result.m存在还会弹出一张散点图前两个特征做坐标轴多数类一种颜色、少数类另一种、合成样本第三种。看这张图重点看两件事合成点是不是落在少数类簇的范围内有没有跑到多数类堆里。如果合成点大面积越界说明k太大或者特征没做归一化。特征量纲差异大时欧氏距离会被大数值特征主导近邻找得不准合成点自然偏。常见做法是先标准化再喂给 SMOTEX_norm normalize(X); % z-score 标准化 [X_bal, y_bal] SMOTE(X_norm, y, 5, 10);normalize默认按列做 z-score把每个特征拉到均值 0、方差 1。注意标准化参数要从训练集算测试集用同一套均值和方差变换别各算各的否则评估会有偏差。3.3 把 SMOTE 接进自己的分类流程演示脚本只是样板真正要用是把SMOTE.m嵌进你现有的训练脚本。关键原则只有一条过采样只作用于训练集验证集和测试集保持原始分布。常见做法是按比例先切分再对训练部分过采样cv cvpartition(y, HoldOut, 0.3); X_train X(training(cv), :); y_train y(training(cv)); X_test X(test(cv), :); y_test y(test(cv)); [X_train_bal, y_train_bal] SMOTE(X_train, y_train, 5, 10); mdl fitctree(X_train_bal, y_train_bal); pred predict(mdl, X_test); recall_minority sum(pred(y_testmin(y_test)) min(y_test)) / sum(y_testmin(y_test)); fprintf(少数类召回率: %.2f%%\n, recall_minority*100);这里用cvpartition做留出切分training和test取索引。评估指标换成少数类召回率比整体准确率更能反映不平衡场景下的真实效果。整体准确率在不平衡数据上参考价值有限这点我在多个项目里反复验证过。4. 避坑与排查SMOTE 用错比不用还糟4.1 合成样本污染评估集现象过采样后准确率飙到 99%换一批真实数据掉到 60%。原因把合成样本混进了测试集模型在“见过”的合成点上评估数字虚高。解决切分在前、过采样在后测试集永远保持原始分布评估只用原始样本。这条是最高频的坑没有之一。4.2 近邻跨类别边界现象合成点散落在多数类区域分类边界变模糊。原因k设得过大或者少数类本身分布分散近邻选到了远处的点。解决k从 5 起步观察散点图少数类内部如果明显分簇考虑按簇分别过采样或者改用带边界清理的变体。别指望一个k通吃所有数据。4.3 特征未归一化导致距离失真现象合成样本集中在某几个特征维度上分布明显偏斜。原因各特征量纲差异大欧氏距离被大数值特征主导。解决过采样前做 z-score 或 min-max 归一化且归一化参数只在训练集上拟合。这条和 4.2 经常一起出现排查时先看量纲再看k。4.4 倍率设太大引入噪声现象少数类召回率上去了但精确率暴跌误报一堆。原因N过大合成样本数量超过真实少数类太多噪声被放大。解决把倍率控制在让两类比例接近 1:1 到 1:2 之间配合交叉验证调。过采样不是越多越好合成样本终究是插值出来的不代表真实分布。4.5 标签编码假设不成立现象min(y)定位少数类时选错了类。原因标签不是 0/1 或 1/2 这种整数编码比如用了字符串或多分类标签。解决显式统计每类样本数用tabulate(y)或groupcounts找真正的少数类别默认min就是少数类。多分类场景下 SMOTE 要逐类处理不能一把梭。5. 二次开发把 SMOTE 改成你能用的样子拿到这份源码后最值得动的几个地方我按优先级排一下。第一是近邻查找pdist2在样本量大时是 O(n²) 的内存和计算开销几千条以上就明显卡。换成knnsearch配合 KD 树能快不少或者只对少数类内部建索引因为 SMOTE 只在少数类里找邻居。第二是插值策略原始 SMOTE 对每个少数类样本一视同仁但靠近边界的样本合成风险高可以给边界样本降权或者只对“安全”样本过采样这就是 Borderline-SMOTE 的思路。第三是倍率自适应按当前类别比例动态算N而不是写死。改造时我一般会加一个验证闭环改完参数立刻用交叉验证看少数类召回率和 F1 的变化别凭感觉调。下面这个片段是我常用的快速对比框架k_list [3, 5, 7]; N_list [5, 10, 15]; for k k_list for N N_list [Xb, yb] SMOTE(X_train, y_train, k, N); mdl fitctree(Xb, yb); pred predict(mdl, X_test); f1 2 * prec * rec / (prec rec); % prec/rec 需先算 fprintf(k%d N%d F1%.3f\n, k, N, f1); end end这个双层循环把k和N的组合扫一遍输出对应的 F1比单看准确率靠谱。参数网格不用太密先粗扫再细调。改完记得把最优参数写回main_demo.m的调用处别让演示脚本和实际流程脱节。还有一个容易被忽略的点合成样本的可解释性。工业场景里模型给出的判断往往要能追溯合成点不是真实记录解释时要说清楚哪些是原始样本、哪些是插值出来的。我一般会在输出里保留一个来源标记列方便回溯。从那以后我每次改过采样逻辑都强制先跑一遍“切分—过采样—评估”的完整闭环再提交绝不跳过测试集验证这一步。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

Vue2老项目调试利器:离线安装Vue Devtools 5.4.3实战指南
Vue2老项目调试利器:离线安装Vue Devtools 5.4.3实战指南

简介:这份资源是面向 Vue 2 项目开发者的 Chrome 调试扩展安装包,版本为 5.4.3,用于弥补 Chrome 原生开发者工具对 Vue 特有调试能力支持的不足。安装后可在浏览器工具栏调出 Vue 面板,直观查看组件树、组件状态与属性&#xff0c… · 2026/11/6 8:02:34

深入解析Docker容器虚拟化与Linux Namespace隔离机制
深入解析Docker容器虚拟化与Linux Namespace隔离机制

1. 容器虚拟化基础概念解析 第一次接触Docker时,我被它轻量快速的特性所震撼。相比传统虚拟机动辄几分钟的启动时间,容器能在毫秒级完成部署。这种革命性的差异源于Linux内核提供的Namespace隔离机制——它让每个容器都拥有独立的进程视图、网络栈和文件… · 2026/11/6 8:01:34

Snort 2.9.x 必装 DAQ 2.0.7 安装指南与排错手册
Snort 2.9.x 必装 DAQ 2.0.7 安装指南与排错手册

简介:DAQ-2.0.7是Snort入侵检测系统核心依赖的数据采集抽象层开源实现,面向网络安全工程师、IDS开发人员及底层网络协议研究者,解决Snort在多平台、多数据源(如libpcap、netmap、nfq、AF_PACKET等)下统一包捕获与接口适… · 2026/11/6 8:01:34

电工证拍照技巧图片保姆级教程:别怕考不过白交培训费
电工证拍照技巧图片保姆级教程:别怕考不过白交培训费

电工证拍照技巧图片保姆级教程:别怕考不过白交培训费 怕考不过白交培训费?别急,先看懂这些拍照技巧,再考再报名都不晚。今天咱们不聊机构,就讲干货—— 电工证拍照技巧图片… · 2026/11/6 20:56:34

电工证作弊视频全流程办理指南:学历不高怕报不上名?官方报名入口全解析
电工证作弊视频全流程办理指南:学历不高怕报不上名?官方报名入口全解析

电工证作弊视频全流程办理指南:学历不高怕报不上名?官方报名入口全解析 你是不是也担心学历不高,连电工证都报不了?别急,今天咱们就来聊聊这个【电工证作弊视频】的话题,顺便告诉你怎么在【官方报名入口】上顺利报考,别再被那些“捷径”忽悠了。… · 2026/11/6 20:56:34

电工证必背代码网上查询全攻略 专为学历不高怕报不上名的你
电工证必背代码网上查询全攻略 专为学历不高怕报不上名的你

电工证必背代码网上查询全攻略 专为学历不高怕报不上名的你 你是不是还在为电工证报考发愁?学历不高怕报不上名?别急,今天我就从 商丘房建工程从业者 角度,一步步告诉你怎么搞定 电工证必背代码 ,以及如何通过 网上查询… · 2026/11/6 20:56:34

高压电工证几个月考试良心建议,别再被中介忽悠了
高压电工证几个月考试良心建议,别再被中介忽悠了

高压电工证几个月考试良心建议,别再被中介忽悠了 你是不是也和我一样,听说了高压电工证几个月考试这个事,心里一万个问号?到底怎么报名?什么时候能考?怕被中介坑?别慌,今天我来跟你唠清楚,从报考到考试,一整套流程说给你听,绝对 良心建议… · 2026/11/6 20:56:34

在哈尔滨哪能考电工证证怎么转异地
在哈尔滨哪能考电工证证怎么转异地

哈尔滨考电工证怎么转异地?外省证书含金量还在吗? 之前考的证在外省能不能转过来?这是很多在外地打工、又想在哈尔滨长期发展的人最关心的问题。尤其是在哈尔滨这类北方工业城市,电工证的 含金量… · 2026/11/6 20:56:34

高压电工证几个月考试网上查询方法全解析
高压电工证几个月考试网上查询方法全解析

高压电工证几个月考试网上查询方法全解析 你现在正在为找工作发愁,手里缺的就是一个高压电工证,别人都有证,你还在等?高压电工证几个月考试,这个问题直接关系到你能不能顺利上岗,甚至影响你未来的薪资和晋升通道。别再等了,现在就来搞清楚高压电工证的… · 2026/11/6 20:55:33

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

三菱PLC数据采集到数据库的时序设计:Python+MC协议实战
三菱PLC数据采集到数据库的时序设计:Python+MC协议实战

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

ASIC主模式RTL设计:状态机与三态驱动的流片级实现
ASIC主模式RTL设计:状态机与三态驱动的流片级实现

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

STM32嵌入式C++开发:GDB调试与Renode仿真实战指南
STM32嵌入式C++开发:GDB调试与Renode仿真实战指南

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

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码