
1. 从零散笔记到体系化知识库的整理思路1.1 为什么选择在这个时间点做完整梳理机器学习这门课很多人都是“看的时候懂合上书就忘”。我自己在学这门课的时候前前后后刷了三遍讲义第一遍是跟着视频走马观花第二遍是配合作业硬啃公式第三遍才真正把概率图模型、指数族分布、广义线性模型这些概念串起来。但真正让我产生“必须把笔记整理出来”这个念头的是某次给一个刚入门的同学讲梯度下降的推导讲到一半发现自己对矩阵求导的某个细节记忆模糊了翻回原来的笔记发现当时只记了结论没记推导过程。这件事让我意识到零散的笔记和体系化的知识库之间差的不只是排版而是知识之间的连接关系。你记下“牛顿法收敛快但计算量大”和你能说清楚“为什么牛顿法在海森矩阵接近奇异时会失效、这和条件数的关系是什么”完全是两个层次的理解。所以这次整理我的目标不是把讲义抄一遍而是把每个算法背后的动机、假设、推导链条、适用边界全部打通。另一个触发点是我发现网上很多笔记要么是纯公式堆砌要么是纯直觉解释很少有把“数学推导”和“工程直觉”结合得比较好的。比如逻辑回归的损失函数从最大似然推导出来是对数损失从信息论角度是交叉熵从凸优化角度它又是光滑可导的——这三个视角其实说的是同一件事但分开看就容易割裂。我想做的就是把这些视角在笔记里显式地连起来。1.2 整体架构三层结构的设计逻辑整理之前我先定了一个框架把整个课程内容分成三层基础层线性代数回顾、概率论基础、凸优化入门。这部分不是课程重点但如果不扎实后面寸步难行。核心层监督学习线性回归、逻辑回归、广义线性模型、生成学习算法、核方法、SVM、决策树、集成方法、无监督学习K-means、GMM、EM算法、PCA、ICA、学习理论偏差方差分解、VC维、正则化。进阶层强化学习基础、概率图模型、变分推断初步。这个分层的好处是复习的时候可以按需跳转。比如你只想搞懂SVM那就直接从核心层进去遇到拉格朗日对偶不懂再回基础层补。而不是像看视频那样必须从头到尾线性推进。每一层的笔记我采用统一的模板算法名称→解决什么问题→核心假设→数学推导→优化方法→复杂度分析→常见变体→踩坑记录这个模板是我试了好几种之后定下来的。最早我按“定义-公式-例子”来记后来发现缺少“解决什么问题”这一环导致过段时间就忘了为什么要学这个算法。加上“核心假设”之后很多算法的局限性就一目了然了——比如线性回归假设噪声是高斯分布且同方差一旦数据有异方差性普通最小二乘就不是最优的了。1.3 工具选型为什么最终用了Markdown加LaTeX工具这块我折腾了不少时间。最早用Word公式编辑慢版本管理混乱后来试过Notion在线编辑方便但导出PDF时公式渲染经常出问题再后来用Jupyter Notebook代码和公式能混排但纯数学推导的排版不够清爽。最终定下来用Markdown LaTeX的组合理由有几个纯文本存储Git可以管理版本每次修改都有记录不怕丢。公式渲染质量高LaTeX的数学排版是学术界标准矩阵、多行公式、对齐环境都很成熟。跨平台任何编辑器都能打开不依赖特定软件。导出灵活用Pandoc可以转PDF、HTML、Word分享给不同需求的人。具体配置上我用VS Code加Markdown All in One插件配合LaTeX Workshop做预览。数学公式用$...$行内和$$...$$块级矩阵用\begin{bmatrix}...\end{bmatrix}。这里有个小技巧多行公式对齐用\begin{aligned}...\end{aligned}而不是eqnarray后者在部分渲染器里会有间距问题。注意如果你也用Markdown记数学笔记建议在文件开头加一个\newcommand的宏定义区把常用的符号比如\R表示实数集、\E表示期望、\argmin等统一定义后面写起来会快很多而且全局替换也方便。2. 核心内容的深度拆解与实操要点2.1 监督学习部分的推导链条怎么记才不忘监督学习是这门课的重头戏也是笔记量最大的部分。我的经验是不要孤立地记每个算法而是抓住“从假设到损失到优化”这条主线。以线性回归为例完整的推导链条是这样的假设$y \theta^T x \epsilon$其中$\epsilon \sim \mathcal{N}(0, \sigma^2)$。似然$p(y|x;\theta) \frac{1}{\sqrt{2\pi}\sigma}\exp\left(-\frac{(y-\theta^Tx)^2}{2\sigma^2}\right)$。最大似然取对数后最大化似然等价于最小化$\sum(y^{(i)} - \theta^Tx^{(i)})^2$。优化对$\theta$求导令为零得到正规方程$\theta (X^TX)^{-1}X^Ty$。概率解释为什么最小二乘是合理的因为高斯噪声假设下最大似然就是最小二乘。这条链条记清楚了后面逻辑回归就是换一个假设$y \in {0,1}$用Sigmoid函数把线性输出映射到概率然后从伯努利分布的最大似然推出交叉熵损失。再往后广义线性模型就是把这两者统一起来指数族分布 自然参数 链接函数。我在笔记里专门画了一张表把线性回归、逻辑回归、Softmax回归放在一起对比算法输出类型分布假设链接函数损失函数线性回归连续值高斯分布恒等函数均方误差逻辑回归二分类伯努利分布Sigmoid交叉熵Softmax回归多分类多项式分布Softmax交叉熵这张表一摆出来广义线性模型的“广义”在哪里就清楚了——分布假设不同链接函数不同但优化框架是一样的。2.2 生成学习算法与判别学习算法的本质区别这部分是我当时学的时候最困惑的地方。高斯判别分析GDA和逻辑回归明明都是分类为什么一个叫生成一个叫判别后来我想明白了一个类比判别模型是直接学“边界”生成模型是先学“每个类别长什么样”再用贝叶斯定理推边界。具体来说GDA假设$p(x|y)$是高斯分布$p(y)$是伯努利分布然后通过贝叶斯定理计算$p(y|x)$。而逻辑回归直接建模$p(y|x)$。有趣的是GDA的假设高斯且协方差相同比逻辑回归更强所以当假设成立时GDA需要更少的样本就能达到同样的效果但当假设不成立时逻辑回归更稳健。我在笔记里记了一个实操心得如果你对数据的分布有很强的先验知识用生成模型如果你只关心分类边界用判别模型。比如文本分类里朴素贝叶斯生成在小样本上往往比逻辑回归表现好就是因为词分布的假设条件独立虽然不准确但在小样本下反而起到了正则化的作用。2.3 核方法与SVM从对偶到核技巧的完整推导SVM是这门课里数学最密集的部分之一。我的笔记分了四步来记第一步最大间隔的原始问题。我们要找一个超平面使得最近的点到它的距离最大。这个“距离”就是函数间隔除以$|\theta|$得到几何间隔。优化目标写成$$\max_{\theta,b} \min_i \frac{y^{(i)}(\theta^Tx^{(i)}b)}{|\theta|}$$第二步转化为凸优化问题。通过缩放约束令函数间隔为1问题变成最小化$\frac{1}{2}|\theta|^2$约束是$y^{(i)}(\theta^Tx^{(i)}b) \geq 1$。第三步拉格朗日对偶。引入拉格朗日乘子$\alpha_i$写出对偶问题。这里的关键是KKT条件特别是互补松弛条件只有当样本点在间隔边界上时对应的$\alpha_i$才非零。这些点就是支持向量。第四步核技巧。在对偶问题中目标函数和决策函数都只涉及内积$\langle x^{(i)}, x^{(j)} \rangle$。把内积替换成核函数$K(x^{(i)}, x^{(j)})$就实现了非线性映射而且不需要显式计算高维特征。踩坑记录我一开始不理解为什么核函数要满足Mercer条件。后来查了资料才明白Mercer条件保证核矩阵是半正定的这样对偶问题才是凸的才能用二次规划求解。常用的多项式核、高斯核都满足这个条件。2.4 无监督学习EM算法与高斯混合模型的收敛性分析EM算法是另一个让我卡了很久的地方。K-means好理解就是不断分配点到最近的中心然后更新中心。但GMM的EM算法E步和M步的公式是怎么来的我的笔记里记了完整的推导E步计算每个点属于每个簇的后验概率$\gamma_{ik} \frac{\pi_k \mathcal{N}(x_i|\mu_k,\Sigma_k)}{\sum_j \pi_j \mathcal{N}(x_i|\mu_j,\Sigma_j)}$。M步用这些后验概率作为权重更新$\pi_k$、$\mu_k$、$\Sigma_k$。关键问题是为什么这样迭代能保证似然函数单调不减这涉及到Jensen不等式和ELBO证据下界的推导。简单说EM算法是在优化一个下界E步固定参数优化下界M步固定下界优化参数两者交替似然函数就会单调上升。我在笔记里特别标注了EM算法收敛到的是局部最优不是全局最优。所以实际使用时通常要跑多次随机初始化取似然最大的那次。另外如果协方差矩阵出现奇异某个簇只有一个点似然会趋于无穷这时候需要加正则项或者重新初始化。3. 实操过程与核心环节的完整记录3.1 从讲义到笔记我的具体整理流程整个整理过程我分了五个阶段每个阶段都有明确的产出阶段一快速通读标记重点。我先把所有讲义和视频过一遍用不同颜色的高亮标记黄色是核心定义蓝色是推导关键步骤红色是没看懂的地方。这个阶段不求甚解只求建立全局感。阶段二逐章精读手写推导。对于标记为红色的部分我会在纸上手推一遍。手推的好处是强迫自己关注每一步的细节比如矩阵求导时的维度变化、概率积分时的变量替换。推完之后再把推导过程用LaTeX敲进笔记。阶段三代码验证加深理解。对于每个算法我会用Python实现一个最小版本。比如线性回归用正规方程和梯度下降两种方法实现对比结果逻辑回归用牛顿法实现观察收敛速度。代码不追求效率只追求逻辑清晰。阶段四交叉引用建立连接。这一步是在笔记之间加链接。比如在逻辑回归的笔记里链接到广义线性模型的笔记在SVM的笔记里链接到拉格朗日对偶的笔记。这样复习时就能顺着链接跳转而不是孤立地看。阶段五输出总结查漏补缺。最后我会为每个大章节写一个“一页纸总结”只包含最核心的公式和直觉解释。如果某个算法的总结写不出来说明还没真正理解需要回去补。3.2 关键公式的推导细节与常见错误这里挑几个我踩过坑的公式推导详细说一下。第一个坑矩阵求导的维度匹配。在线性回归的正规方程推导中需要对$\theta$求导$$\nabla_\theta \frac{1}{2}(X\theta - y)^T(X\theta - y) X^T(X\theta - y)$$我一开始总是搞不清什么时候转置。后来总结了一个规则标量对向量求导结果的维度要和被求导的向量一致。这里$\theta$是$n \times 1$所以结果也应该是$n \times 1$。$X^T(X\theta - y)$中$X^T$是$n \times m$$(X\theta - y)$是$m \times 1$乘起来是$n \times 1$维度对上了。第二个坑Sigmoid函数的导数。逻辑回归的梯度推导中需要用到$\sigma(z) \sigma(z)(1-\sigma(z))$。这个公式看起来简单但推导时容易漏掉负号。我的记忆方法是Sigmoid的导数等于自身乘以1减自身这个形式很对称不容易忘。第三个坑高斯分布的积分。在GDA的推导中需要计算高斯分布的最大似然估计。这里涉及到对$\Sigma$求导用到了矩阵求导的迹技巧$$\nabla_\Sigma \log|\Sigma| \Sigma^{-T}$$$$\nabla_\Sigma \text{tr}(\Sigma^{-1}S) -\Sigma^{-T}S^T\Sigma^{-T}$$这两个公式我当时推了很久后来发现记住结论就行推导过程在笔记里附上参考链接即可。3.3 代码实现中的向量化技巧在实现这些算法时向量化是绕不开的。我举几个例子K-means的向量化计算每个点到每个中心的距离可以用矩阵运算一次性完成。假设数据是$X \in \mathbb{R}^{m \times n}$中心是$C \in \mathbb{R}^{k \times n}$则距离矩阵$D$的每个元素$D_{ij} |X_i - C_j|^2$。利用$|a-b|^2 |a|^2 |b|^2 - 2a^Tb$可以写成D np.sum(X**2, axis1, keepdimsTrue) np.sum(C**2, axis1) - 2 * X C.T这样比双重循环快几十倍。逻辑回归的梯度下降梯度$\nabla_\theta J \frac{1}{m}X^T(\sigma(X\theta) - y)$其中$\sigma$是逐元素的Sigmoid。用NumPy一行就能写出来grad (1/m) * X.T (sigmoid(X theta) - y)EM算法的E步计算后验概率时需要对每个簇计算高斯密度。可以用广播机制for k in range(K): diff X - mu[k] exponent -0.5 * np.sum(diff np.linalg.inv(Sigma[k]) * diff, axis1) coef 1 / np.sqrt((2*np.pi)**n * np.linalg.det(Sigma[k])) pdf[:, k] coef * np.exp(exponent) gamma pdf * pi / np.sum(pdf * pi, axis1, keepdimsTrue)实操心得向量化代码写完之后一定要用一个小数据集和循环版本对比结果确保逻辑正确。我在这上面吃过亏向量化写错了但没发现跑出来的结果和预期差很多排查了半天才发现是广播维度的问题。4. 常见问题与排查技巧实录4.1 数学推导中的典型卡点与突破方法在整理笔记的过程中我遇到了不少卡点这里列几个有代表性的卡点一拉格朗日对偶的强对偶性条件。SVM的推导中原问题是凸的且满足Slater条件所以强对偶成立。但Slater条件具体是什么我查了资料才搞清楚存在一个严格满足不等式约束的点。对于SVM因为约束是线性的只要数据不是完全不可分就存在这样的点。卡点二EM算法的Jensen不等式推导。ELBO的推导中关键一步是利用Jensen不等式把对数里的求和拿出来。Jensen不等式说的是对于凸函数$f$$f(\mathbb{E}[X]) \leq \mathbb{E}[f(X)]$。因为$\log$是凹函数所以不等号方向反过来。这个细节我当时搞混了导致下界的方向搞反了。卡点三PCA的两种推导视角。PCA可以从最大化投影方差推导也可以从最小化重构误差推导。这两种视角得到的解是一样的但直觉不同。我在笔记里把两种推导都写了一遍并标注了它们等价的条件当投影向量是正交基时最大化方差和最小化重构误差是等价的。4.2 笔记整理中的效率陷阱与应对策略整理笔记本身也是个技术活我踩过几个效率陷阱陷阱一追求完美排版。一开始我花了很多时间调整公式的间距、对齐、字体结果进度很慢。后来我定了一个规则先写内容排版最后统一处理。公式只要渲染正确就行美观度放在第二位。陷阱二过度摘抄。有段时间我几乎把讲义原封不动地抄了一遍结果笔记厚是厚但复习时抓不住重点。后来我改成用自己的话重述每段内容都问自己“这句话的核心是什么我能不能用更简单的语言说清楚”陷阱三缺少索引。笔记多了之后找某个知识点很麻烦。后来我在每个文件开头加了一个目录用Markdown的锚点链接跳转。另外我用标签系统给每个笔记打了标签比如#监督学习、#优化、#概率图这样可以用搜索快速定位。4.3 常见问题速查表问题现象可能原因排查方法解决方案梯度下降不收敛学习率过大打印损失曲线减小学习率或使用自适应方法正规方程矩阵不可逆特征共线性计算条件数加正则项或删除相关特征SVM对偶问题求解慢样本量大检查支持向量比例使用SMO算法或线性核近似EM算法似然下降实现错误检查E步和M步公式确保E步归一化、M步更新正确PCA投影后方差很小未中心化检查均值先减去均值再计算协方差逻辑回归过拟合特征过多对比训练和验证误差加L2正则或减少特征避坑技巧对于EM算法我建议在每次迭代后打印似然值如果出现下降一定是E步或M步的实现有问题。最常见的是E步的后验概率没有归一化或者M步更新协方差时忘了除以权重和。4.4 从笔记到分享如何让内容对别人也有价值整理完之后我试着把笔记分享给几个同学发现了一些问题问题一假设读者有背景知识。我写“由KKT条件可得”但没解释KKT条件是什么。后来我在每个专业术语第一次出现时都加了简短解释或链接。问题二缺少动机说明。我直接写“我们定义核函数为...”但没说明为什么要定义核函数。后来我在每个算法开头都加了一段“为什么需要这个”。问题三公式太多直觉太少。纯公式的笔记读起来很累。后来我在每个公式后面加了一句“人话解释”比如“这个公式说的是后验概率正比于先验乘以似然”。经过这几轮修改笔记的可读性好了很多。我的体会是好的笔记不仅是给自己看的还要能经得起别人的审视。当你试图向别人解释一个概念时往往会发现自己理解中的漏洞。5. 一些额外的经验与建议5.1 关于学习节奏的安排这门课的内容密度很大我建议不要试图一次性学完。我的节奏是每周集中攻克一个主题周末做总结和代码实现。比如第一周线性回归和逻辑回归第二周广义线性模型和生成学习算法第三周SVM和核方法以此类推。每个主题的学习分三步看视频建立直觉 → 读讲义补推导 → 写代码验证。三步走完基本就能掌握得比较扎实。如果时间紧至少要走完前两步。5.2 关于数学基础的补充如果数学基础不够我建议先补三块线性代数矩阵运算、特征值分解、SVD、概率论贝叶斯定理、常见分布、期望方差、微积分偏导数、链式法则、拉格朗日乘子法。这三块是这门课的基础不补的话后面会很吃力。补的方式不一定要系统学教材可以用到什么补什么。比如学到SVM时发现拉格朗日对偶不懂就专门去查对偶的资料这样学起来有针对性记忆也更深。5.3 关于笔记的维护和更新笔记不是写完就完了后续的维护也很重要。我的做法是定期回顾每个月抽时间翻一遍笔记看看有没有新的理解可以补充。版本控制用Git管理每次修改都有记录方便回溯。开放分享把笔记放在公开仓库里接受别人的反馈和纠错。最后再分享一个小技巧在笔记里留一个“疑问区”把当时没想明白的问题记下来后面如果解决了就回来更新。我有很多重要的理解都是在回顾这些疑问时突然想通的。