news 2026/10/10 15:56:25

机器学习笔记整理指南:从推导到代码复现的完整路径

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
机器学习笔记整理指南:从推导到代码复现的完整路径

1. 从零到一:这份笔记到底在解决什么问题

如果你正在啃机器学习,大概率经历过这样的场景:视频看完了,公式推导也跟上了,但合上电脑脑子里只剩下一堆散落的符号,真要自己从头推一遍逻辑回归的梯度,或者解释清楚为什么高斯判别分析在某些条件下比逻辑回归更“稳”,就卡壳了。我当初也是这个状态,后来花了相当长一段时间,把一门经典机器学习课程的完整脉络从头到尾梳理成了一套自己的笔记,最近终于收尾完结,顺手把整理过程中的思路、踩过的坑和复用方法分享出来。

这套笔记的核心,不是把课件抄一遍,而是把“为什么这么设计”这条线拉直。它覆盖了监督学习(线性回归、逻辑回归、广义线性模型、生成学习算法、支持向量机、决策树与集成)、无监督学习(K-means、混合高斯与EM、因子分析、PCA、独立成分分析)、学习理论(偏差方差权衡、VC维、正则化与模型选择)以及强化学习的基础框架。适合两类人:一类是正在系统入门、需要一份能对照推导的“第二讲义”的学习者;另一类是已经用过一些模型、但底层原理模糊、想回头补课的在职开发者。它解决的问题很具体——把散落在几十个视频和讲义里的知识点,压缩成一条可以反复查阅、能自己动手复现的推导链。

我个人的判断是,机器学习入门最大的障碍从来不是某个算法难,而是知识点之间的“接口”没打通。比如你单独看逻辑回归能懂,单独看广义线性模型也能懂,但两者之间的那层窗户纸——指数族分布和链接函数的关系——如果没人点破,就会一直悬着。这份笔记的整理逻辑,就是围绕这些接口来组织的。

2. 整体架构设计:为什么按这条线来组织

2.1 三条主线:模型、优化、泛化

整理笔记最容易犯的错,是按课程章节顺序平铺。这样看起来整齐,但复习时你会发现,线性回归和逻辑回归被隔开了,而它们其实共享同一套优化框架。我最后采用的是三条主线交叉的结构:

  • 模型线:从线性模型出发,经过广义线性模型统一视角,再到生成式模型(高斯判别、朴素贝叶斯)和判别式模型(SVM、感知机),最后到非参数方法(决策树、KNN)。
  • 优化线:最小二乘的闭式解、梯度下降、牛顿法、坐标上升、EM算法、SMO,这条线回答“参数到底怎么求出来”。
  • 泛化线:偏差方差分解、正则化、交叉验证、VC维、PAC学习,这条线回答“求出来的模型凭什么可信”。

三条线不是并列的,而是互相咬合。比如讲SVM时,优化线要讲对偶和SMO,泛化线要讲最大间隔和核技巧的容量控制,模型线则把它和逻辑回归做对比。这样组织的好处是,任何一个算法你都能从三个角度去定位它,而不是孤立地记公式。

2.2 为什么不用“一章一算法”的写法

我试过按算法逐个写,写到第五个就发现大量重复:每个算法都要重新讲一遍损失函数、优化方法、正则化,读者会疲劳,写的人也会烦。改成主线结构后,重复的部分被抽成公共章节,比如“指数族与广义线性模型”单独成章,后面逻辑回归和softmax就直接引用,篇幅省了将近三分之一,逻辑反而更清楚。

提示:如果你也在整理自己的笔记,强烈建议先花半天时间画一张“概念依赖图”,把每个知识点依赖的前置概念标出来。这张图决定了你的章节顺序,比目录本身重要得多。

2.3 数学推导的取舍标准

课程里很多推导是跳步的,笔记如果照抄就失去了价值。我的取舍标准是:凡是涉及“为什么这一步能这么变”的地方,必须补全;凡是纯代数化简,可以留白让读者自己动手。比如逻辑回归的梯度推导,关键一步是sigmoid函数的导数性质,这个必须写清楚;而后面把矩阵形式展开成求和形式,属于机械操作,留个提示即可。这样既保证了可读性,又不会把笔记变成保姆式教程。

3. 核心模块拆解:几个必须讲透的关键点

3.1 广义线性模型:把三个模型串成一根绳

这是整份笔记里我认为最有价值的一章。很多人学完线性回归、逻辑回归、softmax回归,感觉它们是三个独立的东西,其实它们都是广义线性模型的特殊情况。核心就三件事:

  1. 假设输出变量 y 服从指数族分布,即 ( p(y;\eta) = b(y)\exp(\eta^T T(y) - a(\eta)) )。
  2. 定义自然参数 ( \eta = \theta^T x )。
  3. 预测时取 ( h_\theta(x) = E[T(y)|x] )。

只要这三步确定,模型形式就唯一确定了。线性回归对应高斯分布,逻辑回归对应伯努利分布,softmax对应多项分布。我在笔记里把这三个推导完整写了一遍,尤其是从分布到预测函数的期望计算,这是最容易卡住的地方。

注意:指数族的标准形式里,( T(y) ) 是充分统计量,很多教材直接取 ( T(y)=y ),但推导时要说明为什么可以这么取。这个细节不写清楚,后面softmax的推导会突然冒出一个矩阵形式的 ( T(y) ),让人措手不及。

3.2 生成式与判别式的分水岭

高斯判别分析和逻辑回归的关系,是另一个必须点破的接口。GDA假设 ( p(x|y) ) 是高斯分布,推导出来的后验 ( p(y|x) ) 恰好是sigmoid形式——也就是说,GDA的决策边界和逻辑回归是同一族函数。但两者的假设不同:GDA假设了更强的分布形式,所以在数据确实服从高斯假设时,它需要的样本更少、效果更好;而逻辑回归更鲁棒,假设错了也能work。

我在笔记里用了一个对比表格来总结:

维度高斯判别分析逻辑回归
假设( p(xy) ) 为高斯
样本效率高(假设强)低(假设弱)
鲁棒性差(假设错则崩)好
优化闭式解梯度下降/牛顿法

这个对比不是背下来的,而是从两者的推导里自然得出的。理解了这一点,你就能判断什么场景该用哪个。

3.3 SVM的对偶与核技巧:从优化到泛化

SVM是笔记里篇幅最长的一章,因为它同时涉及优化线和泛化线。核心逻辑链是:

  1. 原始问题:最大化间隔,等价于最小化 ( \frac{1}{2}|w|^2 ),约束是 ( y^{(i)}(w^Tx^{(i)}+b) \geq 1 )。
  2. 拉格朗日对偶:把约束优化转成对偶问题,发现最优解只依赖样本间的内积 ( \langle x^{(i)}, x^{(j)} \rangle )。
  3. 核技巧:把内积替换成核函数 ( K(x^{(i)}, x^{(j)}) ),隐式映射到高维空间。
  4. 软间隔:引入松弛变量和惩罚参数 C,处理线性不可分。

这里的关键洞察是:对偶形式让SVM的复杂度只取决于样本数,而不是特征维度。这就是为什么核技巧能work——你不需要显式计算高维映射,只需要计算核函数。我在笔记里补了一个手算例子,用二维数据演示核函数如何等价于高维内积,这个例子比纯公式直观得多。

实操心得:SMO算法的推导我建议至少手推一遍,尤其是启发式选择变量的部分。虽然实际用库函数时不需要自己实现,但理解SMO的收敛逻辑,对调参时判断“为什么模型不收敛”很有帮助。

3.4 EM算法:从混合高斯到一般框架

EM算法的笔记我改了三次。第一次按课程顺序写,先讲混合高斯再讲一般EM,结果读者看到一般形式时已经忘了具体例子。第二次反过来,先讲一般框架再套例子,又显得太抽象。最后采用的写法是:先用一个极简的“两枚硬币”例子讲清楚E步和M步在干什么,再推广到混合高斯,最后给出一般形式的推导。

E步的核心是计算隐变量的后验 ( Q_i(z^{(i)}) = p(z^{(i)}|x^{(i)};\theta) ),M步是最大化下界 ( \sum_i \sum_{z^{(i)}} Q_i(z^{(i)}) \log \frac{p(x^{(i)},z^{(i)};\theta)}{Q_i(z^{(i)})} )。这个下界的推导用到了Jensen不等式,我在笔记里把Jensen不等式的条件和等号成立条件都写清楚了,因为这是理解EM为什么能保证似然单调不减的关键。

4. 实操复现:怎么把笔记变成能跑的东西

4.1 环境与工具选择

笔记里的代码我全部用Python实现,依赖只有numpy和matplotlib,不引入sklearn,目的是强迫自己从零写一遍。环境配置很简单:

python -m venv ml-notes source ml-notes/bin/activate # Windows用 ml-notes\Scripts\activate pip install numpy matplotlib jupyter

为什么不用sklearn?因为调库会掩盖细节。比如逻辑回归的梯度下降,自己写一遍才会遇到学习率太大导致发散、太小导致收敛慢的问题,这些经验是调库学不到的。等你手写一遍之后,再用sklearn做对比验证,效果最好。

4.2 以逻辑回归为例的完整复现流程

我拿逻辑回归举例,说明笔记里的代码是怎么组织的。整个流程分四步:

第一步:生成数据。用numpy生成两类高斯分布的数据,注意设置随机种子保证可复现。

import numpy as np np.random.seed(42) n = 200 X_pos = np.random.randn(n//2, 2) + np.array([2, 2]) X_neg = np.random.randn(n//2, 2) + np.array([-2, -2]) X = np.vstack([X_pos, X_neg]) y = np.hstack([np.ones(n//2), np.zeros(n//2)]) X = np.hstack([np.ones((n, 1)), X]) # 加偏置项

第二步:定义sigmoid和损失函数。注意数值稳定性,sigmoid在输入很大或很小时会溢出,实际实现要clip。

def sigmoid(z): z = np.clip(z, -500, 500) return 1 / (1 + np.exp(-z)) def loss(theta, X, y): h = sigmoid(X @ theta) return -np.mean(y * np.log(h + 1e-9) + (1-y) * np.log(1-h + 1e-9))

第三步:梯度下降。这里的关键是学习率和迭代次数的选择。我实测下来,学习率0.1、迭代5000次在这个数据上比较稳。

def gradient_descent(X, y, lr=0.1, iters=5000): theta = np.zeros(X.shape[1]) losses = [] for i in range(iters): h = sigmoid(X @ theta) grad = X.T @ (h - y) / len(y) theta -= lr * grad losses.append(loss(theta, X, y)) return theta, losses

第四步:可视化决策边界。把损失曲线和决策边界画出来,直观验证收敛。

提示:梯度下降的收敛判断不要只看迭代次数,建议同时监控损失变化。如果连续100次迭代损失变化小于1e-6,就可以提前停止,省时间。

4.3 牛顿法与梯度下降的对比实验

笔记里我特意做了牛顿法和梯度下降的对比。牛顿法用Hessian矩阵,迭代次数少但每次计算量大;梯度下降每次计算量小但迭代次数多。在小数据集上,牛顿法通常10次以内收敛,梯度下降要几千次。但牛顿法的Hessian是 ( n \times n ) 的,特征维度高时内存吃不消。

方法迭代次数每次计算量适用场景
梯度下降多(千级)小(O(nd))高维、大数据
牛顿法少(十级)大(O(n³))低维、小数据

这个对比不是理论上的,是我实际跑出来的。你可以自己改代码验证,感受会很深。

4.4 从笔记到项目的迁移方法

笔记里的代码是教学性质的,离实际项目还有距离。我的迁移方法是:把每个算法封装成一个类,统一fit/predict接口。比如逻辑回归封装成:

class LogisticRegression: def __init__(self, lr=0.1, iters=5000): self.lr = lr self.iters = iters def fit(self, X, y): self.theta, self.losses = gradient_descent(X, y, self.lr, self.iters) def predict(self, X): return (sigmoid(X @ self.theta) > 0.5).astype(int)

这样封装之后,不同算法可以互换使用,方便做对比实验。这个习惯我从整理笔记一直保留到现在,实际工作中搭原型非常快。

5. 常见问题与排查技巧实录

5.1 推导卡壳了怎么办

这是整理笔记时最高频的问题。我的经验是:卡住的地方往往不是数学难,而是某个前置概念没吃透。比如推SVM对偶时卡住,大概率是拉格朗日对偶的KKT条件没理解;推EM时卡住,大概率是Jensen不等式不熟。这时候不要硬推,回头把前置概念补上,再回来往往就通了。

我整理了一个“卡壳排查表”:

卡壳位置可能缺失的前置知识
SVM对偶推导拉格朗日乘子法、KKT条件
EM下界推导Jensen不等式、凸函数定义
广义线性模型指数族分布、充分统计量
偏差方差分解期望的线性性、平方和分解
核技巧内积空间、Mercer定理

5.2 代码不收敛的排查思路

逻辑回归不收敛,按这个顺序查:

  1. 学习率太大:损失震荡或发散,调小10倍试试。
  2. 特征未归一化:不同量纲的特征导致梯度方向扭曲,做标准化。
  3. 数据线性不可分:逻辑回归本身无法完美分开,检查是否加了正则化。
  4. 标签编码错误:确认y是0/1而不是-1/1,sigmoid的输出范围是(0,1)。

我踩过最坑的一次是标签用了-1/1,结果损失函数一直不降,查了半天才发现。这个错误很隐蔽,因为代码不报错,只是结果不对。

5.3 笔记越写越乱的解法

写到中期你会发现,前面写的内容和后面矛盾,或者同一个符号在不同章节含义不同。我的解法是:维护一个符号表,所有章节统一引用。比如 ( \theta ) 始终表示参数,( x^{(i)} ) 始终表示第i个样本,( m ) 始终表示样本数。符号表放在笔记开头,写的时候随时对照。

另外,每写完一章,回头把前面相关章节的交叉引用补上。比如写完SVM,回头在逻辑回归那章加一句“与SVM的对比见第X章”。这样笔记才是一个整体,而不是一堆散篇。

5.4 复习时怎么用这份笔记

笔记写完不是终点,复习方法也很关键。我的用法是:先看目录回忆框架,再看公式自己推一遍,最后跑代码验证。如果某一步推不出来,标记下来重点突破。这样一轮复习大概两小时,比从头看视频快得多。

实操心得:我建议把笔记导出成PDF,在平板上手写批注。电子笔记方便搜索,但手写批注能加深记忆。两者结合效果最好。

6. 学习理论部分:最容易被跳过但最重要的一章

6.1 偏差方差分解的直观理解

很多人学到这里就跳过了,觉得太理论。但偏差方差分解是理解过拟合欠拟合的基石。核心公式是:

[ E[(y - \hat{f}(x))^2] = \text{Bias}^2 + \text{Variance} + \text{Noise} ]

偏差是模型预测的期望与真实值的差距,方差是模型预测的波动。高偏差对应欠拟合,高方差对应过拟合。我在笔记里用了一个多项式回归的例子,从一次到十次,画出训练误差和测试误差的曲线,直观展示偏差方差的变化。

这个分解的实用价值在于:当你调模型时,先判断是偏差问题还是方差问题,再决定加特征还是加正则化。加特征降低偏差但增加方差,加正则化降低方差但增加偏差。方向搞反了,越调越差。

6.2 VC维与模型容量

VC维衡量的是模型能打散的最大样本数。线性分类器在二维空间的VC维是3,在n维空间是n+1。这个结论的推导用到了打散的概念,我在笔记里用二维平面的三个点举例,说明为什么线性分类器能打散3个点但不能打散4个点。

VC维的实用意义是:它给出了泛化误差的上界,与模型复杂度和样本数有关。样本数越多,泛化误差上界越紧。这解释了为什么大数据能救复杂模型。

6.3 正则化的统一视角

L1和L2正则化从贝叶斯角度看,分别是拉普拉斯先验和高斯先验的最大后验估计。这个视角统一了正则化和概率模型,我在笔记里把推导写了一遍。L1产生稀疏解是因为拉普拉斯分布在零点有尖峰,L2则是平滑的。

正则化先验分布解的特性适用场景
L1拉普拉斯稀疏特征选择
L2高斯平滑防止过拟合

这个表格是我从推导里总结的,不是背的。理解了先验,你就能自己判断什么场景用哪个。

7. 强化学习入门:笔记的最后一公里

7.1 从监督学习到强化学习的思维转变

强化学习和监督学习最大的区别是:没有标签,只有奖励。监督学习告诉你“这个输入对应这个输出”,强化学习只告诉你“这个动作得了多少分”,你需要自己探索哪些动作是好的。这个转变我花了挺久才适应。

笔记里我用网格世界举例,状态是格子位置,动作是上下左右,奖励是到达终点的正分和每步的负分。这个例子足够简单,能手动算出最优策略,适合入门。

7.2 值迭代与策略迭代

值迭代和策略迭代是强化学习的基础算法。值迭代直接迭代值函数,策略迭代交替评估策略和改进策略。两者都能收敛到最优策略,但值迭代每次迭代计算量小,策略迭代收敛快。

我在笔记里把两者的伪代码都写了一遍,并在网格世界上跑出结果对比。实测下来,小网格上策略迭代5轮收敛,值迭代要20轮,但每轮计算量小。这个对比帮助理解两者的取舍。

7.3 MDP的贝尔曼方程

贝尔曼方程是强化学习的核心,形式是:

[ V(s) = \max_a \left[ R(s,a) + \gamma \sum_{s'} P(s'|s,a) V(s') \right] ]

这个方程的含义是:当前状态的价值等于即时奖励加上折扣后的未来价值。我在笔记里用网格世界手算了一遍,把每个格子的价值迭代过程写出来,比纯公式直观得多。

注意:折扣因子 ( \gamma ) 的选择很关键。( \gamma ) 接近1时模型更看重长期奖励,接近0时更短视。实际调参时,( \gamma ) 通常取0.9到0.99之间。

8. 整理笔记的元技巧:怎么让这件事可持续

8.1 时间管理:每天固定一小时

整理笔记最大的敌人是拖延。我的做法是每天固定一小时,雷打不动。这一小时不追求进度,只追求“今天比昨天多懂一点”。这样坚持下来,比周末突击一整天效果好得多。因为理解需要时间沉淀,突击只能堆量,不能内化。

8.2 输出倒逼输入

我的笔记不是看完再写,而是边看边写。看完一个知识点,立刻用自己的话复述一遍,写不出来说明没懂。这个“输出倒逼输入”的方法,比被动看视频效率高很多。我试过纯看视频,一周后忘得差不多;边看边写,一个月后还能回忆起框架。

8.3 建立自己的例子库

课程里的例子不一定适合你。我在笔记里替换了很多例子,用自己熟悉的数据。比如讲聚类时,我用的是自己整理的读书笔记标签数据,而不是课程里的鸢尾花。用自己的数据,理解会深很多,因为你知道每个簇代表什么。

8.4 定期回顾与修订

笔记不是写完就完了。我每隔一个月会回头翻一遍,把当时没写清楚的地方补上,把过时的代码更新。这个习惯让笔记一直保持“活”的状态,而不是写完就吃灰。最近这次完结,其实就是第三轮修订的结果。

9. 这份笔记后续还能怎么扩展

笔记完结不代表学习结束。我接下来打算做两件事:一是把深度学习部分补上,从反向传播到简单的CNN,保持同样的推导风格;二是把代码整理成一个开源仓库,加上单元测试和文档,方便别人直接跑。如果你也在整理自己的笔记,我建议不要追求一次完美,先写完再迭代。第一版粗糙没关系,重要的是把框架搭起来,后面慢慢填。

最后分享一个小技巧:整理笔记时,把“我懂了”和“我以为我懂了”分开标记。前者是能自己推一遍的,后者是看别人推觉得懂的。复习时重点攻克后者,效率最高。这个习惯帮我省了大量时间,也避免了很多“一看就会一做就废”的尴尬。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 15:55:25

2026年必看:六款热门AI编程工具横评,TaoToken统一Key接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 15:54:31

门诊清洁消毒记录表设计:从填表工具到感控执行中枢

简介:本资源是一份专为医疗机构门诊科室设计的标准化清洁与消毒记录表,面向医院感控管理人员、门诊护士长、院感科专员及基层医疗机构消毒操作人员,用于规范落实日常环境消毒流程、规避交叉感染风险并满足院感检查台账要求。文档为单个Word文…

作者头像 李华
网站建设 2026/10/10 15:49:07

Library cache lock 常见案例分析(二):从 AWR 到 TaoToken 的排查路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 15:46:55

Windows装机效率双件套:全盘文件搜索与无需U盘的系统重装

装机和找文件这两件高频小事,工具选对能省一半时间。记录两个 Windows 小工具的用法:全盘文件搜索 无需 U 盘的系统重装。 一、两个工具解决什么问题 文件搜索:输入即出结果,全盘文件秒级命中,比系统自带搜索快一个…

作者头像 李华