☰
机器学习知识地图:用一条主线串起算法、诊断与复习清单
2026/10/27 3:37:24 网站建设 项目流程

简介:斯坦福大学吴恩达机器学习课程配套资料包,面向希望系统入门并夯实机器学习基础的学习者与数据科学从业者。内容围绕监督学习、无监督学习及模型评估展开,覆盖线性回归、逻辑回归、神经网络与反向传播、支持向量机、决策树与随机森林、聚类、降维、正则化、交叉验证和集成方法等核心知识点,适合课程同步学习、概念复习与作业实践参考。压缩包共130个文件,约17.21MB,以PDF讲义与文档、JPG/GIF示意图、TXT说明、ZIP子包及HTML/CSS网页素材为主,类型分布较完整,便于按章节和主题检索。已有399人学习,可作为理解算法原理、梳理课程脉络和补充实践材料的辅助资料,帮助读者在理论推导与案例应用之间建立联系,逐步形成较完整的机器学习知识框架。

1. 机器学习知识地图:一条主线串起十几种算法

机器学习这门课最容易学成“算法名词表”,考完就忘。真正该先记住的是这样一条主线:假设函数 → 代价函数 → 优化求解 → 评估诊断 → 回到特征和模型。所有算法不过是这条主线上不同位置的不同选择:线性回归和逻辑回归换的是假设函数和代价函数,正则化改的是代价项,偏差方差分析判断的是这条主线有没有走偏。

这份整理面向两类人:正在系统学机器学习、需要一张能随时对照检查的图的人;已经学过一遍、复习时想快速定位漏洞的人。下面按监督学习主线、分类与复杂度控制、无监督与诊断流程、易错点、复习清单五段展开,每个模块都落到能自测的具体问题上。

2. 监督学习主线:假设函数、代价函数与梯度下降

监督学习部分的骨架只有三件事:用什么样的函数去逼近目标、用什么样的标准衡量逼近得好不好、用什么方法把标准压到最低。三个环节任意一环理解偏了,后面调参就全靠猜。

2.1 假设函数与代价函数:模型究竟在拟合什么

线性回归的假设函数写成 h_θ(x) = θ₀ + θ₁x₁ + … + θₙxₙ,习惯上补一个 x₀ = 1,把它写成向量内积 θᵀx。这个写法不只是为了好看,而是把“截距”和“权重”统一成同一类参数,后面推导梯度、写矩阵运算都会省一半力气。特征工程在机器学习里的分量,从这个式子上就能看出来:模型能表达的东西,完全被 x 里有什么决定。

代价函数 J(θ) = (1/2m) Σ (h_θ(x⁽ⁱ⁾) − y⁽ⁱ⁾)² 里的 1/2 是纯粹的手工便利——求导时平方下来的 2 正好和它抵消,最优解的位置一点没变。除以 m 则是让代价的量级跟样本数脱钩,否则换个数据集,学习率又得重调。理解这两点的意义在于:看到别人写的代价函数形式略有不同时,先看常数因子,别急着怀疑推导错了。

平方损失并非随便选的。它对应“目标值 = 真实函数值 + 独立同分布的高斯噪声”这一假设下的极大似然估计,也就是说,当目标变量里存在少数极端离群点时,平方损失会被放大得非常厉害,这也是后面选择损失函数时要考虑的第一件事。

2.2 梯度下降:更新式、学习率与收敛判断

批量梯度下降的更新式是 θⱼ := θⱼ − α·(1/m)·Σ(h_θ(x⁽ⁱ⁾) − y⁽ⁱ⁾)·xⱼ⁽ⁱ⁾。所有参数必须同步更新:先算完整个梯度向量,再一次性减掉,不能算一个改一个,否则后面的样本用到的就是已经变过的参数,梯度方向会偏。

import numpy as np def gradient_descent(X, y, alpha=0.01, iters=1500): # X: 形状 (m, n+1),第 0 列已补 1;y: 形状 (m,) m, n = X.shape theta = np.zeros(n) history = [] for _ in range(iters): h = X @ theta # 前向计算:一次矩阵乘法代替 m 次循环 err = h - y # 残差向量,长度 m grad = (X.T @ err) / m # 批量梯度:所有样本一起贡献 theta = theta - alpha * grad # 同步更新,整向量一次性替换 history.append((err ** 2).sum() / (2 * m)) # 记录 J,用于画收敛曲线 return theta, history

这段代码里有三个值得反复看的点。X @ theta把 m 次点积压成一次矩阵乘法,是向量化的核心;X.T @ err一次算出全部 n+1 个偏导,省掉外层循环;history记录的是代价而不是参数,因为判断收敛要看 J 的曲线,不是看 θ 的变化量。

学习率的判断全靠这条曲线:J 随迭代次数单调下降并逐渐走平,说明 α 合适;J 出现上升或来回震荡,说明 α 太大,模型直接跳过谷底;J 下降得又慢又平滑,迭代几百次还看不到平台,说明 α 太小。实践中用三倍序列去试(0.001、0.003、0.01、0.03、0.1),比在连续区间里乱搜效率高得多。迭代次数不用预先定死,看曲线走平就停。

提示:如果 J 在前几十次迭代里下降得极快然后完全不动,先别怀疑 α,检查是不是特征尺度差了几个数量级。

2.3 特征缩放与向量化:让梯度下降真正跑得动

特征缩放做的事情很朴素:把每个特征减去均值、再除以它的范围或标准差,让所有特征大致落在 [−1, 1] 附近。允许的范围比较宽松,[−3, 3] 一般也能接受,但如果有特征落在 [−100, 100] 而另一个在 [−0.001, 0.001],代价函数的等高线会被拉成极扁的椭圆,梯度下降在长轴方向上反复振荡,收敛慢得让人怀疑代码写错了。

缩放的对象只包括特征,不包括标签;如果后面要预测,训练时算出的均值和标准差必须存下来,对测试数据用同一组参数变换,这是最容易在工程上翻车的一处细节——用测试集自己的统计量去归一化,等于把测试集信息泄露进了流程。

向量化的收益在规模上才明显。m 取几千、n 取几十时,Python 循环和 NumPy 矩阵乘法的差距通常在两三个数量级。也正因为向量化后的代码短到看不出错误,梯度检验才变得必要:用 (J(θ+ε) − J(θ−ε)) / (2ε) 这种中心差分去逼近数值梯度,和解析梯度对比相对误差,小于 1e-7 基本可以放心。检验代码只用来调试,跑通就删掉,绝不能留在训练循环里。

2.4 正规方程与梯度下降:两种解法的取舍

线性回归还能直接用正规方程一次性解出 θ = (XᵀX)⁻¹Xᵀy,不用选学习率、不用迭代、也不用特征缩放,看起来很划算。代价是矩阵求逆的复杂度约为 O(n³),特征数到上万时开始明显吃力;而梯度下降每次迭代只跟 m×n 成正比,特征多、样本多的时候反而更稳。

对比项梯度下降正规方程
需要选学习率 α需要不需要
需要迭代需要,次数看曲线不需要,一次求解
需要特征缩放需要不需要
特征数很大时可扩展求逆开销急剧上升
其他模型能否复用逻辑回归、神经网络都用它只适用于线性回归这类形式

正规方程还有一个必须知道的坑:当特征之间存在线性相关,或者特征数 n 大于等于样本数 m 时,XᵀX 不可逆。处理办法不是硬求伪逆,而是删掉冗余特征,或者加正则项——加正则之后矩阵一定可逆,这个结论在后面讲正则化时会再遇到一次。

3. 分类与复杂度控制:逻辑回归、正则化与神经网络

监督学习主线的第二段从“预测连续值”转到“判断类别”。这一步换的不只是函数形式,还换了损失函数、评估指标和一整套调试直觉。

3.1 逻辑回归:把输出压进 (0,1) 的代价函数

逻辑回归的假设函数是 h_θ(x) = g(θᵀx),其中 g(z) = 1/(1+e^(−z)) 是 sigmoid 函数,把任意实数压进 (0,1)。它的输出可以理解为“属于正类的概率估计”,这个解释在后续调阈值、算精确率和召回率时都会用到。

关键的一步是换损失函数。如果把平方损失直接套在 sigmoid 上,代价函数对 θ 就不再是凸的,梯度下降会停在局部极小值上,结果好坏全看初始化运气。正确的做法是用交叉熵形式:

import numpy as np def logistic_cost(theta, X, y, eps=1e-9): # X: (m, n+1),含偏置列;y: (m,),取值为 0 或 1 z = X @ theta h = 1.0 / (1.0 + np.exp(-z)) h = np.clip(h, eps, 1 - eps) # 防止 log(0) 变成 -inf 污染整个代价 return -(y @ np.log(h) + (1 - y) @ np.log(1 - h)) / len(y)

np.clip那一行不是多余的保险。当某个样本的预测概率被压到极接近 0 或 1 时,log 会返回负无穷,一次迭代就能把梯度变成 NaN,之后所有参数都是 NaN,现象是损失曲线突然消失。加上 eps 截断,代价最多变大一点,不会直接崩掉。

决策边界是 θ 的属性,不是数据的属性。θᵀx = 0 定义的那条线(或曲面)把特征空间一分为二,训练只是在旋转和平移这条边界;边界画成曲线,靠的是往特征里加多项式项,而不是换模型。多分类用一对多:为每个类别训练一个“属于该类 vs 其他所有类”的二分类器,预测时取输出概率最大的那个。

3.2 正则化:λ 在偏差和方差之间移动

正则化的做法是在代价函数后面加一项 (λ/2m)·Σθⱼ²,注意求和从 j=1 开始,θ₀ 不参与惩罚——截距只是平移,不影响模型的弯曲程度,惩罚它没有意义,反而会让模型在标签整体偏移时表现变差。

λ 的作用是连续的:λ = 0 时正则项完全失效,模型可以为了拟合每一个训练点把参数推到很大,表现为训练误差极低、交叉验证误差很高;λ 逐渐增大,参数被压向零,模型变平滑;λ 大到过头,所有参数趋近于零,模型退化成一条水平线,训练误差和验证误差一起变高。这条曲线的两端都是坑,中间的取值要靠验证集来定,而不是凭感觉。

正则化后的梯度更新式会多出一个收缩因子:θⱼ := θⱼ(1 − αλ/m) − (α/m)·Σ(h_θ(x⁽ⁱ⁾) − y⁽ⁱ⁾)·xⱼ⁽ⁱ⁾。前一项让每次迭代参数都先按比例缩小一点,后一项才是拟合数据的方向,两者拉扯出来的平衡点就是最终解。线性回归的正规方程版本则是 θ = (XᵀX + λI')⁻¹Xᵀy,其中 I' 是把单位阵第一项改成 0 的矩阵——顺带解决了上一节提到的不可逆问题。

注意:正则化不能替代特征缩放。加了正则项之后,未缩放特征的系数本来就被压得更狠,等于在惩罚力度上对不同特征区别对待,结果会莫名其妙地偏向尺度大的特征。

3.3 神经网络:前向传播的矩阵视角与对称初始化

神经网络的每一层做的事可以写成 a⁽ˡ⁾ = g(Θ⁽ˡ⁻¹⁾a⁽ˡ⁻¹⁾),其中 a⁽⁰⁾ = x,计算前要往 a 里补一个 1 作为偏置项。参数矩阵 Θ⁽ˡ⁾ 的形状是 sₗ₊₁ × (sₗ + 1),即“下一层单元数 × 本层单元数加一”,这个维度关系错一次就会在矩阵乘法上报错,靠它自检比靠打印调试快得多。

反向传播要算的是每层的误差项 δ,从输出层往输入层递推,用到的是链式法则和前向传播时保存的中间结果。最容易忽略的一点是:误差项里要去掉偏置单元对应的那一项,因为偏置不对应任何输入特征,不需要梯度。另外,如果输出层用一对多编码,输出单元数等于类别数,而不是类别数减一。

初始化的规则是随机且接近零:用 Θ = rand(sₗ₊₁, sₗ+1) × 2ε − ε 打散。全部初始化为零会让同一层的所有单元在训练中始终保持相同,网络等价于只有一个单元——这个现象叫对称失效,写起来一句话,调试起来能让人找半天。梯度检验在这里同样适用,但要记得检验时把正则项算进去,否则比对不上。

3.4 核方法与支持向量机:什么时候不用神经网络

支持向量机在特征数不大、样本量中等的场景下仍然是很强的选择,它的核心是用核函数隐式地把特征映射到高维,从而在原始空间里画出非线性边界。两个参数控制模型的松紧:C 相当于正则化强度的倒数,C 大意味着不太允许分类错误,偏差低、方差高;高斯核里的 σ² 越大,单个样本的影响范围越广,边界越平滑,偏差高、方差低。

选择模型的直觉可以按特征数和样本量来分:特征数 n 远大于样本数 m 时,用逻辑回归或线性核,因为高维空间里本来就容易线性可分,再上非线性核只会过拟合;n 小、m 中等时,高斯核往往表现最好;n 小、m 极大时,先补特征、再用线性模型或神经网络。神经网络适用面最广,但训练成本最高,且需要调的东西更多。

4. 无监督与流程诊断:聚类、降维、偏差方差与误差分析

前面几章讲的都是“已知答案”的情形。真实项目里还有一半的功夫花在没有标签的数据上,以及判断当前模型到底缺什么。

4.1 聚类与降维:K-means 和 PCA 的判断标准

K-means 的流程只有两步循环:把每个样本分配给最近的中心,再把每个中心移到它名下样本的均值处。它的目标函数是各点到所属中心距离平方和,迭代过程中这个值单调不增。因为可能停在局部最优,实践中要随机初始化几十次,取目标函数最小的那一组结果,这一步很多人省掉,然后发现每次跑出来的簇都不一样,还以为是随机种子的问题。

选 K 的方法被讲得最多的是肘部法:画 K 与目标函数的关系曲线,找拐点。真实数据里拐点经常不明显,这时候更可靠的做法是问下游用途——聚类结果要喂给什么任务,那个任务要的是粗分还是细分,K 就跟着定。

PCA 之前必须做均值归一化,必要时还要特征缩放,否则方差大的特征会垄断主成分方向。降维维数 k 的选法是看保留的方差比例,通常取到 99% 左右。这里有两条非常容易踩的误区:一是用 PCA 来防过拟合,降维丢掉的可能是有效信息,防过拟合应该用正则化;二是一上来就对数据做 PCA 可视化,实际更该先看原始特征的分布和量纲。

4.2 异常检测与推荐系统:极不平衡样本怎么评估

异常检测假设正常样本的每个特征服从高斯分布,把各维概率相乘得到 p(x),低于阈值 ε 就判为异常。这里没有标签也能训练,但阈值的选择需要一批带标签的验证数据,并且评估指标用 F1 而不是准确率——异常样本占比不到 1% 时,全判正常也能拿到 99% 的准确率,这个数字毫无意义。

什么时候该用监督学习、什么时候该用异常检测,判断标准是异常的类型和数量:如果异常样本只有个位数、而且未来出现的异常类型无法预知,用异常检测;如果已经有几十上百个带标签的异常样本,且未来的异常类型和已知的相似,用监督学习更准。这个判断做反了,效果会差很多。

推荐系统的协同过滤是另一种思路:没有每个用户的偏好向量,也没有每个物品的特征向量,那就交替估计——固定物品特征求用户偏好,再固定用户偏好求物品特征,反复迭代到收敛。有个细节容易被跳过:对从未评分的用户,先按每个物品的均值做中心化处理,否则模型会预测出一个“平庸但错误”的高分。

4.3 偏差方差与学习曲线:诊断顺序不能反

拿到一个效果不好的模型,第一步不是加数据、也不是换模型,而是判断它属于高偏差还是高方差。判断方法看两个数:训练误差和交叉验证误差。

组合训练误差交叉验证误差诊断主要动作
情形一高高,且与训练误差接近高偏差、欠拟合加特征、加多项式项、减小 λ、换更强的模型
情形二低高,远高于训练误差高方差、过拟合加样本、减特征、增大 λ
情形三低低合适关注业务指标和误差分析
情形四高更高偏差方差都高先解决偏差,再解决方差

学习曲线把这件事画得更清楚:横轴是样本量,纵轴是误差。高偏差时,两条曲线很快靠拢在一个偏高的位置,继续加数据几乎没用;高方差时,两条曲线中间有一条明显的缝,加样本能让验证误差继续下降。这个图能挡掉大量无效投入——训练集翻倍的成本远高于先做一次诊断。

4.4 误差分析与上限分析:把力气花在刀刃上

误差分析的做法很手工:拿一批交叉验证样本,把预测错的挑出来,人工归类,数一数哪一类占大头。如果某一类错误占了 60%,那下一个动作就明确了;如果错例零散分布在十几个类别上,说明问题不在某个具体环节,回去看特征和模型容量。

上限分析用于多模块串联的系统:逐个把某个模块换成“人工给出的正确答案”,看整体指标能涨多少。涨得多的模块值得投入,几乎不涨的模块说明它是瓶颈之外的东西,优化它没有收益。这一步做完,往往能把“要不要重写某个子模块”这种争论直接终结。

5. 易错点:五处最容易翻车的地方

这一章按“易漏点 → 为什么漏 → 怎么补”写,都是复习时最容易一眼扫过、实战里最容易出问题的地方。

5.1 数学实现里的两处硬伤

易漏点一:正则化时把 θ₀ 也算进惩罚项。为什么漏——向量化写法里 θ 是一个整体,1/2m·λ·θᵀθ 一行就写完了,看起来干净利落,很少有人会特意回头把第 0 项摘出来。怎么补——在代码里显式区分:正则项用 theta[1:] @ theta[1:],梯度里第 0 个分量不加收缩因子。更稳妥的办法是写一个单元测试,把 λ 设成极大值,看 θ₀ 是否基本不变,其余参数是否被压到接近零,符合预期才算写对。

易漏点二:用平方损失训练逻辑回归,或者忘了给 log 加截断。为什么漏——平方损失的代码上一章刚写过,复制过来改个假设函数就能跑,损失曲线看着也在下降,于是没人再回头验证凸性。而 log(0) 的问题更隐蔽,它只在某次迭代里偶发,出现一次就全程 NaN,现象是损失变成 nan 而不是报错。怎么补——固定用交叉熵形式,并在取 log 前统一 clip 到 [1e-9, 1−1e-9];训练结束后加一个断言,检查参数和损失是否都为有限值。

5.2 流程与评估里的两处误用

易漏点三:拿测试集反复调参。为什么漏——手上只有一份数据,切出训练和测试之后,很自然地会看着测试集的表现去改 λ、改特征、改模型,改到满意为止。问题是每看一次测试集,它就向训练过程泄露一点信息,最终报出来的泛化误差是乐观的。怎么补——严格三段切分:训练集拟合参数,验证集选 λ 和模型,测试集只在最后用一次。数据量小的时候用 k 折交叉验证来选超参,测试集留到最后。如果已经反复看过测试集,那这份数据只能当验证集用,得重新找一份干净数据来评估。

易漏点四:用准确率评价类别极不平衡的问题。为什么漏——准确率是默认指标,几乎所有库的评估函数第一个返回它,拿到 0.98 的第一反应是效果不错,而不是去看正类召回是多少。怎么补——先看类别比例,只要正类占比低于一成,就改看精确率、召回率和 F1;需要控制误报时看精确率,需要尽量不漏时看召回率,两者拉扯时用 F1 或看具体的业务代价。阈值也要跟着调,别死守 0.5。

5.3 工程习惯上的一处隐形坑

易漏点五:神经网络全零初始化,或者把梯度检验留在训练循环里。为什么漏——初始化写成 np.zeros 是最省事的写法,而梯度检验的代码看起来“更严谨”,好像留着也无害,很多人干脆不删。怎么补——初始化统一用 rand × 2ε − ε,并检查同一层各单元的初始权重确实不同;梯度检验只在调试阶段跑一次,用极小的 ε 和少量样本,确认相对误差在 1e-7 量级后立刻注释掉或删除。反向传播写错时,数值梯度对比是唯一能在几分钟内定位问题的手段,所以这段代码值得写,但不值得留。

提示:这五条里的每一条,都不是“理论上可能错”,而是复习时看着都懂、动手时真会写错。复习阶段建议把每条对应到自己的代码里,逐条找一遍。

6. 复习清单:把整门课压成一张自测表

复习到最后阶段,最有用的做法是把知识压缩成一张自测表:每一行是一个模块,每一列是“能不能用自己的话讲清楚”。讲不清的那一格,就是下一轮要花时间的地方。

模块自测问题达标标准
假设函数为什么补 x₀ = 1?模型能表达什么由谁决定?能说清参数与特征的对应关系
代价函数为什么除以 2m?平方损失隐含什么假设?能解释常数因子的作用与离群点的影响
梯度下降更新式怎么推?α 过大和过小分别什么现象?能画出 J 曲线的三种形态并对应判断
特征缩放对谁做、用哪组统计量、为什么测试集不能重算能说出信息泄露的具体后果
逻辑回归为什么不用平方损失?决策边界由什么决定?能写出交叉熵并解释 clip 的必要
正则化λ 从 0 增大会发生什么?为什么 θ₀ 不惩罚?能对应到偏差方差的移动方向
神经网络参数矩阵形状?为什么不能全零初始化?能独立推一遍前向传播的维度
诊断高偏差和高方差分别看哪两个数?能画出两种学习曲线的形状
评估什么情况下准确率失去意义?能说出改用 F1 的判断依据
无监督K-means 为什么多次初始化?PCA 能不能防过拟合?两条都能给出否定或肯定的理由

如果只能安排三天,可以这么走:第一天过公式和推导,把梯度下降、交叉熵、正则项三处的更新式在纸上各推一遍;第二天只做诊断练习,随便找几组“训练误差、验证误差”的组合,练习判断该加特征还是加样本;第三天对着上面的表做自测,凡是卡住超过三十秒的格子,回去翻对应章节,只翻那一节。

我自己的教训很具体:第一次系统学的时候,我把大部分时间花在推导上,正则化的梯度式子写得一丝不差,却从来没想过 λ 变大到底会把模型推向哪边。后来真正动手才发现,判断方向比记住式子有用得多。从那以后我每次复习,都强制先走一遍“训练误差多少、验证误差多少、该动哪一端”的判断,再去翻公式。

这份按主线梳理的完整笔记,覆盖了从假设函数、代价函数、正则化到偏差方差、误差分析与复习清单的全部条目,需要拿去对照复习的话,直接取用即可。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询