
简介《模式识别与智能计算——MATLAB技术实现》第3版电子书面向计算机、信息工程、生物医学工程、智能机器人及自动化等专业的学生、研究人员与工程技术人员帮助读者在掌握模式识别理论的同时获得可运行的MATLAB实现思路。全书14章从特征选择与优化、相似性测度讲起覆盖贝叶斯分类器、判别函数、BP/RBF/概率/自组织竞争等神经网络、决策树与粗糙集分类器并延伸到模糊聚类、禁忌搜索、遗传算法、蚁群与粒子群等群智能聚类方法以手写数字识别贯穿实例给出实现步骤、示范代码与效果图示便于对照复现和比较不同算法。资源包为1个PDF文件约17.87MB适合按章节系统阅读或作为课程教材、项目参考。目前已有313人学习可作为模式识别课程学习与算法选型的案头资料。1. 零基础也能上手的模式识别 MATLAB 入门先弄明白机器是怎么「认字」的刚接触模式识别 MATLAB 入门的人十个里有八个会先卡在同一个念头上数学基础不够是不是根本学不了。其实这份资料干的事特别朴素——教机器把看到的东西归到某个类别里比如看一眼手写数字就说出它是 0 还是 7。这件事你每天都在做只是从没意识到。换个说法模式识别就是把「人一眼能看出来的事」拆成能一步步算的流程再用 MATLAB 写成能跑的代码。这份资源里 14 章算法全都围着同一个例子转手写数字识别每个算法都配了理论、实现步骤和可以直接运行的程序。适合谁刚上手、要交课程作业、要做课题、想搞懂算法本身而不是只会调包的人。看完这篇你至少能把第一个例子跑起来。2. 入门先弄懂三个概念样本、特征、相似度很多新手一上来就翻到神经网络那一章结果看两页就放弃问题不在脑子笨在于前三个概念没落地。这一章只干一件事把「一张手写数字」翻译成 MATLAB 能处理的数字再把「像不像」翻译成一个能算出来的数。这两步通了后面 14 章你都会觉得是同一件事的不同做法。2.1 样本和特征向量一张手写数字怎么变成一串数先统一叫法。被观测的每一个对象叫样本比如你写在纸上的一百个数字就是一百个样本描述样本的每一个 measurable 的指标叫特征比如这个数字占了多少像素、笔画有多长、上下左右四块的黑点密度分别是多少一个样本的全部特征排成一列就是特征向量所有可能的特征向量张成的空间叫特征空间。举个能算的例子。假设你要区分数字 0 和 1别一上来就用 28×28784 个像素先粗化成 8×8 的网格数每个格子里黑点的比例得到 64 个特征。那么一个手写的「0」在 MATLAB 里就是% 一个样本8x8 的图像先展平成 1x64 的行向量再转成列向量 img double(imresize(imread(digit_0.png), [8 8])); % 读图并缩到 8x8 x img(:) / 255; % 展平成 64x1顺便把 0-255 的灰度压到 0-1 size(x)img(:)是 MATLAB 里最常用的展平手法把二维矩阵按列顺序拉成一维/255是把像素值归一化到 0 到 1 之间这一步不做后面算距离时像素值会压过其他特征。跑完你会看到64 1这就是一个 64 维的特征向量。一百个样本摞起来就是一个 100×64 的矩阵每一行是一个样本每一列是一个特征。这份资料的原书里用的是另一种写法——n 行 N 列每一列是一个样本。两种写法数学上完全等价但 MATLAB 的习惯是「行是样本、列是特征」因为几乎所有内置函数都这么吃数据。这是新手第一个容易翻车的地方照着书上的表格敲进 MATLAB维度反了报错信息还特别难懂。我第一次学的时候就在这里卡了半天后来养成的习惯是读入数据后立刻size(X)打印一次心里默念「行是样本」。还有一件事得提前说特征不是越多越好。784 维的像素直接丢进分类器样本量不够时效果往往比 64 维还差这叫维数灾难。资料第 2 章专门讲特征的选择与优化包括主成分分析降维、特征评估、样本筛选那一章值得在动手之前先翻一遍哪怕只看懂结论。2.2 相似性测度机器判断「像不像」的那把尺子机器不会「看」它只会算。判断一个手写数字是 0 还是 1本质是算它跟已知的 0 模板、1 模板分别差多少差得少的那个赢。这个「差多少」就是相似性测度是整个模式识别的基础。资料第 3 章把常用的几种都列了出来新手先认识四个就够用。测度怎么算适合什么数据新手要注意什么欧氏距离两个向量对应元素差的平方和开根号连续特征比如像素灰度、长度各维量纲差距大时必须先归一化否则数值大的特征会主导结果马氏距离欧氏距离再除以协方差矩阵特征之间有相关性、量纲不统一样本数必须大于特征维数否则协方差矩阵不可逆夹角余弦两个向量的点积除以模长乘积关心方向不关心长度文本、二值图像全零向量没法算要先处理Tanimoto 测度交集除以并集纯二值数据比如黑白像素、有无某个属性只认 0 和 1连续值必须先二值化拿欧氏距离举例两个 64 维向量 x 和 y 的距离在 MATLAB 里就一行% 两个 64 维特征向量之间的欧氏距离 d sqrt(sum((x - y).^2));.^2是逐元素平方sum把 64 个数加起来sqrt开根号。注意这里是x - y如果 x、y 维度不一致MATLAB 的新版本会做隐式扩展而不报错算出来的结果是错的——这种错最难查因为程序不崩只是结果离谱。为什么值得花时间理解测度因为后面所有算法都可以看成「换个方式算距离」。贝叶斯分类器算的是概率意义上的接近程度K 均值聚类算的是到簇中心的欧氏距离神经网络算的是加权之后的相似度。你把这一层看透了14 章里至少一半的内容会突然变得眼熟。2.3 第一个能跑的例子二十行代码走完一次完整分类理论先放一放先把流程跑通。零基础最怕的是「看懂了但不知道从哪下手」所以这个例子刻意做到零依赖、不需要任何工具箱、复制粘贴就能跑。数据集用 MATLAB 自带的鸢尾花数据150 个样本、4 个特征、3 个类别小到能一眼看明白又真实到能算出有意义的准确率。% 第一步载入自带数据。meas 是 150x4 的特征矩阵species 是 150x1 的类别标签 load fisheriris X meas; % 每行一个样本每列一个特征 y species; % 每个样本属于哪一类 % 第二步划分训练集和测试集隔一个取一个各占一半 idxTrain 1:2:150; idxTest 2:2:150; XTrain X(idxTrain,:); yTrain y(idxTrain); XTest X(idxTest,:); yTest y(idxTest); % 第三步最近邻分类。测试样本和每个训练样本算欧氏距离抄最近那个的标签 pred cell(size(yTest)); % 预分配用来存预测结果 for i 1:size(XTest,1) d sqrt(sum((XTrain - XTest(i,:)).^2, 2)); % 当前样本到所有训练样本的距离 [~, k] min(d); % 距离最小的那个的下标 pred{i} yTrain{k}; % 抄它的类别 end % 第四步算准确率确认流程真的跑通了 acc mean(strcmp(pred, yTest)); fprintf(最近邻分类准确率%.2f%%\n, acc*100);逐段解释一下。load fisheriris是 MATLAB 自带的数据不需要联网也不需要额外工具箱1:2:150是从 1 开始每隔 2 取一个得到 75 个训练样本剩下 75 个做测试这种分法简单但够用。第三步里的sqrt(sum((XTrain - XTest(i,:)).^2, 2))第二个参数2表示沿着第 2 维列方向求和所以结果是 75×1 的列向量每个元素是当前测试样本到一个训练样本的距离。[~, k] min(d)里那个波浪号表示「第一个返回值我不需要」只要最小值的下标。最后strcmp逐元素比较两个 cell 数组里的字符串返回逻辑数组mean一算就是准确率。跑完你大概会看到 94% 左右。这个数字不用太当真它的意义是证明流程走通了数据 → 划分 → 训练 → 预测 → 评估五步一个不少。参数想改的话看这张表想改什么改哪里影响训练测试比例idxTrain、idxTest的取值规则训练样本太少学不好测试样本太少评估不准换成别的数据替换X和y两行特征矩阵保持「行样本列特征」标签保持同样行数距离换成余弦把sqrt(sum(...))换成点积除以模长适合关心方向、不关心绝对大小的场景最近邻改成 K 近邻min换成排序后取前 K 个再投票K 大了更稳但类别边界会糊现在把它换成手写数字你只需要动两行X换成你算出来的特征矩阵比如 N×64y换成对应的数字标签。流程一模一样只是特征从 4 维变成 64 维类别从 3 类变成 10 类。等你把这一步走顺了就是真正在入门了而不只是看别人入门。提示第一次跑的时候在XTrain后面加一句size(XTrain)把维度打在屏幕上。养成这个习惯能省掉后面一半的报错。3. 分类器怎么挑从贝叶斯到神经网络的上手顺序流程跑通之后下一个问题自然冒出来最近邻这么简单为什么还要学那么多分类器答案是不同数据有不同的坑没有一个方法通吃。这一章按「新手最容易上手」的顺序来排先概率统计再神经网络最后才是可解释性优先的那几个。顺序反了会很痛苦。3.1 概率统计路线贝叶斯和判别函数到底在赌什么贝叶斯分类器的思路特别像人做判断。医生看病先看这个病在人群里有多常见先验概率再看病人的症状在这个病里出现的概率类条件概率两者一乘算出「得了这个病」的可能性后验概率谁大判谁。资料第 4 章讲的就是这套东西分最小错误率和最小风险两个版本前者只管「判对的概率最大」后者还会考虑「判错要付多大代价」——比如把有病判成没病代价远大于反过来这时就该用最小风险版本。判别函数则是另一个思路不绕概率直接找一条线或者一个曲面把特征空间切成几块落在哪块就是哪类。资料第 5 章列了一长串线性判别函数、感知器算法、增量校正、LMSE、Fisher 分类、基于核的 Fisher、势函数法、支持向量机。名字吓人其实核心动作只有一个——找一个让类间距离大、类内距离小的方向。Fisher 就是干这个的特别直观。为什么把这两个放在最前面学因为参数少、结果可解释、失败时能看出原因。贝叶斯只有先验和类条件概率要估Fisher 主要是求一个投影方向你调完之后画个图就知道为什么对了或者为什么错了。神经网络就不一样二十个隐层节点调成二十一个结果可能完全不同新手很难判断是自己错了还是模型就这样。真上手的时候建议你拿鸢尾花数据把贝叶斯跑一遍再换 Fisher 跑一遍对比两者的决策边界。资料里对每种方法都给了理论基础、实现步骤、编程代码三段式按这个顺序读不会乱。看得懂公式就推一遍看不懂就先跑代码看效果回头再补——这是我自己觉得最省时间的读法。3.2 神经网络路线六种网络分别适合什么场景资料第 6 章一口气讲了六种神经网络新手容易在这里迷路。先给一句总结它们都是在学一个从特征到类别的映射差别在于网络结构、学习规则和擅长的数据规模。网络一句话理解适合什么场景新手注意BP 神经网络最通用的多层前馈网络靠反向传播调权重中小规模分类入门首选隐层节点数、学习率要试训练不收敛很常见RBF 径向基网络用一堆「局部响应」的基函数拼出决策面小样本、要求训练快的场合中心点的选取影响很大自组织竞争网络神经元互相竞争谁响应强谁赢无监督聚类、特征拓扑输出要先想清楚怎么解读概率神经网络 PNN把贝叶斯决策塞进网络结构里分类任务训练极快样本一多网络就膨胀内存吃紧对向传播网络 CPN竞争层加输出层两段式模式联想、分类资料里篇幅不大先了解思路即可Hopfield 反馈网络有反馈回路能「回忆」出完整模式联想记忆、带噪声图像复原容易陷入局部极小稳定性要分析入门顺序我的建议是BP 先跑通因为资料里 BP 的篇幅最长、示例最全而且它的训练流程前向计算、算误差、反向调权重是理解其它网络的地基然后看 PNN因为它把上一节学的贝叶斯直接搬进网络结构学起来有承上启下的感觉RBF 放在第三理解「局部响应」这个概念剩下三个当扩展阅读先知道它们解决什么问题就够了不用一开始就死磕。3.3 跑通第一个神经网络分类器接着第 2 章的流程往下走这次把最近邻换成 BP 网络。需要 Deep Learning Toolbox如果你的 MATLAB 没有装先用上一章的代码把流程跑熟不影响理解。% 前提安装了 Deep Learning Toolbox load fisheriris X meas; % 神经网络工具箱的约定是每列一个样本所以这里转置 y zeros(3, 150); % 独热编码3 个类别各占一行 classes {setosa,versicolor,virginica}; for i 1:150 y(:,i) strcmp(classes, species{i}); % 属于哪一类哪一行就是 1其余是 0 end net patternnet(10); % 建一个隐含层含 10 个神经元的分类网络 net.trainParam.showWindow false; % 关掉训练弹窗命令行看结果就够了 net train(net, X, y); % 开始训练 out net(X); % 拿训练好的网络把全部数据回头预测一遍 [~, idxPred] max(out); % 输出值最大的那一行就是预测类别 [~, idxTrue] max(y); acc mean(idxPred idxTrue); fprintf(网络在全部数据上的准确率%.2f%%\n, acc*100);几个关键点。meas这个转置非常关键神经网络工具箱和统计工具箱的数据约定是反的一个要列是样本一个要行是样本转错方向不会报错但结果会很难看。patternnet(10)里的 10 是隐含层神经元个数可以改成 5、20、50 试改完重新跑看准确率怎么变这个过程比看十页理论更直观。独热编码那一段是把setosa这种字符串标签转成[1;0;0]的向量因为网络只会处理数字。max(out)取每列最大值的下标就是预测类别。这里必须提醒一句上面算的是「在全部数据上的准确率」网络在训练时已经见过这些样本了所以这个数字虚高不代表真实水平。资料里强调过训练与学习的区别你要真评估效果就得像第 2 章那样留出测试集。这个坑我后面第 5 章还会再讲一次因为它实在太常见了。3.4 决策树和粗糙集需要给结论找理由时先学这两个有些场景不光要分类结果还要说清楚「为什么这么判」。比如某类样本被判成故障你得告诉别人是哪几个指标触发的。这时候神经网络就不太合适了它像个黑匣子输出很准但你解释不清。决策树资料第 7 章的好处是天生可解释它把判断过程变成一串「如果某个特征大于某个值就往左走」的问句最后落到叶子上就是类别。你把这个树画出来任何人都能顺着走一遍看得明明白白。粗糙集第 8 章解决的是另一类问题数据里有冗余属性、有不精确的信息能不能在不损失分类能力的前提下把属性砍掉一些。它的核心是「属性约简」思路是不引入额外假设直接从上近似、下近似这些集合概念出发来判断哪些属性是必要的。这两个方法新手不用一上来就深挖但值得知道它们存在。等你做课题时被老师问「你这个模型凭什么这么判」你会庆幸自己翻过这两章。4. 聚类入门没有答案的时候让机器自己分组前面讲的都是有标签的情况你知道每个样本是几让机器学。但现实里更多时候你手里只有一堆数据没人告诉你该分几类。这时候就该聚类上场了资料从第 9 章一直讲到第 14 章占了全书三分之一还多值得认真对待。4.1 K 均值无监督学习最该先跑通的一个K 均值是整个聚类里最经典、最容易理解的算法思路四步随便挑 K 个点当簇中心把每个样本分给最近的中心重新算每簇的均值当新中心重复直到中心不再动。就这么简单。下面这个版本不依赖任何工具箱纯基础语法方便你逐行看懂每一步在干什么% 不依赖工具箱的 K 均值把数据粗分成 K 组 load fisheriris X meas(:,3:4); % 只取后两个特征方便在平面上看效果 K 3; % 想分成几类 rng(1); % 固定随机种子保证每次跑结果一样便于对比 centers X(randperm(size(X,1), K), :); % 随机挑 K 个样本当初始中心 for iter 1:20 d zeros(size(X,1), K); % 存每个样本到每个中心的距离 for k 1:K d(:,k) sqrt(sum((X - centers(k,:)).^2, 2)); end [~, assign] min(d, [], 2); % 每行取最小值得到归属的簇编号 newCenters centers; for k 1:K if any(assign k) % 防止某一簇空了导致 mean 出错 newCenters(k,:) mean(X(assignk, :), 1); end end if isequal(newCenters, centers) % 中心不再移动就提前收工 break end centers newCenters; end fprintf(迭代 %d 次后收敛各簇样本数%s\n, iter, mat2str(accumarray(assign,1)));参数说明K是你想分几类这个数得自己给K 均值不会告诉你该分几组rng(1)是固定随机种子不固定的话每次跑出来的初始中心都不一样结果也跟着变iter控制最多迭代多少轮实际大多十几轮就收敛assign是每个样本的簇编号后面画图、算指标都靠它。那个if any(assign k)判断容易被忽略但没有它某一簇变空时mean会返回 NaN整个结果就废了这是我自己踩过的坑。min(d, [], 2)里的[]是占位符表示「第二个参数跳过」2表示沿着列方向找最小值也就是对每个样本找最近的中心。这种写法在 MATLAB 里出现频率极高记住了能省很多查文档的时间。4.2 类别数说不清怎么办层次聚类和 ISODATA 的思路K 均值最大的软肋是 K 得你自己定。可很多时候你根本不知道数据该分几类这时候有两个思路可以试。第一个是层次聚类资料第 9 章。它不求一步到位而是先把每个样本当成独立的一簇然后不断把最近的两簇合并一直到只剩一簇整个过程画出来是一棵树。你在树上横着切一刀切出几枝就是几类。资料里列了最短距离法、最长距离法、中间距离法、重心法、类平均距离法五种合并规则差别在于「两簇之间的距离怎么定义」最短距离看最近的一对点最长距离看最远的一对点。新手先用类平均距离它比较稳不容易被个别离群点带偏。第二个是 ISODATA迭代自组织数据分析算法。它在 K 均值的基础上加了「分裂」和「合并」两个动作某一簇太散就拆成两簇两簇中心太近就并成一簇类别数在迭代过程中自己调整。这个算法参数多一些但对「我不知道该分几类」这种情况非常友好。再补一个思路基于试探的聚类比如最大最小距离算法先随便挑一个样本当第一簇中心找出离它最远的点当第二簇中心再找离这两个都足够远的点当第三簇中心一直加到没有点满足条件为止。整个过程不需要预设 K思路很符合直觉代码也短适合作为层次聚类和 K 均值之外的一个补充练习。4.3 遗传、蚁群、粒子群为什么聚类还要学这些算法翻到资料后半部分你会看到模拟退火、禁忌搜索、遗传算法、蚁群算法、粒子群算法全是聚类的变体名字一个比一个玄。新手的第一反应通常是K 均值几行代码就搞定了为什么还要搞这么复杂原因就一个K 均值是局部搜索。它从初始中心出发每次都往「当前看起来更好」的方向走走到走不动为止。问题是它可能停在一个并不理想的局部最优上——你换个初始中心结果就完全变了。这个现象我第一次遇到时以为是程序写错了反复检查才发现是算法本身的特性。这些「玄学」算法的共同点是引入了跳出局部的机制模拟退火允许以一定概率接受更差的解相当于给算法一个后悔药禁忌搜索记住最近走过的路短期内不回头遗传算法把解编码成染色体通过选择、交叉、变异一代代进化蚁群靠信息素正反馈逐步找到好的分组粒子群让一群「粒子」在解空间里飞互相参考彼此的历史最优位置。真上手的话建议按这个顺序先跑遗传算法聚类因为它的框架最清晰编码、适应度、选择、交叉、变异五个部件资料里也给了完整的构成要素讲解再跑粒子群代码短、参数少比较容易看到效果蚁群放在后面它的参数最多调起来最像玄学第一遍跑不出好结果很正常别灰心。模拟退火和禁忌搜索更多是作为一种「改进策略」出现在资料里比如用模拟退火改进 K 均值理解它们的思路比会默写代码更重要。5. 避坑指南新手最容易翻车的五个地方这一章可能是全篇最值钱的部分。下面五条全部来自实际跑代码时会遇到的情况按「现象 → 原因 → 解决」写遇到问题时对着排一遍能省下大量时间。5.1 五个高频坑一条一条对着排坑一准确率高得离谱换一批数据就崩。现象训练完一测准确率 99%兴冲冲拿去跑新样本结果惨不忍睹。原因八成是评估方式错了——你把训练用过的数据又拿来测试模型当然全对。这种情况在神经网络上尤其常见因为它的拟合能力太强。解决办法很简单一定要留出模型没见过的数据做测试第 2 章那种隔一个取一个的做法虽然粗糙但有效讲究一点就做三份训练、验证、测试。坑二训练半天损失不降或者所有样本都判成同一类。现象网络跑了几百轮误差曲线一条水平线或者预测结果清一色是某一类。原因最常见的是特征没归一化——比如某个特征是 0 到 1000 的像素值另一个是 0 到 1 的比例前者会把距离和权重完全主导。解决训练前用zscore做标准化注意标准化用的均值和标准差必须来自训练集再原样应用到测试集反过来做就是数据泄漏。坑三K 均值每次跑出来的结果都不一样。现象同一份数据连着跑三次分出来的簇完全不同。原因有两个初始中心是随机挑的而且算法本身容易停在局部最优。解决先用rng(1)固定种子保证结果可复现再试试多次随机重启取簇内距离之和最小的那次如果数据维度高先做主成分分析降到二维或三维再聚效果往往好很多。坑四把所有像素直接丢进去跑得又慢又不准。现象用 784 维的原始像素做特征训练时间长得离谱准确率还不高。原因是维数灾难——特征维度上去了样本就显得稀疏距离度量失去区分度同时计算量暴涨。解决先做特征提取再分类。资料第 2 章讲的主成分分析就是干这个的把 784 维压到几十维往往不掉点甚至还涨点。坑五整体准确率 90%但某一类几乎全错。现象看总体准确率挺好看细看发现有个类别基本没识别对。原因是类别不平衡——多数类样本多模型只要全判成多数类就能拿到不错的分数。解决别只看总体准确率去看混淆矩阵再补上每一类的召回率哪个类别拖后腿一眼就清楚。5.2 每次跑完实验先看这四样东西比「不犯错」更实际的是养成一套固定的检查习惯。我自己每次跑完分类实验会强制看四样整体准确率、混淆矩阵、每类召回率、以及换一组随机种子后结果稳不稳。前三个用一小段代码就能算出来% 在第 2 章最近邻例子的基础上自己算一个混淆矩阵不依赖工具箱 labels unique([yTest; pred]); % 所有出现过的类别 C zeros(numel(labels)); % 行是真实类别列是预测类别 for i 1:numel(yTest) r find(strcmp(labels, yTest{i})); % 真实类别对应的行号 c find(strcmp(labels, pred{i})); % 预测类别对应的列号 C(r,c) C(r,c) 1; % 对应格子加一 end disp(array2table(C, RowNames, labels, VariableNames, labels)) recall diag(C) ./ sum(C, 2); % 每一类的召回率对角线除以该行总数 disp(array2table(recall, RowNames, labels, VariableNames, {recall}))混淆矩阵的对角线是判对的非对角线是判错的。哪一类总是被误判成哪一类看非对角线哪一列数大就知道了。sum(C, 2)是沿行求和得到每一类的真实样本总数diag(C)取对角线两者相除就是召回率。array2table只是为了让输出好读不加也照样能跑。注意换随机种子重跑这件事看着多余但它是判断「模型真有效」还是「这次运气好」最便宜的办法。同一个模型跑三次结果差十几个点那说明它不稳定别急着写报告。6. 下一步学什么从跑通示例到做出自己的小项目跑通第一个例子之后最容易出现的状态是「会跑了但不知道下一步干什么」然后就在原地打转。给一条我验证过、对新手比较友好的路线按周来排四周下来你能有一个能拿得出手的小东西。周次重点具体做什么检验标准第 1 周打地基吃透样本、特征、相似度三个概念把第 2 章的最近邻例子换成自己造的两类数据重跑一遍能说清每一行代码在干什么能自己改距离公式第 2 周分类器入门跑通贝叶斯和 Fisher再跑通 BP 网络对比三者在同一份数据上的表现能画出决策边界能解释谁为什么更好第 3 周聚类入门K 均值、层次聚类各跑一遍再用遗传算法聚类跑一遍比较结果稳定性能解释 K 均值为什么会卡在局部最优第 4 周完整小项目选一个自己感兴趣的识别问题从特征提取做到评估写出完整流程有训练测试划分有混淆矩阵有失败分析具体到每天怎么分配我的建议是把「读」和「跑」的比例控制在三比七。资料里每种方法都给了理论基础、实现步骤、编程代码三段理论基础那部分第一遍别死磕看懂「它在解决什么问题」就够了剩下的时间全部用来改代码、换参数、看结果怎么变。等你对结果有直觉了再回头补理论效率会高得多。如果四周之后你还想继续深入有三个方向可以挑一是往特征工程走把第 2 章的主成分分析、特征评估吃透这是提升效果最实在的地方二是往集成走把多个分类器的结果合起来投票比死磕单个模型调参划算三是往可解释性走决策树和粗糙集那两章值得细读做课题时特别有用。最后说一句我自己的教训。刚学那会儿我总想一口气把所有算法都跑一遍结果每个都只跑了个皮毛遇到问题完全不知道从哪查。后来我改了个习惯每跑一个新数据集先强制走一遍「看维度、看分布、留测试集、看混淆矩阵」这四步哪怕数据再小也不跳过。这个习惯帮我挡掉了后面大量的返工。希望帮到你。本文还有配套的精品资源点击获取