MATLAB一维数据二分类实战:从阈值分析到分类器选择

发布时间:2026/10/16 4:15:16
MATLAB一维数据二分类实战:从阈值分析到分类器选择 在信号处理、传感器数据分析和工业检测里我们经常碰到这种场景手上攒了一批采样点每个点只有一个数值特征——可能是温度、电压、振动幅值或者光强现在要根据这个数值把样本分成两个类别。比如判断电机当前是正常还是异常区分钢管焊缝合格还是开裂。这类问题听起来简单真做起来却也有不少讲究阈值定在哪里最合理样本重叠区怎么处理分类器该选谁这篇博文就围绕“基于 MATLAB 的一维数据二分类”这个项目把从数据准备、可视化诊断、分类器选型到模型评估的完整流程拆开讲。内容适合正在做课程设计、毕业设计的学生也适合刚入门机器学习、想在 MATLAB 里快速跑通一个分类任务的开发者。我不光会贴出能直接跑的代码还会解释每一步为什么这么做、什么时候该换一种做法以及我实际踩过的坑。1. 项目整体设计与思路拆解1.1 一维二分类问题的本质是什么一维数据二分类指的是输入特征只有一个维度也就是每个样本用标量 x 来表示目标输出 y 是二值标签比如 0 和 1、正品和次品、正常和故障。很多资料喜欢拿二维平面上的点云分类做演示那是在二维特征空间里画一条直线或曲线分界。一维问题其实是它的退化版特征空间退化成一条数轴决策边界不再是曲线而是一个或多个阈值点。如果把一维数据点在数轴上画出来两组数据天然存在三种关系。第一类是完全可分左边全是 A 类、右边全是 B 类中间有明显空档。第二类是存在少量交叉大部分样本能分开但在交界处有几个“刺头”混在对方的阵营里。第三类是严重重叠两组数据的分布范围大面积重合单靠一个阈值永远无法完美分开。理解这三种情况很重要因为它决定了后面选什么分类器、该不该做特征工程以及最终模型的准确率上限在哪里。这个项目里还有个容易被忽视的点一维数据虽然“简单”但它同样能暴露出机器学习流程中的所有关键环节。维度低不代表问题 trivial数据的质量、标签的可靠性、验证集划分合理性这些因素对一维问题的影响和对高维问题一样致命。把一维问题吃透了再去做高维特征分类思路完全是相通的。1.2 为什么选 MATLAB 而不是 Python做一维二分类可选工具很多。Python 生态有 scikit-learnR 有 caretMATLAB 也有 Statistics and Machine Learning Toolbox。我在实践中更偏向用 MATLAB 做这类小规模分类任务原因有几个。MATLAB 的交互式环境对“边做边看”非常友好。一维数据本身没有什么隐藏结构可视化是最重要的诊断手段而 MATLAB 的绘图交互、数据光标标注和图形窗口管理非常顺手。写代码的时候工作区里每个变量一目了然新手不容易迷路。MATLAB 的机器学习接口高度统一。逻辑回归、SVM、决策树、KNN 这些分类器都通过 fit 开头的一系列函数实现调用的逻辑几乎一样传进去特征矩阵 X、标签 Y返回一个模型对象再统一用 predict 函数做预测。不需要像 Python 那样在不同库之间来回切换对于学习阶段来说这种一致性可以大幅降低认知负担。还有一点是文档和示例代码齐全。MATLAB 官方文档里每个分类器都有针对性的一维或多维示例遇到问题直接 help 一下就能找到参考。对不知道“该选哪个模型”的新手来说这种内置的引导体验是很重要的。当然Python 也有不可替代的优势比如深度学习框架支持、社区库丰富、部署灵活。但就这个项目而言——一维、二分类、数据量不大、重点是理解原理和流程——MATLAB 的学习曲线更平缓出结果更快。工具选择本身就是一种权衡没有绝对的优劣。1.3 技术路线总览整个项目我按下面这条线推进后面的章节也顺着这个顺序展开数据准备构造或加载一维特征向量和标签做必要的清洗和归一化。可视化诊断画出直方图、箱线图、散点分布用肉眼判断类别可分性。数据划分用交叉验证的思路划分训练集和测试集确保评估结果可信。分类器实现分别用逻辑回归、SVM、决策树、KNN 训练模型对比效果。模型评估用准确率、混淆矩阵、ROC 曲线等指标综合评判。常见问题排查梳理边界重叠、样本不平衡、过拟合、数据泄漏等坑。这条路线是分类任务的通用骨架一维问题只是在这个骨架上填充了更简单的几何直觉。每一步都有充分的理由后面我会在对应位置把“为什么”讲透。2. 核心细节解析与实操要点2.1 数据从哪里来构造与加载的常见做法这个项目的数据有两种常见来源。第一种是已有的真实数据比如某公司提供了一批传感器采样值对应着两种运行状态。这种情况下数据通常是 Excel、CSV 或 TXT 文件列结构是“特征值 标签”。读取方式很简单用 readtable 或 readmatrix 就能搞定。% 从 CSV 读取假设第一列是特征 x第二列是标签 y data readtable(sensor_data.csv); x data.Feature; y data.Label;第二种来源是自己构造仿真数据这也是我强烈建议初学者先做的。自构造数据的最大好处是“标准答案已知”你能清楚地知道两组数据的真实分布参数这样验证模型效果时心里有底。最常用的构造方法是高斯混合模型从两个不同均值、不同标准差的正态分布中分别采样再打上不同标签。rng(42); % 固定随机种子保证可复现 % 类别 0均值 0标准差 1 x0 randn(200, 1) * 1.0 0; % 类别 1均值 3标准差 1.2 x1 randn(200, 1) * 1.2 3; % 合并数据 X [x0; x1]; Y [zeros(200, 1); ones(200, 1)]; % 打乱顺序 idx randperm(length(Y)); X X(idx); Y Y(idx);把均值间距设为 3标准差设为 1 和 1.2两组数据会存在一定程度的交叉但绝大部分样本还是可分的。这个参数组合模拟的是“有噪声但工程上可处理”的真实场景而不是一个理想化的完美分离问题。想观察过拟合或更困难的情况可以缩小均值差到 1.5那会儿两组数据会大面积重叠分类器怎么调都吃力。2.2 可视化直方图、箱线图和散点图怎么用一维数据的可视化是我认为整个项目中最关键的一步它决定了你对“这个问题到底有多难”的感知。很多新手拿到数据就急着训练模型这是完全错误的路径。一维数据的分布通过图表一眼就能看明白没必要盲目跑模型。直方图是最直观的方式。横轴是特征值 x纵轴是频数用不同颜色画两组数据的直方图并叠加马上就能看出分类的大致规律。figure; histogram(X(Y0), FaceColor, [0.2 0.6 1], FaceAlpha, 0.6); hold on; histogram(X(Y1), FaceColor, [0.9 0.3 0.3], FaceAlpha, 0.6); xlabel(特征值 x); ylabel(频数); legend(类别 0, 类别 1); title(两类样本的特征分布直方图); grid on;运行这段代码你会看到两个山峰形状的分布蓝色峰在左、红色峰在右中间有一段“谷地”。这个谷地的宽度就是分类器发挥作用的余地谷地越宽分类越容易谷地越窄甚至出现负谷地蓝峰右尾压在红峰左尾上分类难度就上来了。箱线图适合看离群点和分布的四分位间距。它把每组数据的中位数、上下四分位数、最大最小值和离群点画成一种“带须的盒子”。如果两个箱体在纵向位置上错开明显说明特征有区分度如果箱体高度重叠说明这个特征本身对分类贡献有限。figure; boxplot(X, Y, Labels, {类别 0, 类别 1}); ylabel(特征值 x); title(两类样本的箱线图对比);散点图也值得画一下不过一维数据的散点图需要做点处理横轴放特征值纵轴可以放样本序号或一个随机的抖动值避免所有点叠在一条线上什么都看不清。figure; y_jitter Y (rand(size(Y)) - 0.5) * 0.2; scatter(X(Y0), y_jitter(Y0), 20, filled, MarkerFaceColor, [0.2 0.6 1]); hold on; scatter(X(Y1), y_jitter(Y1), 20, filled, MarkerFaceColor, [0.9 0.3 0.3]); xlabel(特征值 x); ylabel(标签抖动); legend(类别 0, 类别 1); title(两类样本散点分布); grid on;我个人的经验是可视化花的时间和训练模型的时间一样多都值得。一维数据的分布形态直接决定了后续模型的性能上限。如果直方图显示两组数据几乎完全重叠那么再高级的分类器也不可能做到 90% 以上的准确率这个认知能帮你避免在错误的方向上死磕。2.3 训练集与测试集划分必须认真对待的一步划分训练集和测试集是机器学习的基本功但在简单的项目里容易被敷衍过去。有些同学图省事直接拿全部数据训练再用同一批数据评估得到的准确率高得惊人但完全没有意义——那是“考试开卷还看答案”的假成绩。正确的做法是把数据切成互不重叠的两份训练只用训练集测试只用测试集。在 MATLAB 里cvpartition 是划分数据集的推荐方式。cv cvpartition(length(Y), HoldOut, 0.3); idxTrain training(cv); idxTest test(cv); XTrain X(idxTrain); YTrain Y(idxTrain); XTest X(idxTest); YTest Y(idxTest);HoldOut 的含义是保留 30% 的数据作为测试集剩下 70% 用于训练。这个比例不是死规定数据量大的时候可以留 20%数据量小的时候建议留 40%核心原则是测试集要足够大大到能反映模型在未见数据上的真实表现。还有一个隐蔽但非常重要的问题数据打乱顺序。如果原始数据在文件里就是按类别排好序的——前 200 行是类别 0后 200 行是类别 1——而你直接用前 70% 训练、后 30% 测试那么训练集里可能只有类别 0测试集里只有类别 1模型直接崩溃。解决方案就是在划分之前做一次随机打乱。前面构造数据时我已经用 randperm 打乱了一次但读真实 CSV 文件时尤其需要检查这一点。cvpartition 的 HoldOut 选项默认不做打乱它按顺序抽取所以一般建议先打乱数据再划分或者用 cvpartition 自带的 Stratify 选项来按类别比例分层抽样。% 分层抽样保证训练集和测试集中各类别比例与原数据一致 cv cvpartition(Y, HoldOut, 0.3, Stratify, true);这个细节对不平衡数据尤其重要。如果原始数据中类别 1 只占 5%普通随机划分有可能把测试集里的类别 1 全部划走导致测试结果完全失真。分层抽样可以在很大程度上缓解这个问题。3. 实操过程与核心环节实现3.1 逐步实现一个完整的二分类流程现在我们把前面几个环节串起来实现一个完整的 MATLAB 脚本。假设我们手头有一份名为 process_data.csv 的文件里面包含特征列 feature 和标签列 label标签取值为 0 和 1。第一步读取并检查数据。data readtable(process_data.csv); X data.feature; Y data.label; % 检查是否有缺失值 fprintf(缺失值数量%d\n, sum(ismissing(X))); fprintf(类别分布\n); disp(categorical(Y));缺失值在真实数据中非常常见一维特征只要有一个缺失这个样本的模型预测就没法进行。最简单的处理方式是删除缺失样本如果缺失占比很高就需要考虑填充策略比如用均值填充或用 KNN 插补。不过对这个项目来说删除是最稳妥的方案。第二步绘制分布图观察可分性。这一步就是前面 2.2 小节里那些直方图代码不再重复。这里要补充一个关键经验直方图的 bin 数量会影响视觉判断。bin 太多会看到大量毛刺bin 太少会掩盖分布细节。MATLAB 默认的 bin 数量通常是 10~20 之间对于 400 个样本的一维数据我习惯手动指定 bin 数为 20~30。figure; histogram(X(Y0), 25, FaceColor, [0.2 0.6 1], FaceAlpha, 0.6); hold on; histogram(X(Y1), 25, FaceColor, [0.9 0.3 0.3], FaceAlpha, 0.6);第三步划分数据。cv cvpartition(Y, HoldOut, 0.3, Stratify, true); XTrain X(training(cv)); YTrain Y(training(cv)); XTest X(test(cv)); YTest Y(test(cv));第四步训练逻辑回归分类器。逻辑回归是二分类任务的首选入门模型。它输出的是一个概率值表示样本属于类别 1 的可能性决策规则就是概率是否超过 0.5。在 MATLAB 中训练逻辑回归用 fitclinear 函数但注意它是针对高维稀疏数据优化的对于一维数据更常用的是 fitglm因为它直接支持广义线性模型。% 使用 fitglm 拟合逻辑回归 mdl_lr fitglm(XTrain, YTrain, Distribution, binomial, Link, logit); % 预测测试集概率 prob_lr predict(mdl_lr, XTest); % 根据概率得到类别标签 pred_lr double(prob_lr 0.5);这里有个细节predict 返回的是概率值不是标签。必须自己设定阈值 0.5。这个阈值默认是 0.5但在类别不平衡的时候可能需要调整。后面我会专门讲。第五步训练 SVM。SVM 在一维空间上的表现很有意思。因为特征只有一维SVM 的核函数选择其实被“压缩”了。线性核就是把空间内的点映射到一条数轴上找最大间隔阈值点高斯核RBF 核在这里几乎退化成一种局部密度比较。不过 SVM 依然值得尝试因为它的间隔最大化思想在噪声环境下比逻辑回归更稳健。mdl_svm fitcsvm(XTrain, YTrain, KernelFunction, linear, Standardize, true); pred_svm predict(mdl_svm, XTest);Standardize 参数值得注意。它会对特征做标准化处理让均值为 0、方差为 1。一维数据虽然只有一个特征但如果这个特征本身数值范围很大比如电压在几百伏量级标准化就能让 SVM 的优化过程更稳定。第六步训练决策树。决策树在一维场景下非常直观它只会做一件事就是寻找最佳切分阈值使得切分后两个子节点的纯度最高。MATLAB 中使用 fitctree。mdl_tree fitctree(XTrain, YTrain, MaxNumSplits, 4); pred_tree predict(mdl_tree, XTest);MaxNumSplits 控制树的深度。默认情况下决策树可能长得很深把训练数据完完整整地背下来这就是过拟合的典型表现。一维数据上树深度超过 4 基本就是在记样本了。限制分裂次数是防止过拟合最直接的手段。第七步训练 KNN。KNN 的思路更朴素对于一个新样本看看它在训练集里最近的 K 个邻居都是什么标签按多数投票决定自己的类别。一维数据上“距离”就是数轴上两个数的绝对差。mdl_knn fitcknn(XTrain, YTrain, NumNeighbors, 5); pred_knn predict(mdl_knn, XTest);K 值的选取很关键。K 太小模型对单个样本的噪声敏感K 太大模型会被远处的多数类“绑架”。对于 280 个训练样本K 取 3 到 10 都算合理区间具体可以用交叉验证来选。我通常习惯先试 K5再观察错误分布微调。3.2 分类器性能对比与可视化训练完四个模型后我们需要一个统一的标准来评估谁的效果好。最基础的是准确率预测正确的样本数除以总样本数。accuracy_lr sum(pred_lr YTest) / length(YTest); accuracy_svm sum(pred_svm YTest) / length(YTest); accuracy_tree sum(pred_tree YTest) / length(YTest); accuracy_knn sum(pred_knn YTest) / length(YTest); fprintf(逻辑回归准确率%.2f%%\n, accuracy_lr * 100); fprintf(SVM 准确率%.2f%%\n, accuracy_svm * 100); fprintf(决策树准确率%.2f%%\n, accuracy_tree * 100); fprintf(KNN 准确率%.2f%%\n, accuracy_knn * 100);准确率只是最粗的指标。当两类样本数量不均衡时准确率会产生很大的误导。比如 95% 的样本是类别 0那么一个“永远预测类别 0”的垃圾模型也能拥有 95% 的准确率。所以必须看混淆矩阵。figure; confusionchart(YTest, pred_lr); title(逻辑回归混淆矩阵);confusionchart 会画出一个 2x2 的热力图矩阵四个格子分别代表真负例TN、假正例FP、假负例FN和真正例TP。理想情况是反对角线元素TN 和 TP占绝对优势对角线以外的 FP 和 FN 越小越好。混淆矩阵还能告诉我们另一件事模型的错误是偏向哪一侧。如果 FP 多说明模型容易把类别 0 错判为类别 1如果 FN 多说明模型容易漏掉真正的类别 1。这在工程上往往有完全不同的代价比如在故障检测里漏掉一次故障FN的代价可能远大于一次误报FP。所以选用分类器不能只看准确率还要结合实际的错误代价。ROC 曲线是另一个重要工具。它刻画的是不同概率阈值下真正例率TPR和假正例率FPR的关系。曲线下的面积 AUC 越大模型区分两类的能力越强。MATLAB 中用 perfcurve 函数可以方便地绘制 ROC 曲线。% 以逻辑回归概率为例绘制 ROC [Xroc, Yroc, ~, AUC] perfcurve(YTest, prob_lr, 1); figure; plot(Xroc, Yroc, LineWidth, 2); xlabel(假正例率 FPR); ylabel(真正例率 TPR); title([逻辑回归 ROC 曲线AUC , num2str(AUC)]); grid on;AUC 达到 0.9 以上说明区分能力强0.8~0.9 是优秀0.7~0.8 是一般。一维可分性较好的数据AUC 通常在 0.9 以上如果 AUC 低于 0.75就该回头检查是数据本身重叠太严重还是预处理环节出了问题。3.3 阈值调整与不平衡数据处理如果我们发现模型在类别 1 上的召回率偏低而类别 1 又是我们更关心的对象可以在逻辑回归输出的概率上做文章。默认阈值是 0.5把它降低到 0.3意味着只要样本有 30% 的概率属于类别 1 就判定为类别 1。这样会提高召回率但代价是误报增多。阈值的选择本质上是在“宁可不漏”和“宁可不错”之间寻找平衡。% 调整阈值提高类别 1 的召回率 threshold 0.3; pred_lr_adjusted double(prob_lr threshold); recall_original sum(pred_lr 1 YTest 1) / sum(YTest 1); recall_adjusted sum(pred_lr_adjusted 1 YTest 1) / sum(YTest 1); fprintf(原始阈值召回率%.2f%%\n, recall_original * 100); fprintf(调整阈值召回率%.2f%%\n, recall_adjusted * 100);数据不平衡的另一个常见处理思路是调整样本权重或重采样。在 MATLAB 里fitcsvm 和 fitctree 都支持 Prior 或 Weights 参数。给少数类样本更高的权重模型会更“重视”它们代价是整体准确率可能略降但对少数类的识别能力会显著增强。% 给类别 1 分配更高权重 w ones(length(YTrain), 1); w(YTrain 1) 2; % 类别1权重加倍 mdl_svm_w fitcsvm(XTrain, YTrain, KernelFunction, linear, ... Standardize, true, Weights, w);我的经验是权重调整要克制从 1.5 倍开始试不要一上来就调到 10 倍否则模型会从“忽略少数类”跳到“把大量多数类误判为少数类”两个极端都不好。4. 常见问题与排查技巧实录4.1 两类数据严重重叠时怎么办这是做一维分类最常遇到的难题。直方图一画出来两个峰基本重叠中间没有明显的谷。此时无论用哪种分类器准确率天花板都差不多。我们能做的有几件事。第一能不能加特征。如果手头有原始信号数据而不是只有一张最终特征表可以提取额外特征比如均值、峰值、方差、过零率、频域能量等把一维特征扩展成多维特征。这是治本的办法从根本上改变问题的复杂度。第二可不可以换一个时间尺度上的特征。传感器数据里单点值可能重叠严重但相邻两个点的差值或短时间窗口内的趋势往往包含更多区分信息。比如两根温度曲线的瞬时值可能接近但变化速率明显不同。差值和斜率就是这个项目里值得试的一维特征。第三接受现实调整预期。如果特征本身信息量不足再好的分类器也分不开。此时可以诚实地报告模型的 AUC 和混淆矩阵而不是反复调参追求不切实际的准确率。工程上我们经常要面对“能做到什么程度”的问题把结论交代清楚本身就很有价值。4.2 模型在训练集上表现好但测试集上拉胯这是典型的过拟合。在一维数据的场景下过拟合常出现在两个场合。决策树深度过深是第一个树可以拆到每个叶节点只有一个样本训练准确率 100% 没问题但测试集完全失去泛化能力。解决办法是限制 MaxNumSplits或者用交叉验证自动选出合适深度。第二个是 KNN 中 K 值取太小。K1 时模型把每个训练样本都当成了自己的“私密邻居”测试样本只要和某一个训练样本接近就会继承它的标签噪声被完整保留下来。增大 K 值或者用交叉验证选最优 K。% 用交叉验证自动选择 K 值范围 for k 1:2:15 mdl_tmp fitcknn(XTrain, YTrain, NumNeighbors, k); cvmodel crossval(mdl_tmp, KFold, 5); loss kfoldLoss(cvmodel); fprintf(K%d 交叉验证损失%.4f\n, k, loss); end还有一种隐蔽的过拟合来源模型选择过程本身。如果我们在测试集上反复试不同模型看谁准确率高就选谁那测试集的信息就“泄漏”进了模型选择过程最终选出来的模型其实是对测试集过拟合。正确做法是用交叉验证来选择模型和参数测试集只在最后评估一次。4.3 预测结果为什么总偏向多数类这是类别不平衡的直接表现。当类别 1 只占 5% 时逻辑回归的默认决策边界会整体偏向类别 1导致几乎所有的预测结果都是类别 0。处理思路有三个层面数据层面做重采样或合成少数类样本算法层面给少数类加权重决策层面降低阈值或调整代价矩阵。这三个层面可以组合使用但要注意不要同时用力过猛否则会从“全都预测 0”翻转到“全都预测 1”。我个人在工程实践中的体会是先用混淆矩阵和召回率精确率定位问题在哪一侧再决定用哪种手段。大多数情况下简单调整阈值就能满足需求重采样和加权是杀手锏留在最后用。4.4 随机种子与结果可复现性MATLAB 的随机数生成器如果不固定每次运行脚本都可能产生不同的数据划分和不同的模型表现。同一个模型跑两次准确率相差几个百分点会让人对自己的代码产生怀疑。解决办法是在脚本开头固定随机种子。rng(2024); % 固定随机数生成器固定种子之后rand、randn、randperm 等函数生成的随机序列就完全确定了整个流程从数据采样、打乱顺序到交叉验证都能复现。做实验和写报告的时候这个习惯能在你排查问题时省下大量时间——如果每次结果都不一样你根本分不清一个修改到底是改善了模型还是纯粹由随机波动引起的。4.5 代码调试中的三个实操技巧第一定期打印中间变量的尺寸。用 size() 检查 X 和 Y 的行数是否一致。特征向量和标签长度不匹配是最常见的低级错误一旦 mismatchfit 函数就会报错而且错误信息往往不够直观。第二用 isscalar 或 isnumeric 确认特征类型。从 CSV 读入的数据可能是字符串格式直接参与运算会报错或产生隐式转换。用 class() 和 whos 检查变量类型发现不对就及时处理。第三理解 predict 和 fit 的输入格式。MATLAB 的 fit 系列函数统一要求特征矩阵是 n×m其中 n 是样本数m 是特征维度。一维数据要写成 XTrain 是列向量而不是行向量否则模型会认为只有一个样本、280 个特征训练结果完全错误。5. 从一维到多维的扩展思路一维二分类虽然简单但它的方法论可以平移到更复杂的问题上。我建议做完这个项目之后可以尝试沿着以下两个方向做扩展练习。第一个方向是特征扩展。把原来的一维特征扩展成二维或三维特征比如同时记录传感器读数的均值、峰值和方差。你会发现分类边界从“点”变成了“线”再到“面”SVM 的核函数选择开始有发挥余地决策树的形状也从“阈值列表”变成“多维切分树”。这个过程能帮你直观理解维度对人类视觉和模型能力的影响。第二个方向是引入时间结构。如果数据是按时间顺序采集的可以构造滑动窗口特征。比如用过去 10 个采样点的平均值、斜率、标准差作为新特征。这类特征在语音识别、心电信号分类、机械故障诊断中非常常见。理解了窗口特征的意义就理解了时序分类的本质。还有一个值得动手的实验把各类分类器的决策边界画出来。在二维特征空间里决策边界是一条曲线比较逻辑回归的线性边界和 SVM 的 RBF 边界在视觉上的差异比读任何教科书都更直观。反过来再看一维问题你会发现一维空间里所有分类器的边界本质上都落在少数几个阈值点上这恰恰说明了一维问题的“信息容量”是有限的。6. 完整可运行的参考代码最后给出一个整合了全部环节的完整 MATLAB 脚本。你可以直接复制保存为 classify_1d.m换掉数据文件名和相应列名就能用到自己的数据上。%% 基于 MATLAB 的一维数据二分类完整流程 clear; clc; close all; rng(2024); %% 1. 加载数据 data readtable(process_data.csv); % 替换为自己的数据文件 X data.feature; Y data.label; %% 2. 查看基本信息和缺失值 fprintf(样本总数%d\n, length(Y)); fprintf(类别0数量%d类别1数量%d\n, sum(Y0), sum(Y1)); fprintf(缺失值数量%d\n, sum(ismissing(X))); % 剔除缺失样本 validIdx ~ismissing(X) ~ismissing(Y); X X(validIdx); Y Y(validIdx); %% 3. 可视化 figure; histogram(X(Y0), 25, FaceColor, [0.2 0.6 1], FaceAlpha, 0.6); hold on; histogram(X(Y1), 25, FaceColor, [0.9 0.3 0.3], FaceAlpha, 0.6); xlabel(特征值 x); ylabel(频数); legend(类别0, 类别1); title(两类样本的分布直方图); grid on; figure; boxplot(X, Y, Labels, {类别0, 类别1}); ylabel(特征值 x); title(两类样本的箱线图对比); %% 4. 划分训练集和测试集分层抽样 cv cvpartition(Y, HoldOut, 0.3, Stratify, true); XTrain X(training(cv)); YTrain Y(training(cv)); XTest X(test(cv)); YTest Y(test(cv)); fprintf(训练集样本数%d\n, length(YTrain)); fprintf(测试集样本数%d\n, length(YTest)); %% 5. 训练逻辑回归 mdl_lr fitglm(XTrain, YTrain, Distribution, binomial, Link, logit); prob_lr predict(mdl_lr, XTest); pred_lr double(prob_lr 0.5); %% 6. 训练SVM mdl_svm fitcsvm(XTrain, YTrain, KernelFunction, linear, Standardize, true); pred_svm predict(mdl_svm, XTest); %% 7. 训练决策树 mdl_tree fitctree(XTrain, YTrain, MaxNumSplits, 4); pred_tree predict(mdl_tree, XTest); %% 8. 训练KNN mdl_knn fitcknn(XTrain, YTrain, NumNeighbors, 5); pred_knn predict(mdl_knn, XTest); %% 9. 评估 accuracy (p) sum(p YTest) / length(YTest); fprintf(\n 测试集准确率 \n); fprintf(逻辑回归%.2f%%\n, accuracy(pred_lr) * 100); fprintf(SVM%.2f%%\n, accuracy(pred_svm) * 100); fprintf(决策树%.2f%%\n, accuracy(pred_tree) * 100); fprintf(KNN%.2f%%\n, accuracy(pred_knn) * 100); %% 10. 混淆矩阵 figure; confusionchart(YTest, pred_lr); title(逻辑回归混淆矩阵); %% 11. ROC曲线 [Xroc, Yroc, ~, AUC] perfcurve(YTest, prob_lr, 1); figure; plot(Xroc, Yroc, LineWidth, 2); xlabel(假正例率 FPR); ylabel(真正例率 TPR); title([逻辑回归 ROC 曲线AUC , num2str(AUC)]); grid on;这个脚本可以直接跑通整个流程。但记住它只是一个起点。真实项目中你会遇到数据噪声更大、样本更少、类别更不平衡的情况处理起来需要灵活应变。多做几个不同的数据模拟调整参数观察结果变化你对分类模型的理解会远比“跑通一个脚本”要深得多。我在做这个项目时最有感触的一点是一维数据把机器学习里几乎所有核心概念都压缩在一个极简的几何图景里反而比那些花哨的高维案例更容易让人看清本质。明白分类边界本质上就是在数轴上选位置你就能明白所有复杂模型不过是在高维空间里做同样的事。把基础想透了后面无论做多复杂的项目都不会发怵。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询