读完这一课,你将能够
- 说清随机变量 \(X\)、PMF \(p(x)\)、PDF \(f(x)\)、CDF \(F(x)\) 各自描述什么,并指出"PDF 的值不是概率、可以大于 1、单点概率为 0"。
- 用 \(\mathbb{E}[X]=\sum_x x\,p(x)\) 或 \(\int x f(x)\,dx\) 手算期望,并把它解释成"长期平均 / 分布的质心"。
- 运用期望的线性性 \(\mathbb{E}[aX+bY]=a\mathbb{E}[X]+b\mathbb{E}[Y]\)(即便 \(X,Y\) 相关),并辨认 \(\mathbb{E}[g(X)]\neq g(\mathbb{E}[X])\) 的陷阱。
- 用 \(\mathrm{Var}(X)=\mathbb{E}[X^2]-\mu^2\) 算方差、复核标准差,并说出方差刻画"分布的胖瘦"。
- 写出离散分布的 CDF 阶梯,说明 \(F(x)=P(X\le x)\) 单调地从 0 爬到 1,并知道连续情形下 \(F'(x)=f(x)\)。
- 写出蒙特卡洛估计:用样本平均近似期望,并说清它为什么是无偏的、为什么 \(n\) 越大越准——以及它和 SGD 梯度估计是同一个思想。
模块 1 里,我们用线性代数把世界写成"确定的"向量与变换:给定输入,输出唯一。但真实数据从来不是这样——传感器有噪声、样本是随机抽到的、模型对世界总有"不知道"的部分。从这一课起,我们给世界加入不确定性,而描述不确定性的语言就是概率 probability。这一课先把最基础的四个词——随机变量、分布、期望、方差——讲透,它们是后面最大似然、信息论、以及训练用的 SGD 全部建立其上的地基。这些更高层的名词现在不必懂,只需知道它们都是从这四个词长出来的。
为什么机器学习离不开概率
先别急着背定义,问一个更前置的问题:ML 为什么非用概率不可?答案是,ML 要处理的每一处"不确定"都得有语言来量化它。
- 数据有噪声。同一张猫的照片,光照、压缩、标注员的手抖都会让像素值抖动。我们不说"这个像素是 137",而说"它在 137 附近以某种概率分布"。
- 数据是采样来的。训练集只是从真实世界这口大锅里舀出的一小勺。模型在这一勺上学到的东西,能不能推广到整锅?这是"采样 sampling"带来的随机性,要用概率回答。
- 模型对世界"不知道"。一个好的分类器输出的不是"这是猫",而是"90% 是猫、8% 是狗、2% 是其它"。这个 90% 是模型给出的一个概率化猜测——它把不确定性显式写了出来,而不是硬给一个非黑即白的答案。
一句话直觉:线性代数回答"给定输入,输出是什么";概率回答"给定输入,输出大概是什么、有多大把握"。ML 的全部训练目标,几乎都可以写成"让模型给出的概率分布尽量贴近数据的真实分布"——这就是为什么这门语言绕不开。
样本空间、事件、随机变量:把"随机结果"映成数
掷一颗骰子,可能的结果有 6 种:\(\{1,2,3,4,5,6\}\)。这个"所有可能结果的集合"叫样本空间 sample space,记作 \(\Omega\)。其中某一类结果(比如"掷出偶数" \(\{2,4,6\}\))叫一个事件 event,事件发生的可能性大小就是它的概率 \(P(\cdot)\)。
但样本空间里的结果不一定是数字——抛硬币得到的是"正/反",抽卡得到的是"金/紫/蓝"。为了能算、能比较、能放进公式,我们需要一座桥:把每个随机结果映射成一个数。这座桥就是随机变量 random variable,习惯用大写 \(X\) 表示,它取到的具体数值用小写 \(x\)。
纠正一个常见误解:随机变量既不"随机"也不是"变量",它其实是一个函数——输入是样本空间里的某个结果 \(\omega\),输出是一个实数 \(X(\omega)\)。比如抛两枚硬币,令 \(X=\) 正面个数,那么 \(X(\text{正正})=2,\ X(\text{正反})=1,\ X(\text{反反})=0\)。一旦把结果翻译成数,我们就能问"\(X\) 平均是多少""\(X\) 波动多大"这类定量问题。
离散 vs 连续
随机变量按取值方式分两类,这个区分会一路贯穿全课:
- 离散 discrete:取值是可以一个个数清的(骰子点数 \(\{1,\dots,6\}\)、邮件里"垃圾/正常"、一句话里的词)。
- 连续 continuous:取值充满一整段实数区间(身高、温度、神经网络某个权重)。在任意小区间里都塞着无穷多个可能值。
"能不能数清"决定了我们用求和 \(\sum\) 还是积分 \(\int\) 来描述它,也决定了下面 PMF 和 PDF 的分野。
PMF 与 PDF:分布是什么
知道了 \(X\) 能取哪些值还不够,我们还想知道每个值有多大可能——这套"哪个值多大可能"的完整说明书,就叫 \(X\) 的分布 distribution。离散和连续各有一种说明书格式。
离散:概率质量函数 PMF
对离散变量,直接给每个可能取值分配一份概率,这个函数叫概率质量函数 probability mass function(PMF),记 \(p(x)=P(X=x)\)。它必须满足两条铁律:
\[ p(x)\in[0,1]\quad\text{(每份概率在 0 和 1 之间)},\qquad \sum_x p(x)=1\quad\text{(所有份加起来正好是 1)}.\]"质量 mass"这个词很形象:想象你有 1 单位的"概率泥巴",把它捏成几块、按重要性分配到各个取值上。公平骰子就是把这团泥巴均分成 6 块,每块 \(\tfrac16\)。
连续:概率密度函数 PDF
连续变量麻烦在哪?取值有无穷多个。如果给每个具体值都分一份正概率,那"无穷多个正数加起来"就会爆掉,超过 1。所以连续情形下,问"\(X\) 恰好等于 3.0000…"是没意义的——答案是 0。我们改问区间:"\(X\) 落在 \([3,3.1]\) 之间的概率多大",这才有意义。
描述连续分布的说明书叫概率密度函数 probability density function(PDF),记 \(f(x)\)。它不直接给概率,而给"概率的密度"——某点附近概率有多密集。真正的概率要靠积分(求面积)得到:
\[ P(a\le X\le b)=\int_a^b f(x)\,dx,\qquad f(x)\ge 0,\qquad \int_{-\infty}^{\infty} f(x)\,dx=1.\]易错:PDF 的值不是概率!
这是初学者最大的坑。请把下面三条钉死:
- PDF 的值 \(f(x)\) 本身不是概率,它是"密度",单位是"概率 / 单位长度"。只有把它在一段区间上积分(求面积)才得到概率。
- \(f(x)\) 可以大于 1。例如在 \([0,0.5]\) 上均匀分布,密度处处为 \(1/0.5=2>1\),完全合法——因为底乘高 \(=0.5\times2=1\),面积才是概率。密度高不等于概率大于 1。
- 连续变量单点概率为 0:\(P(X=c)=\int_c^c f=0\)。线宽为零的竖线下面积是 0。所以对连续变量 \(P(X\le 3)\) 和 \(P(X<3)\) 一模一样。
上面用的是最平的均匀分布(密度是条水平线,"面积"退化成"底×高"),但你脑子里得有一条会起伏的曲线:比如钟形的高斯密度,中间高、两边低。某一段的概率仍然是那段曲线下的面积;峰值处密度最大,但"峰值那一点的概率"照样是 0(单点概率永远为 0)。高斯的公式留到下一课,这里只要让"面积=概率"在一条起伏的曲线上被想象一次,免得把"密度=常数"当成默认锚点。
一句话记住区别:PMF 的高度就是概率(柱子高度直接读数);PDF 的面积才是概率(曲线下方一块面积才是概率,高度只是密度)。
累积分布函数 CDF:一个统一的视角
无论离散还是连续,有一个函数都能用,叫累积分布函数 cumulative distribution function(CDF):
\[ F(x)=P(X\le x).\]它回答"\(X\) 不超过 \(x\) 的概率是多少",是把概率从左往右一路累加 / 累积。它从 0 单调爬升到 1,永不下降。CDF 的好处是统一:离散时它是一条阶梯(每遇到一个取值就往上跳一格,跳的高度正是该点的 \(p(x)\));连续时它是一条光滑上升的曲线,而且它的斜率就是密度:\(F'(x)=f(x)\)。反过来,区间概率就是 CDF 的差:\(P(a 记不清 PDF 和 CDF 谁是谁时,记住这句:CDF 是 PDF 的"面积累加版",PDF 是 CDF 的"斜率版"——它们是积分与求导的一对,正好接上模块 1 的微积分。 有了分布,第一个想问的总结量是:"这个随机变量平均是多少?"这就是期望 expectation,记 \(\mathbb{E}[X]\),也常写成 \(\mu\)。定义是"取值按概率加权求和 / 积分": 连续情形为什么也是这个式子?别把它当成"把 \(\sum\) 换成 \(\int\)、把 \(p(x)\) 换成 \(f(x)\,dx\)"的死记。关键在 \(f(x)\,dx\):回想 PDF 要乘上一小段宽度才成概率,\(f(x)\,dx\) 恰好就是 \(X\) 落在 \([x,x+dx]\) 这一小片里的概率质量。于是 \(\int x\cdot f(x)\,dx\) 和离散的 \(\sum x\cdot p(x)\) 干的是同一件事——把每个取值乘上"它那一份概率"再累加,只不过取值连成一片,求和升级成了积分。 它有三个等价直觉,挑你最顺的记: 取值 \(x\in\{1,2,3,4,5,6\}\),每个 \(p(x)=\tfrac16\)。 注意 3.5 本身不是骰子能掷出的点数——期望是"平衡点",不必是可能取值。 (1) 线性性 linearity(最常用、最强大): 这条性质强在哪?它不要求 \(X,Y\) 独立,甚至不要求它们不相关——只要期望存在,永远成立。直觉上,求和与求平均都是"线性"操作,可以先各自平均再相加,顺序无所谓。后面你会无数次用它把一个复杂的求和拆成一项项的平均(比如把一个 batch 的损失拆成每个样本损失的平均)。 线性性只对"线性"的 \(g\)(即 \(aX+b\) 这种)成立。对非线性的 \(g\),"先变换再平均"和"先平均再变换"通常给出不同结果。用骰子验证 \(g(x)=x^2\): 两者差了 2.92,绝不相等。一般地,对凸函数 \(g\) 总有 \(\mathbb{E}[g(X)]\ge g(\mathbb{E}[X])\)——这就是Jensen 不等式,下一模块讲信息论和 ELBO 时会正式登场。 这个坑在 ML 里随处可见。举个例子:集成(ensemble)多个分类器时,正确做法是先各自 softmax 出概率、再把概率平均;如果图省事先把各模型的 logits 平均、再 softmax,结果是不一样的——因为 softmax 是非线性的,"先平均再变换"不等于"先变换再平均"。记住:非线性变换不能随便把期望往里塞。 期望告诉你分布的中心在哪,但两个分布可以中心一样、胖瘦完全不同:一个紧紧挤在均值附近,一个铺得很开。刻画"铺多开 / 波动多大"的量就是方差 variance。 怎么量化波动?很自然地想看"每个取值离均值有多远",即偏差 \(X-\mu\)。但直接平均偏差会得到 0(正负相消,因为均值就是平衡点)。所以我们先平方再平均——平方消掉符号、且放大大偏差: 实战中更好用的是它的等价展开式("平方的期望减去期望的平方"): 推导一行:\(\mathbb{E}[(X-\mu)^2]=\mathbb{E}[X^2-2\mu X+\mu^2]=\mathbb{E}[X^2]-2\mu\mathbb{E}[X]+\mu^2=\mathbb{E}[X^2]-\mu^2\)(用了线性性,且 \(\mu\) 是常数)。这个式子只要算 \(\mathbb{E}[X^2]\) 和 \(\mathbb{E}[X]\) 两个量就行,特别省事。 方差的单位是"原单位的平方"(比如米²),不好直观比较,所以常开方还原回原单位,得到标准差 standard deviation \(\sigma=\sqrt{\mathrm{Var}(X)}\)。标准差就是"典型偏离均值多远"的尺度。 已知 \(\mu=\mathbb{E}[X]=3.5\)。先算 \(\mathbb{E}[X^2]\): 标准差 \(\sigma=\sqrt{35/12}\approx1.708\)。用定义式复核:偏差平方按概率加权,\(\tfrac16\big[(1{-}3.5)^2+\dots+(6{-}3.5)^2\big]=\tfrac16(6.25+2.25+0.25+0.25+2.25+6.25)=\tfrac{17.5}{6}=2.9167\) ✓,两条路殊途同归。 设 \(X\in\{0,1,2,3\}\),\(p=(0.1,\,0.2,\,0.4,\,0.3)\)(先验证 \(\sum p=1\) ✓)。 定义式复核:\(\sum (x-1.9)^2 p(x)=0.361+0.162+0.004+0.363=0.89\) ✓。 到目前为止我们都在"知道分布、算期望"。但真实 ML 里恰恰反过来:我们不知道真实分布的解析式,只能采样——拿到一堆样本 \(x_1,\dots,x_n\)。这时怎么估计期望?最朴素、也最强大的办法是直接用样本的算术平均去近似: 这就是蒙特卡洛估计 Monte Carlo estimation。它凭什么管用?两条腿撑着: 训练神经网络时,真正想最小化的是整个训练集上的平均损失(经验风险),它的梯度是 \(\nabla L=\frac1N\sum_{x}\nabla \ell(x)\),也可以写成在训练集上取期望 \(\mathbb{E}_{x\sim\text{训练集}}[\nabla \ell(x)]\)——一个期望。但数据动辄上亿条,每步都算全量梯度太贵。随机梯度下降(SGD)的做法是:每步随机抽一个小批量(mini-batch),用这批样本的平均梯度 \(\frac1B\sum_i\nabla\ell(x_i)\) 代替真梯度。 看出来了吗?这正是蒙特卡洛估计,只不过被估计的随机变量是"梯度"。只要每个 mini-batch 是从训练集均匀随机抽取的,由期望的线性性,小批量梯度就是"整个训练集上真梯度"的无偏估计:平均而言方向是对的,只是带噪声。注意"无偏"是相对训练集这个经验平均而言的,不是相对世界的真实分布——后者牵扯到泛化,是另一个话题。batch 越大,由 \(\sigma/\sqrt{B}\) 知噪声越小、但每步越贵——这正是炼丹时 batch size 取舍的数学本质。本课埋的这个点,到模块的最优化部分会完整展开。 运行会看到:误差随 \(n\) 增大而整体缩小(但不是单调,因为是随机的),到千万级时 \(E\) 已稳在 3.50 附近、\(Var\) 稳在 2.917 附近。这就是大数定律在你眼前发生。 把上面的思路改一个数、跑一遍,用眼睛确认理论。每个实验都先想"预期看到什么",再运行验证。 改什么:固定骰子分布,对每个 \(n\in\{100,400,1600\}\),重复 2000 次实验各算一个样本均值,再看这 2000 个均值自己的标准差。 改什么:造一对完全相关的变量:掷骰子得 \(X\),令 \(Y=2-X\)(\(Y\) 被 \(X\) 完全决定)。分别估计 \(\mathbb{E}[X]+\mathbb{E}[Y]\) 和 \(\mathbb{E}[X+Y]\)。 改什么:取 \(g(x)=x^2\),分别估计"先平方再平均" \(\mathbb{E}[X^2]\) 与"先平均再平方" \((\mathbb{E}[X])^2\)。 下一课,我们把这套语言"装满弹药":认识 ML 最常用的几种具体分布(伯努利、二项、高斯、类别分布等),看它们各自适合刻画什么数据;并把协方差 \(\mathrm{Cov}(X,Y)\) 推广到多维,接回模块 1 第 4 课——你会看到协方差矩阵对称半正定、可以特征分解,它的特征向量正是数据散布的主轴(PCA 的种子)。期望 \(\mathbb{E}[X]\):分布的质心
例题:公平骰子的期望
期望的两条核心性质
易错:\(\mathbb{E}[g(X)]\neq g(\mathbb{E}[X])\)
方差 \(\mathrm{Var}(X)\):分布的胖瘦
例题:骰子的方差(用 \(\mathbb{E}[X^2]-\mu^2\) 复核)
例题:一个非均匀离散分布的 E 与 Var
蒙特卡洛估计:用样本平均近似期望
ML 和 ML 的联系:SGD 的梯度是真梯度的无偏估计
代码:用 numpy 采样估计骰子的 E 与 Var,并看 n 增大变准
import numpy as np
rng = np.random.default_rng(0)
# 理论值
E_true, Var_true = 3.5, 35/12
print("理论: E[X]=%.4f Var=%.4f" % (E_true, Var_true))
# 不同样本量下的蒙特卡洛估计
for n in [100, 1_000, 100_000, 10_000_000]:
s = rng.integers(1, 7, size=n) # 公平骰子的 n 次采样
E_hat = s.mean() # 样本均值 ≈ E[X]
Var_hat = s.var() # 样本方差 ≈ Var(X)
print("n=%-9d E_hat=%.4f (误差%.4f) Var_hat=%.4f (误差%.4f)"
% (n, E_hat, abs(E_hat-E_true), Var_hat, abs(Var_hat-Var_true)))
调一调,观察现象
实验 1:样本量翻 4 倍,估计波动减半(√n 律)
预期看到:波动随 \(n\) 增大而收窄,且大致是 \(\sigma/\sqrt n\):约 0.17、0.085、0.043——每次 \(n\) 翻 4 倍,波动减半。
为什么:样本均值的标准差是 \(\sigma/\sqrt n\)(\(\sigma=\sqrt{35/12}\approx1.708\)),分母里是 \(\sqrt n\) 而非 \(n\),所以要让精度翻倍得付出 4 倍样本——蒙特卡洛"回报递减"的根源。import numpy as np
rng = np.random.default_rng(1)
sigma = np.sqrt(35/12)
for n in [100, 400, 1600]:
means = [rng.integers(1,7,size=n).mean() for _ in range(2000)]
print("n=%-5d 样本均值的标准差=%.4f 理论 sigma/sqrt(n)=%.4f"
% (n, np.std(means), sigma/np.sqrt(n)))
实验 2:线性性即便变量相关也成立
预期看到:两者都约等于 2.0(理论上 \(\mathbb{E}[X+Y]=\mathbb{E}[2]=2\) 精确成立),尽管 \(X,Y\) 强相关。
为什么:线性性 \(\mathbb{E}[aX+bY]=a\mathbb{E}[X]+b\mathbb{E}[Y]\) 不依赖独立性。这里 \(X+Y\equiv2\) 是常数,期望当然是 2。import numpy as np
rng = np.random.default_rng(2)
X = rng.integers(1,7,size=500_000).astype(float)
Y = 2.0 - X # Y 与 X 完全相关
print("E[X]=%.3f E[Y]=%.3f 之和=%.3f" % (X.mean(), Y.mean(), X.mean()+Y.mean()))
print("E[X+Y]=%.3f (理论恒为 2)" % (X+Y).mean())
实验 3:\(\mathbb{E}[g(X)]\neq g(\mathbb{E}[X])\)(Jensen 埋点)
预期看到:\(\mathbb{E}[X^2]\approx15.17\),而 \((\mathbb{E}[X])^2\approx12.25\),前者明显更大,差约 2.92(恰好等于 \(\mathrm{Var}(X)\)!)。
为什么:\(g\) 是凸函数,由 Jensen 不等式 \(\mathbb{E}[g(X)]\ge g(\mathbb{E}[X])\);而二者之差正是 \(\mathbb{E}[X^2]-(\mathbb{E}[X])^2=\mathrm{Var}(X)\)。非线性变换不能把期望随便挪进去。import numpy as np
rng = np.random.default_rng(3)
X = rng.integers(1,7,size=2_000_000).astype(float)
print("E[X^2] = %.4f" % (X**2).mean())
print("(E[X])^2 = %.4f" % (X.mean()**2))
print("差值 = %.4f (= Var(X) ≈ 2.9167)" % ((X**2).mean() - X.mean()**2))
动手练习
import numpy as np
rng = np.random.default_rng(0)
p = 0.7
# TODO: 手算 E[X]=? Var(X)=? (提示:E[X]=p, Var=p(1-p))
X = (rng.random(1_000_000) < p).astype(float) # 1 表示正面
print("E_hat=%.4f Var_hat=%.4f" % (X.mean(), X.var()))
import numpy as np
rng = np.random.default_rng(1)
X = rng.uniform(0, 0.5, size=1_000_000)
# TODO: 估计 P(X<=0.25),并想想 底0.5 × 高2 = 面积1
print("P(X<=0.25) ≈ %.4f" % (X <= 0.25).mean())
np.cumsum 验证它们是 \(0.1,0.3,0.7,1.0\)。rng.choice([0,1,2,3], p=...) 采样 \(n=10^6\) 次,确认样本均值 ≈ 1.9、样本方差 ≈ 0.89。把 \(n\) 调小到 30,多跑几次,体会小样本时估计的抖动。掌握自检
可以先放过的点