4. 监督学习算法快速原型

在MATLAB机器学习工程中,快速原型阶段的核心目标不是追求最高精度,而是用最短路径验证“数据是否可分、特征是否有效、模型是否值得继续投入”。分类学习器App(Classification Learner)与fitcensemble、fitcsvm等函数,分别对应交互式探索与脚本化复现两条路径,二者配合可以显著缩短从数据到可用模型的周期。

一、分类学习器App:交互式快速筛选

分类学习器App适合在特征工程尚未完全定型时使用。启动方式为在命令行输入classificationLearner,或在“App”选项卡中点击“Classification Learner”。导入数据时,App会自动识别表变量类型,并要求指定响应变量(标签)与预测变量(特征)。对于本节示例,假设有一个fisheriris数据集,包含150个样本、4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和3个类别(setosa、versicolor、virginica)。

在App中,选择“交叉验证”并设置折数(如5折),然后可同时勾选多种模型进行训练:决策树、K近邻、支持向量机、集成方法等。App会以列表形式给出每种模型的验证准确率,并允许点击任一模型查看其混淆矩阵。这一阶段的判断依据是:若多个模型准确率接近且均高于基线(如多数类占比),说明特征具有可分性;若所有模型都接近基线,则应回到特征工程而非继续调参。

分类学习器App的“快速”体现在:无需编写代码即可比较十余种算法,且混淆矩阵、ROC曲线、特征重要性等诊断图可一键生成。但App不适合自动化调参和批量实验,因此原型验证后应导出为函数或脚本。

二、脚本化训练:fitcsvm与fitcensemble

当需要复现、调参或嵌入工程流程时,应使用函数式接口。以二分类SVM为例,fitcsvm的基本调用形式为:

load fisheriris
X = meas(1:100,:);          % 取前两类,共100个样本
Y = species(1:100);
Mdl = fitcsvm(X, Y, ...
    'KernelFunction', 'rbf', ...
    'BoxConstraint', 1, ...
    'Standardize', true);
CVMdl = crossval(Mdl, 'KFold', 5);
loss = kfoldLoss(CVMdl);

其中KernelFunction选择核函数,BoxConstraint控制惩罚强度,Standardize对特征标准化。训练后可用predict获得预测标签,用confusionmat计算混淆矩阵。对于多分类问题,fitcsvm默认采用“一对多”策略,也可通过fitcecoc使用纠错输出码。

集成方法fitcensemble则通过组合多个弱学习器提升泛化能力。常用调用为:

Mdl = fitcensemble(X, Y, ...
    'Method', 'AdaBoostM2', ...
    'NumLearningCycles', 100, ...
    'Learners', 'tree');

其中Method可选'AdaBoostM2'、'Bag'、'RUSBoost'等,NumLearningCycles为学习器数量,Learners指定基学习器类型。集成模型通常比单模型更稳健,但训练时间更长,且可解释性下降。

三、准确率与混淆矩阵:从数字到判断

准确率(Accuracy)是最直观的指标,定义为正确预测样本数除以总样本数。但在类别不平衡时,准确率可能产生误导。例如,若90%样本属于A类,模型全部预测为A,准确率仍达90%,但B类完全漏判。因此必须结合混淆矩阵分析。

混淆矩阵的行表示真实类别,列表示预测类别。以三分类为例,矩阵对角线为正确分类数,非对角线为误分类数。由此可计算:

  • 召回率(Recall):某类真实样本中被正确预测的比例,反映“漏判”程度;
  • 精确率(Precision):某类预测结果中真实属于该类的比例,反映“误报”程度;
  • F1分数:精确率与召回率的调和平均,适合不平衡数据。

在MATLAB中,confusionchart可直接绘制带颜色映射的混淆矩阵,并显示每类的召回率与精确率。例如:

YPred = predict(Mdl, X);
figure;
cm = confusionchart(Y, YPred);
cm.Title = 'SVM分类混淆矩阵';
cm.RowSummary = 'row-normalized';
cm.ColumnSummary = 'column-normalized';

观察混淆矩阵时,应重点关注:对角线是否显著高于非对角线;是否存在某一类被系统性误判为另一类;误判是否集中在特征空间重叠区域。若某两类互相误判严重,说明现有特征不足以区分它们,需要引入新特征或非线性变换。

分类模型快速原型:双路径与评估闭环 数据准备 fisheriris / 自定义表 路径A:分类学习器App 交互式勾选多模型 5折交叉验证 · 一键对比 路径B:函数式训练 fitcsvm / fitcensemble 可复现 · 可调参 · 可嵌入 评估与判断 准确率 · 混淆矩阵 召回率 · 精确率 · F1 confusionchart 可视化 若准确率接近基线或误判集中 → 回到特征工程 关键判断: 对角线显著高于非对角线 → 模型有效 某类系统性误判 → 特征不足或类别重叠 推荐流程: App快速筛选 → 函数复现调参 → 混淆矩阵诊断 → 迭代特征

四、从原型到可复现:导出与封装

分类学习器App支持将训练好的模型导出到工作区,或生成等效的MATLAB函数。导出后,可用saveLearnerForCoder保存模型,用loadLearnerForCoder加载,便于部署。对于fitcensemble和fitcsvm,建议将训练脚本封装为函数,输入为特征矩阵和标签向量,输出为模型对象和评估指标,便于批量实验。

一个实用的原型脚本结构如下:

function [mdl, acc, cm] = trainAndEval(X, Y, method)
    % method: 'svm' 或 'ensemble'
    if strcmp(method, 'svm')
        mdl = fitcsvm(X, Y, 'KernelFunction', 'rbf', ...
            'Standardize', true, 'BoxConstraint', 1);
    else
        mdl = fitcensemble(X, Y, 'Method', 'AdaBoostM2', ...
            'NumLearningCycles', 100, 'Learners', 'tree');
    end
    cvmdl = crossval(mdl, 'KFold', 5);
    acc = 1 - kfoldLoss(cvmdl);
    YPred = predict(mdl, X);
    cm = confusionmat(Y, YPred);
end

该脚本返回交叉验证准确率与训练集混淆矩阵。注意:训练集混淆矩阵仅用于诊断模型是否过拟合,最终评估应以交叉验证或独立测试集为准。

常见误区:直接用训练集准确率作为最终指标。若训练集准确率远高于交叉验证准确率,说明模型过拟合,应减少模型复杂度、增加正则化或补充数据。混淆矩阵应同时观察行归一化和列归一化结果,前者反映召回率,后者反映精确率。

五、参数选择与快速调参建议

对于fitcsvm,关键参数包括BoxConstraint(越大越严格,易过拟合)、KernelScale(RBF核宽度,越小越平滑)和Standardize(建议开启)。可用fitcsvm的自动优化选项'OptimizeHyperparameters'进行贝叶斯优化,但原型阶段建议先手动尝试2~3组参数。

对于fitcensemble,NumLearningCycles通常设为50~200,LearnRate(AdaBoost)设为0.1~1,MaxNumSplits控制基树深度。若数据类别不平衡,优先使用'RUSBoost'方法,它通过欠采样平衡类别。

快速原型的判断标准可以归纳为:交叉验证准确率是否显著高于多数类基线;混淆矩阵对角线是否占主导;误判是否集中在可解释的类别对之间。若满足前两条,即可进入下一阶段;若不满足,应优先检查特征质量与类别可分性,而非盲目增加模型复杂度。