📑 本页目录(点开跳转)
01 · 最大似然:最小二乘的真身
⏱ 28 分钟 | ⭐⭐ 一把钥匙开一堆锁
🎯 一句话
最大似然(MLE)= 挑一组参数,让「你实际看到的这批数据」发生的概率最大。 它是一个原则,不是一个算法——而机器学习里几乎所有损失函数,都是它推出来的。
🧠 一、先建立直觉
你捡到一枚硬币,抛 10 次,8 次正面。
问:这枚硬币正面朝上的概率 p 是多少?
你脱口而出:0.8
⭐ 但你有没有想过,你凭什么这么答?
你其实做了这样一件事:
| 假设 p 是 | 出现「10次里8次正面」的概率 |
|---|---|
| 0.5 | 4.4% |
| 0.7 | 23.4% |
| 0.8 | 30.2% ⭐ 最大 |
| 0.9 | 19.4% |
→ 挑那个让"我看到的数据"最可能发生的 p
💡 这就是最大似然的全部思想:
不问「真相是什么」,只问「哪个假设最能解释我看到的东西」。
⚠️ 一个必须分清的概念
似然 L(θ) = p(数据 | 参数) ← 参数已知,问数据出现的概率
后验 p(参数 | 数据) ← 数据已知,问参数的概率
⭐ 它们【不是】一回事,方向是反的
MLE 最大化的是【似然】;下一章的 MAP 才涉及后验
为什么这个区分重要:似然不是概率分布(对 θ 积分不等于 1), 所以「p=0.8 的似然是 30.2%」不能读成「p 是 0.8 的概率有 30.2%」。
📐 二、数学形式
给定数据 $D = \{x_1,...,x_n\}$ 和参数 $\theta$:
$$\hat\theta_{MLE} = \arg\max_\theta \; \underbrace{p(D \mid \theta)}_{\text{似然}} = \arg\max_\theta \prod_{i=1}^n p(x_i\mid\theta)$$
💡 人话:把每个样本出现的概率乘起来(假设样本独立),挑让这个乘积最大的 θ。
实践中都取对数:
$$\hat\theta = \arg\max_\theta \sum_{i=1}^n \log p(x_i\mid\theta)$$
取对数的三个理由:
| 理由 | 说明 |
|---|---|
| 防数值下溢 ⭐ | 1000 个 0.5 相乘 = 10⁻³⁰¹,浮点数直接变 0 |
| 连乘变连加 | 求导容易得多 |
| 不改变最优解 | log 是单调递增的 |
🔑 注意这个转换:
最大化对数似然=最小化负对数似然。 而「负对数似然」就是你天天在用的损失函数。 下面是证据。
⭐ 三、高光时刻:最小二乘 = 高斯噪声下的 MLE
这是本章最重要的推导。 你一直在用平方误差,但为什么是平方?
建模假设
真实世界:y = w·x + ε
↑ 噪声,假设 ε ~ N(0, σ²)
换句话说:给定 x,y 的分布是以 w·x 为中心的钟形曲线
y | x ~ N(w·x, σ²)
y ▲ ╱ 真实直线 w·x
│ ╱ ╱▔╲ ← 每个 x 处,y 在这条线上下呈钟形分布
│ ╱ ╲_╱
│ ╱
└──────────► x
📐 推导(想看再点,不看不影响)
单个样本的概率密度:
$$p(y_i\mid x_i,w) = \frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{(y_i - w^\top x_i)^2}{2\sigma^2}\right)$$
对数似然:
$$\log L(w) = \sum_i \log p(y_i\mid x_i,w) = \underbrace{-\frac{n}{2}\log(2\pi\sigma^2)}_{\text{和 } w \text{ 无关,是常数}} - \frac{1}{2\sigma^2}\sum_i (y_i - w^\top x_i)^2$$
最大化它 ⟺ 最小化后面那一项 ⟺
$$\boxed{\hat w = \arg\min_w \sum_i (y_i - w^\top x_i)^2}$$
这正是最小二乘。
💡 结论(不看推导也要记住这句)
你用平方误差,等价于你假设了「噪声服从正态分布」。 不是因为平方"好算",而是因为高斯密度函数的指数上就是平方项。
这个认知的三个实践含义:
| 含义 | 说明 |
|---|---|
| 有离群值时平方误差会崩 ⭐ | 高斯分布尾巴薄,认为极端值"几乎不可能出现",于是模型被迫为了迁就一个离群点而扭曲整条线 |
| 改用 L1 损失 = 改变噪声假设 | L1(绝对值误差)对应拉普拉斯分布——尾巴更厚,天然抗离群值 |
| 选损失函数 = 选你对噪声的信念 | 这不是玄学,是可以推导的 |
🔬 一个能亲眼看到的实验
import numpy as np
from sklearn.linear_model import LinearRegression, HuberRegressor
rng = np.random.RandomState(0)
X = np.linspace(0, 10, 50).reshape(-1, 1)
y = 2 * X.ravel() + 1 + rng.randn(50) * 0.5 # 真实斜率 = 2
y[45] = 100 # ⭐ 加一个离群点
print("最小二乘斜率:", LinearRegression().fit(X, y).coef_[0]) # 会被拽歪
print("Huber 斜率: ", HuberRegressor().fit(X, y).coef_[0]) # 基本不动
一个点就能把最小二乘拽歪——因为高斯假设认为"这不可能发生", 模型只好大幅调整参数来"解释"它。
🎲 四、第二个例子:交叉熵 = 伯努利分布下的 MLE
分类任务里你用交叉熵。它也是 MLE 推出来的:
建模:y | x ~ Bernoulli(p),其中 p = σ(w·x)
(给定 x,y 是 0 或 1,正类概率是 p)
单样本似然:p(y|x) = p^y · (1−p)^(1−y)
↑ y=1 时取 p,y=0 时取 1−p,一个式子搞定
取对数:log p(y|x) = y·log p + (1−y)·log(1−p)
取负、求和 → 交叉熵损失 ✅
🔗 你在基础教程第 3 章学的 「分类要用交叉熵不用 MSE」——根因在这: 分类的输出服从伯努利分布而不是高斯分布,用错分布假设就用错了损失。
⭐ 这里还藏着一件更大的事,本章先不展开: "交叉熵"这个名字里的熵是信息论的词。它不是随手挑的一个"衡量两个分布差多远"的量 —— 最大化似然、最小化交叉熵、最小化 KL 散度,其实是同一件事的三种说法。 下一节 01b · KL 散度 把这三者接起来,顺便给 KL 一个正式定义 (这套教程从 PPO 到 RLHF 到蒸馏一共用了它六次,却从没定义过)。
📋 五、损失函数速查:每一个背后的分布假设
| 损失函数 | 隐含的分布 | 什么时候用 |
|---|---|---|
| 平方误差 MSE | 高斯 | 回归,噪声对称且无重离群值 |
| 绝对值误差 L1 / MAE | 拉普拉斯 | 回归,有离群值 |
| Huber | 高斯+拉普拉斯混合 | 想兼顾两者(小误差用平方,大误差用线性) |
| 交叉熵 | 伯努利 / 类别分布 | 分类 |
| 泊松损失 | 泊松 | 计数数据(点击数、访问量、事故数) |
| 负二项损失 | 负二项 | 计数数据但方差 > 均值(过离散) |
| 分位数损失 | 非对称拉普拉斯 | 只关心某个分位数(如预测 90 分位) |
🔑 拿到一个新任务时,问自己:我的输出是什么类型的随机变量? 答案直接告诉你该用哪个损失函数。
💡 一个常见错误:用 MSE 预测"点击数"这类计数数据。 计数是非负整数且方差随均值增长,高斯假设明显不对——该用泊松损失。
⚠️ 六、MLE 的三个毛病
毛病 1:数据少时会过拟合
抛硬币 3 次,全是正面 → MLE 说 p = 1.0
↑ 「这枚硬币永远不会出反面」
显然荒谬。但 MLE 没办法——它只看数据,不带任何先验常识。
毛病 2:没有不确定性
MLE 给你一个点估计,但不告诉你这个估计有多可靠。 抛 10 次得 0.8 和抛 10000 次得 0.8,MLE 的输出一模一样。
毛病 3:对模型设定错误很敏感
MLE 只保证「在你假设的分布族里,这是最好的参数」
它【不检查】你的分布假设本身对不对
→ 假设错了(比如数据其实是重尾的却假设高斯)
→ MLE 会自信地给出一个错误答案
🔑 前两个毛病的解药是同一个:加入先验。 这就是下一章的 MAP。 第三个毛病的解药是模型检验(看残差分布、做敏感性分析)。
🔗 七、和站内其他章的关系
| 相关的地方 | 根因在这 |
|---|---|
| 回归用 MSE、分类用交叉熵 | 对应高斯 / 伯努利分布假设 |
| 有离群值改用 L1 或 Huber | 换一个尾巴更厚的分布假设 |
| 基础教程第 3 章「分类不用 MSE」 | 用错了分布 |
基础教程第 15 章的 BCEWithLogitsLoss |
伯努利 MLE 的数值稳定实现 |
| 推荐算法第 5 章 MF 的目标函数 | 平方误差 = 高斯噪声假设 |
| 推荐算法的 BPR 损失 | 另一种概率建模(对"排序对"建模) |
✅ 检查点
- 最大似然在问什么问题?它和「求真相」有什么区别?
- 似然和后验的区别是什么?为什么不能说「p=0.8 的概率是 30.2%」?
- 取对数的三个理由?
- 为什么最小二乘用平方而不是别的?
- 有离群值时平方误差为什么会崩?该换成什么?
- 预测"每天的点击数"该用什么损失?为什么不用 MSE?
- MLE 的三个毛病是什么?
👀 答案
- 问「哪组参数让我实际看到的这批数据最可能发生」。它不问真相是什么,只挑最能解释观测的假设。
- 似然 = p(数据|参数),后验 = p(参数|数据),方向相反。似然不是关于 θ 的概率分布(积分不等于 1),所以不能读成"θ 是某值的概率"。
- 防数值下溢(连乘会变 0)、连乘变连加便于求导、log 单调不改变最优解。
- 因为假设了噪声服从正态分布,而高斯密度的指数上正好是平方项。最大化对数似然 ⟺ 最小化平方和。
- 高斯分布尾巴薄,认为极端值几乎不可能出现,所以模型会大幅扭曲参数去"解释"那个离群点。换 L1(拉普拉斯,尾巴厚)或 Huber。
- 泊松损失。计数数据是非负整数且方差随均值增长,高斯假设(对称、方差恒定、可取负值)明显不成立。
- ①数据少时过拟合(3次全正说 p=1)②只给点估计无不确定性 ③对分布假设错误敏感,且不会自我检查。
🛑 可以停在这里
⚡ 走神救援
MLE = 挑一组参数,让「你看到的这批数据」发生的概率最大——不问真相,只问哪个假设最能解释观测。抛 10 次得 8 次正面:p=0.5 时这批数据只有 4.4% 的概率出现,p=0.8 时最大,30.2%。⚠️似然 p(数据|参数) 和后验 p(参数|数据) 方向相反,而且似然不是概率分布(对 θ 积分不等于 1)——「似然 30.2%」不能读成「p 是 0.8 的概率有 30.2%」。取对数三个理由:防下溢(1000 个 0.5 相乘 = 10⁻³⁰¹,浮点数直接变 0)、连乘变连加、log 单调不改最优解。⭐最大化对数似然 = 最小化负对数似然 = 你天天在用的损失函数。两条核心结论:最小二乘 = 假设噪声服从高斯(y|x ~ N(w·x, σ²),高斯密度的指数上就是平方项),交叉熵 = 假设服从伯努利(似然 p^y·(1−p)^(1−y) 取对数求和取负)。所以选损失函数 = 选你对噪声的信念。⚠️有离群值时平方误差会崩:高斯尾巴薄,认为极端值「几乎不可能出现」,模型只好扭曲整条线迁就它——一个离群点就能把最小二乘的斜率拽歪,Huber 却基本不动;换尾巴更厚的 L1(拉普拉斯)或 Huber。⚠️另一个高频错误是用 MSE 预测点击数——计数是非负整数且方差随均值增长,高斯假设不对,该用泊松损失。拿到新任务先问:输出是什么类型的随机变量,答案直接给出损失。MLE 三个毛病:①数据少时过拟合(抛 3 次全正就说 p=1.0)②只给点估计、不带不确定性(抛 10 次得 0.8 和抛 10000 次得 0.8,输出一样)③对模型设定错误敏感,只保证「在你假设的分布族里最好」,并不检查假设本身对不对。⭐前两个毛病的解药是同一个——加入先验,就是下一章的 MAP;第三个靠模型检验。
下一节 👉 01b-KL散度.md
去那里的理由:本章说"交叉熵是伯努利分布下的 MLE",但没说为什么"交叉熵"这个信息论的量会出现在统计问题里。 01b 证明 最大似然一直在最小化 KL 散度,只是这一章没点破 —— 并且把 KL 这个后面四个板块都在用、却从没定义过的东西,正式定义下来。 ⚠️ 只想尽快拿到「正则化 = 先验」那个结论的话,也可以先跳到 02-MAP与正则化的真身.md ⭐⭐⭐,回头再补 01b —— 02 不依赖 KL。