☰
机器学习模型诊断与实战:偏差方差、SVM、聚类、PCA及异常检测
2026/10/19 9:44:16 网站建设 项目流程

如果你正在跟着吴恩达的机器学习公开课刷课,应该会有个很明显的感受:前半段教你线性回归、逻辑回归、神经网络,把梯度下降写出来,训练误差降下去,心里就踏实了。但从第11课往后,画风完全变了——课程开始反复追问一个问题:你的模型到底是真的学到了规律,还是只是在训练集上把答案背下来了?

按最常见的大纲划分,第11~15课这一段大致对应模型诊断、机器学习系统设计、支持向量机、无监督学习里的聚类与降维,以及异常检测。我把这几个主题放在一起写一篇总结,不是替你复述公式,而是想聊聊这些内容在实际项目里怎么落地、怎么避坑,哪些是课程里一笔带过但真实工程里至关重要的东西。

这篇内容适合正在跟课、刚学完前几周的读者,也适合那种“模型能跑、但效果总是不行,不知道下一步该往哪使劲”的人。如果你只想把课水过去,那我建议你至少把“学习曲线”和“误差分析”这两块吃透——它们是后面所有内容的地基,也是你把算法从“能用”做到“好用”的分水岭。

1. 模型诊断思路:先搞清楚偏差和方差,再决定下一步

1.1 偏差与方差:判断模型的“病根”

课程在讲完神经网络之后,专门拿出一大段时间讲诊断方法,核心就是偏差(bias)和方差(variance)。我当时学到这里最大的收获是:以后模型效果不好,我不再是靠猜去瞎调,而是先判断病根是“欠拟合”还是“过拟合”。

判断方式很直接。把数据分成训练集、验证集、测试集,然后同时看训练误差和验证误差。如果训练误差本身很高,验证误差也跟着高,两者差距不大,说明模型太简单,连训练集都没拟合好,这就是高偏差。打个比方,好比一个学生平时作业都不及格,期末考试当然也不及格,这不是粗心,是压根没学会。反过来,如果训练误差很低,验证误差却高出不少,说明模型把训练集里的细节和噪声都记下来了,但在新数据上泛化不行,这就是高方差。类比一下就是,学生把作业答案背得滚瓜烂熟,可考试题目稍一变式就不会了。

这里有个很容易被忽略的点:训练误差低不代表模型好,验证误差才是你调模型时的“成绩单”。我自己早期调模型时喜欢盯着训练集上的损失看,看到损失一直降就觉得万事大吉,结果模型一上真实数据就原形毕露。后来养成习惯,训练过程中始终保留一份验证集,每一步都看验证误差,整个调参路径就清晰多了。

1.2 学习曲线:加数据不是万灵丹

第11课附近最值得反复看的内容之一,就是学习曲线。横轴是训练集大小,纵轴是误差,把训练误差和验证误差两条曲线画在一个图上,信息量非常大。

高偏差的情况下,两条曲线会很快“贴在一起”,并且都维持在一个较高的水平。这说明你再往训练集里塞数据,模型能力就那样了,该不会的还是不会。高方差的情况下,两条曲线之间通常隔着一条明显的“沟”,训练误差很低、验证误差很高。这种情况下加数据是有效的,因为数据越多,模型就越难靠背答案混过去,验证误差会逐渐向训练误差靠拢。

我实际项目里很喜欢先用一小部分数据快速跑一个baseline,画出学习曲线,而不是一上来就上万条数据、几十个特征。举个例子,之前做一个分类任务,第一版特征工程做完之后效果不好,我第一反应是“特征不够,继续加特征”。后来冷静下来,先画了学习曲线,发现是典型的高方差,问题不在特征少,而是模型复杂度和数据量不匹配。把正则化调强、数据量提上去之后,效果立刻好了不少。如果不做这一步,我大概会在错误方向上浪费一周。

课程里还强调一个点:正则化参数λ相当于在偏差和方差之间找平衡。λ太小,正则化几乎不起作用,容易高方差;λ太大,模型被压得太狠,所有特征都被削弱,容易高偏差。换到实际场景里,我建议每次只动一个变量,要么调正则化强度,要么加数据,要么调特征,然后记录验证集效果的变化。同时动好几个因素的话,最后你根本分不清是哪个改动让效果变好的。

2. 机器学习系统设计:先学会把时间花在刀刃上

2.1 误差分析:把直觉变成一张清单

课程用垃圾邮件分类这个例子讲机器学习系统设计,我现在回头看,这段课的精华其实不是那个例子本身,而是里面反复强调的设计方法论:先做一个能跑的简单版本,再去看错误样本,最后根据错误类型决定优化优先级。

误差分析的具体操作,说起来特别朴素:从验证集里把被错分的样本捞出来,人工看一遍,然后给错误分类。比如垃圾邮件分类里,你会看到有些垃圾邮件是包含股票推荐的、有些是带恶意链接的、有些是伪装成正常邮件的。把这些类型列一个表,数一数每类各占多少,优化优先级自然就出来了——优先处理数量最多、最容易解决的那类,而不是靠感觉决定先修哪个。

这门课教给我最重要的一句话是:不要靠感觉猜哪里出了问题,要去看真实的错误样本。我后来做项目,几乎把这个方法当成了默认流程。模型效果不行,先打印出几十条预测错的样本,逐个看,很多问题一眼就能发现:标签错了、特征处理有bug、某些类别的数据量太不均匀。这些问题如果靠“换个更先进的模型”去解,根本解决不了。

2.2 不对称分类:别让准确率骗了你

第11~15课里另一个必须掌握的内容,是针对“正例很少”这种场景的评估方法。课程举了癌症筛查的例子:如果只有0.5%的人是阳性,你写一个“永远预测阴性”的分类器,准确率都能到99.5%。但这样的模型一点用都没有。

所以课程引入了查准率(precision)和查全率(recall)。查准率衡量的是“你预测为正例的那些样本里,有多少真是正例”;查全率衡量的是“所有真正的正例里,你找出来了多少”。这两个指标天然存在权衡:把判定阈值调高,只有足够自信才判成正例,查准率上去了,但查全率会下降;把阈值调低,正例被漏掉的可能性小了,但误报也会变多。

指标计算公式关注点
准确率(TP+TN)/(TP+TN+FP+FN)类别均衡时可用,正例极少时没有参考价值
查准率TP/(TP+FP)预测为正例的样本里,有多少是真正例
查全率TP/(TP+FN)真正的正例里,有多少被找出来了
F1分数2×查准率×查全率/(查准率+查全率)同时平衡查准率和查全率,适合作为单一优化指标

我实践中比较常用的做法,是在验证集上计算F1,然后选F1最高时对应的阈值,而不是固定用默认的0.5。课程里没细讲阈值扫描,但它和“用验证集选参数”的思路一脉相承:你的模型输出的是概率,真正决定分类结果的阈值完全可以按业务需求调。

3. 支持向量机:从逻辑回归的“近亲”到最大间隔

3.1 SVM的来路:从代价函数改造说起

吴恩达讲SVM的时候,故意没有直接从“最大间隔”的几何直觉切入,而是从逻辑回归的代价函数一路改造过来,这个讲法对我这种非数学背景的人特别友好。他先把逻辑回归里的代价函数换成一个分段线性的近似,再把正则化项从1/λ换成直接放一个C参数,本质上就是换了个缩放方式。C大,相当于λ小,正则化弱;C小,相当于λ大,正则化强。

SVM最后学到的决策边界,会尽量离两类样本都远,所以叫最大间隔分类器。这个性质带来一个很直观的好处:决策边界对靠近分界线的单个样本不那么敏感,泛化能力通常比逻辑回归更稳健。当然,代价是它对异常点相对敏感,所以C这个参数在SVM里尤其重要——C设得过大,模型会拼命把所有训练样本都分对,边界变得很窄,容易过拟合;C设得适中,边界更宽,但会容忍少量误分类。

实战里我一般把C当成“模型信任训练数据的程度”。如果验证集显示方差很大,就往小调C;如果偏差很明显,就往大调C。这跟调正则化强度是一样的思路。

3.2 核函数与两个关键参数

SVM真正厉害的扩展是核函数。课程重点讲了高斯核,也叫径向基函数(RBF),它的作用是把样本映射到更高维空间,从而在原始空间里解决非线性分类问题。高斯核需要设置σ这个参数,它控制单个样本点的“影响半径”。

关于C和σ,可以简单记成一张表:

参数偏大偏小
C低偏差高方差,容易对噪声敏感高偏差,决策边界过于简单
σ高偏差,核函数过于平滑,边界太直高方差,核函数过于尖锐,边界太曲折

还有一个细节特别容易踩坑:高斯核内部算的是欧氏距离,所以特征缩放极其重要。如果有一个特征是“收入”,量级是几万,另一个特征是“年龄”,量级是几十,距离计算基本会被收入主导,核函数的相似度就失去意义了。用SVM做高斯核之前,我一定是先做标准化或者归一化,这个操作不做,调参调半天都是白费。

3.3 工程里怎么用SVM:别自己造轮子

课程里提了一句“你应该用现成的SVM软件包,而不是自己写”,这句话放到今天依然成立。成熟库里的SVM实现经过大量优化,直接调用比自己折腾可靠得多。

工程选型上,我的经验是:特征维度很高(比如上万)但样本量不大,优先线性核或逻辑回归,因为这时候把特征映射到更高维往往没必要;样本量中等、特征维度适中,高斯核效果通常很好;样本量特别大(几十万以上),高斯核的训练速度会很痛苦,这时候线性核或者直接上神经网络更实际。多分类问题就做一对多(one-vs-rest),训练多个二分类器,取分数最高的那个作为预测结果。

现在深度学习确实很流行,很多新手容易忽视SVM,但在中小规模数据集上,SVM依然是那个又稳又能打的选手。它不需要特别大的数据量,解释性也还行,我在一些模型上线要求严格、样本量又不太宽裕的项目里,还是会首选SVM。

4. 无监督学习第一站:K-means聚类

4.1 算法流程与优化目标

K-means是课程进入无监督学习的第一个算法,理解起来相当直白。目标是把一堆没有标签的样本分成K簇,让每个样本离它所属簇的中心尽可能近。课程把它归纳成两个反复交替的步骤:先根据当前中心把所有样本分配到最近的簇,再根据每个簇里的样本重新计算中心。重复这两步,直到中心不再明显变化。

随机初始化K个聚类中心 μ1, μ2, ..., μK 重复以下两步: 1. 对每个样本 x_i,计算它到每个聚类中心的距离,分到最近的簇 2. 对每个簇,重新计算中心为该簇所有样本的均值 直到中心不再变化或达到最大迭代次数

课程点出了K-means的一个隐藏细节:它其实在优化一个代价函数,也就是所有样本到各自簇中心的距离平方和。每次更新中心,代价只会下降不会上升,但因为目标函数不是凸函数,算法很可能停在局部最优而不是全局最优。这就是为什么要做多次随机初始化,然后挑代价最小的结果。

我自己的理解是,K-means本质上就是一个贪心式的坐标下降。它简单、高效,但也正因为简单,对初始化、数据量纲、K的选择都非常敏感。这些敏感性解决好了,K-means在工程里依然非常好用。

4.2 初始化方式、K值选择与落地经验

课程讲随机初始化时,推荐的做法是随机选K个样本当初始中心,然后重复若干次,选代价最小的。这个方法在簇比较均衡的情况下没问题,但在某些场景下会退化。业界更常用的是K-means++:逐个选择初始中心,每次选的时候让离已有中心更远的点有更高概率被选中。它本身不复杂,却能把局部最优的概率大幅降低。

K值怎么选?课程提到“肘部法则”是看代价函数下降曲线,找到那个下降突然变缓的拐点。但课程也直言,肘部法则在真实数据里常常不明显。我的经验是:与其纠结肘部,不如结合业务。比如你聚类是为了用户分群,那就看分出来的每个群在业务上能不能解释、能不能采取不同策略;你是为了做图像颜色压缩,那就直接按需要的颜色数量定K。聚类效果的评估,很多时候要回到“聚类结果能不能解决问题”这个根本问题上。

实操层面还有几个教训。第一,特征标准化几乎必须做,否则量纲大的特征会完全主导距离。第二,可能出现空簇,也就是某轮更新后,某个簇一个样本都没有。常见处理办法是重新随机初始化这个簇的中心,或者直接删掉它并把K减一。第三,K-means对噪声和异常点敏感,如果数据里有少量脏数据,聚类中心会被拉偏,所以先简单清洗一下异常点再聚类,效果会稳定很多。

我学K-means最大的体会是:无监督学习没有“正确答案”,K-means给你的其实是一个数据结构的参考。它不该被当成打包好的黑盒,而该被当成一个探索数据的工具——跑完聚类之后,你一定要去看每个簇里的样本长什么样,而不是只看聚类评估分数。

5. PCA降维:不只是个画图工具

5.1 主成分分析的数学路径

课程讲降维时,主要讲的就是PCA。它的目标很纯粹:找到数据方差最大的方向,把高维数据投影到低维空间,同时尽量保留原始数据的信息。注意这里用的是“投影误差”,也就是样本点到低维空间的正交距离。

PCA的实现步骤课程讲得很清楚。先做特征标准化,然后计算协方差矩阵,再对协方差矩阵做奇异值分解(SVD)。SVD会得到三个结果:U、S、V。取U的前K列作为主成分方向,把原始数据 X乘以这个降维矩阵,就得到了低维表示 Z。整个流程里,标准化是很多人容易漏的一步。PCA找的是“最大方差方向”,如果不标准化,方差大的特征天然占据主导,这不一定是你想要的,所以先让每个特征都在同一量纲下再算协方差,结果才有意义。

课程还特意强调,PCA不是线性回归。线性回归是预测y,误差是“垂直方向”的误差;PCA是在没有y的情况下找数据本身的结构,误差是“正交投影”的误差。这两个问题看起来像,本质完全不一样。

5.2 主成分数量K怎么定

PCA需要决定降到几维。课程给了个很实用的标准:不是拍脑袋定K,而是看保留了百分之多少的方差。由于SVD会输出奇异值向量S,你只需要从第一个奇异值开始累加,直到累计占比达到99%(或者95%),对应的个数就是K。

这个做法比“我要降到3维因为我要可视化”要科学得多。可视化只是K=3或K=2的一种特殊情况,更多时候你需要的是“尽量少的维度、尽量多的信息”。我自己当初用过数据压缩类的PCA,目标是让训练速度变快又不想损失太多精度,用99%方差作为阈值,效果非常稳,模型精度几乎没有掉。

5.3 PCA不能解决过拟合

有一点课程讲得很直白,我觉得价值很大:不要用PCA来防止过拟合。很多人觉得,降维减少了特征数量,应该能缓解过拟合。这个想法看似合理,其实很危险。PCA在降维时根本没看过标签y,它丢掉的信息可能恰巧是和y高度相关的关键信息。想防过拟合,老老实实用正则化就好,正则化是冲着偏差方差去的,PCA是冲着数据压缩和加速去的,两码事。

还有几个工程细节要特别留意。第一,如果你在监督学习前用PCA,只能在训练集上拟合PCA映射,然后把同一个映射应用到验证集和测试集。如果在全部数据上先做PCA再划分训练验证集,那是典型的数据泄漏,得到的验证结果会虚高。第二,除非内存或训练速度遇到实际瓶颈,我不建议默认在每个项目里都套一层PCA,先用原始数据把baseline跑通,再判断要不要降维,是更稳的做法。第三,PCA非常适合高维数据的可视化,把维度压到2D或者3D,配合颜色标注,能很直观地看出来样本分布、类别重叠、离群点,这是我在探索数据阶段很喜欢的用法。

6. 异常检测:少数派问题的工程解法

6.1 从高斯分布到异常检测模型

异常检测的核心思想是:先用大量正常的样本学出一个“正常模式”的密度估计,然后对每个新样本计算它属于这个正常模式的概率。如果概率很低,就判定为异常。

课程先讲了单变量高斯分布的做法:对每个特征估计均值μ和方差σ²,然后假设每个特征独立,把各特征的概率乘起来,得到样本的总体概率p(x)。当p(x)小于阈值ε时,判定为异常。这个方法简单、可解释性强,是异常检测的经典入门思路。

课程还补充了一个进阶版本:多变量高斯分布。单变量高斯假设特征独立,但真实数据里特征往往有关联。比如一台服务器的CPU使用率和内存使用率可能是正相关的,单独看每个特征都在正常范围,但组合起来却可能是不正常的。多变量高斯直接对整组特征建模,能自动捕捉这种相关性。不过它的要求也高:协方差矩阵要可逆,通常需要样本数远大于特征数。我在实际项目里,如果特征数不多(比如几十维以内)而且相关性明显,会用多变量高斯;特征很多的情况下,还是单变量高斯加特征工程更方便。

6.2 异常检测和监督学习怎么选

课程专门列了一张对比表,核心判据是正例的数量。如果异常样本极少,少到模型根本学不到它的结构,就用异常检测。比如欺诈交易、设备故障、服务器异常,这些场景下你大概只有极少量的“出事”样本,但你有大量正常样本可以建模。反过来,如果正例和负例都很多,比如垃圾邮件、肿瘤分类,那就直接用监督学习,让模型学到“长什么样是垃圾邮件”“长什么样是恶性肿瘤”。

场景推荐方法原因
正例极少:欺诈检测、设备故障、服务器监控异常检测正常样本充足,异常样本太少,监督学习学不到模式
正例和负例数量都充足:垃圾邮件、肿瘤分类、广告点击监督学习可以从已知正例中充分学习并泛化

这里我的理解是,异常检测其实是在回答“这东西看起来像不像我见过的正常东西”的问题,所以它能发现“从来没见过的”新异常;而监督学习只能识别它见过的那些正例模式。做安全风控的同学应该深有体会,攻击手段一直在变,用监督学习识别已知攻击模式,再用异常检测盯住偏离正常行为的未知情况,是更完整的风控方案。

6.3 特征处理、阈值选择与工程细节

特征工程对异常检测的影响,比很多算法都大。课程强调,如果一个特征的分布不是高斯分布,可以先做变换,比如取log、开根号,把它变成近似高斯分布。这一步非常实用。我调异常检测的时候,经常遇到某个特征特别偏,导致模型把很多正常样本判成异常的情况。对特征做一些变换之后,误报率立刻降下来。

阈值ε的选择也不能靠感觉。课程建议的做法是:用标记好的验证集(其中包含一些已知异常样本)来选ε,比如让F1最高的那个ε作为最终阈值。这跟前面提过的“用验证集选超参数”完全一致。

我实际做异常检测时还遇到过一个细节问题:多个特征概率相乘,数值会越乘越小,很容易出现浮点下溢。解决方法是直接计算log p(x),然后和log ε比较,效果等价,数值稳定很多。另一个经验是,不要把异常检测的结果直接当成最终结论。我一般把它当作一个“召回候选”的工具——异常检测筛出可疑样本,再人工或者用另一个模型复核。这样既能发挥无监督方法覆盖面广的优势,又能靠人工规则控制误报,综合效果比单用任一方法都稳。

最后再分享一点个人体会。学完第11~15课,我最大的收获不是多会了几个模型,而是整个思路从“怎么把模型跑起来”变成了“怎么判断模型到底行不行”。现在我处理项目效果不好的问题,第一反应不是换个更花哨的模型,而是先画学习曲线、做误差分析、检查评估指标对不对。该用K-means做分层、该用PCA做可视化、该用异常检测抓脏数据,这些工具单独看都不复杂,但组合起来就是一套完整的解决实际问题的流程。如果这段课只允许留一句话给别人,我会说:它就是你从调包侠走向能独立解决实际问题的人的那个转折点。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询