约 35 分钟 · 需要向量表示、条件概率与矩阵运算

读完你能: 训练一个带平滑的多项式朴素贝叶斯分类器;手算 SVM 的 hinge loss 并理解间隔与正则化参数的作用;用伪逆或岭回归求解 ELM 输出层权重;计算高斯过程回归的预测均值与方差,并为具体文本任务挑选合适的基线模型。

1. 特征表示与分类模型是两个独立选择

前几章介绍了如何把文本转换成数值向量:词频计数、TF-IDF、稠密词向量,或者 SVD/NMF 降维后的低维坐标。一旦文本变成了特征向量,后续接什么学习模型是另一个独立的设计选择:词频计数常配朴素贝叶斯,高维稀疏 TF-IDF 常配线性 SVM,低维稠密特征则可以进一步尝试核方法或高斯过程。

方法 核心学习目标 关键假设与注意点
朴素贝叶斯 类别先验 P(c)P(c) 与词的条件概率 P(w∣c)P(w\mid c) 给定类别时词条件独立;需配合平滑与固定词表
线性 SVM 最大间隔分离超平面 关注决策边界附近的样本;受特征尺度与惩罚系数 CC 影响
极限学习机(ELM) 随机隐藏层之后的线性输出权重 β\beta 输入到隐藏层随机固定;依赖隐藏层宽度与最小二乘求解稳定性
高斯过程(GP) 潜在函数的先验与后验分布 核函数决定平滑性;精确求解时间复杂度 O(n3)O(n^3)
线性回归 连续目标与特征的线性映射 优化平方误差;输出值不限制在 [0,1][0,1],不能直接当作类别概率

2. 多项式朴素贝叶斯

设文档 dd 中词 ww 的出现次数为 fw,df_{w,d},候选类别为 c∈Cc\in C。由贝叶斯公式,给定文档时类别的后验概率满足

P(c∣d)=P(c)P(d∣c)P(d)∝P(c)P(d∣c).P(c\mid d)=\frac{P(c)P(d\mid c)}{P(d)}\propto P(c)P(d\mid c).

朴素贝叶斯之所以叫“朴素”,是因为它假设给定类别 cc 后,各个位置的词相互条件独立。于是文档的似然可以拆成各词条件概率的连乘;同一个词 ww 出现 fw,df_{w,d} 次,就连乘 fw,df_{w,d} 次。取对数把连乘化为连加,判别规则为:

c^=arg⁡max⁡c[ln⁡P(c)+∑w∈Vfw,dln⁡P(w∣c)].\hat c=\arg\max_c\left[\ln P(c)+\sum_{w\in V}f_{w,d}\ln P(w\mid c)\right].

虽然自然语言里的词并不真正独立,但这个简化能以极低的计算成本给出稳健的分类基线。

若某个词在训练集某类别下从未出现,直接按最大似然估计会得到 P(w∣c)=0P(w\mid c)=0,一旦测试文档包含该词,整个连乘就变成 0。为此,多项式模型通常采用加 α\alpha 平滑(α=1\alpha=1 时即拉普拉斯加一平滑):

P(w∣c)=Ncw+αNc+α∣V∣,Nc=∑w∈VNcw.P(w\mid c)=\frac{N_{cw}+\alpha}{N_c+\alpha\lvert V\rvert},\qquad N_c=\sum_{w\in V}N_{cw}.

这里 NcwN_{cw} 是类别 cc 的所有训练文档中词 ww 出现的总词元次数,NcN_c 是类别 cc 的全部词元总数,∣V∣\lvert V\rvert 是词表大小。类别先验则用类别文档数除以总训练文档数估计:P(c)=Dc/DP(c)=D_c/D。

分清多项式模型与 Bernoulli 模型的分母

多项式朴素贝叶斯按词元出现次数建模,平滑分母是 Nc+α∣V∣N_c+\alpha\lvert V\rvert(词元总数加词表大小);Bernoulli 朴素贝叶斯则按“每篇文档是否包含该词”的 0/1 事件建模,分母是类别文档数加 2α2\alpha。手算时切勿把两套分母混用。

3. 手算一个朴素贝叶斯分类器

设训练集有 4 篇短评:

  • 正面(++):good movie、good fun
  • 负面(−-):bad movie、bad boring

词表为 V={good, movie, fun, bad, boring}V=\{\text{good, movie, fun, bad, boring}\},大小 ∣V∣=5\lvert V\rvert=5。正负两类各有 2 篇文档,因此先验 P(+)=P(−)=1/2P(+)=P(-)=1/2;两类各自的词元总数都是 N+=N−=4N_+=N_-=4。

取拉普拉斯平滑 α=1\alpha=1,分母均为 4+1×5=94+1\times 5=9,各词的条件概率如下:

词 ww 正面计数 N+wN_{+w} 负面计数 N−wN_{-w} P(w∣+)P(w\mid +) P(w∣−)P(w\mid -)
good 2 0 (2+1)/9=3/9(2+1)/9=3/9 (0+1)/9=1/9(0+1)/9=1/9
movie 1 1 (1+1)/9=2/9(1+1)/9=2/9 (1+1)/9=2/9(1+1)/9=2/9
fun 1 0 (1+1)/9=2/9(1+1)/9=2/9 (0+1)/9=1/9(0+1)/9=1/9
bad 0 2 (0+1)/9=1/9(0+1)/9=1/9 (2+1)/9=3/9(2+1)/9=3/9
boring 0 1 (0+1)/9=1/9(0+1)/9=1/9 (1+1)/9=2/9(1+1)/9=2/9

每一列的条件概率之和都等于 9/9=19/9=1。现在对测试文档 d=d= good movie 分类:

s+=P(+)P(good∣+)P(movie∣+)=12×39×29=127,s_+=P(+)P(\text{good}\mid +)P(\text{movie}\mid +)=\frac12\times\frac39\times\frac29=\frac1{27},
s−=P(−)P(good∣−)P(movie∣−)=12×19×29=181.s_-=P(-)P(\text{good}\mid -)P(\text{movie}\mid -)=\frac12\times\frac19\times\frac29=\frac1{81}.

因为 s+>s−s_+>s_-,分类器判定为正面。将两类得分归一化可得后验概率 P(+∣d)=1/271/27+1/81=0.75P(+\mid d)=\dfrac{1/27}{1/27+1/81}=0.75。需要注意,由于条件独立假设会让重复特征的证据成倍累加,朴素贝叶斯算出的后验往往偏极端(趋近 0 或 1),需要概率校准后才能当作真实置信度使用。

实际工程实现中,文档包含几十上百个词,直接连乘很容易发生浮点数下溢,因此一律在对数域累加:

from collections import Counter
from math import log

train = [("good movie", "+"), ("good fun", "+"),
         ("bad movie", "-"), ("bad boring", "-")]
vocab = {w for text, _ in train for w in text.split()}
class_docs = Counter(label for _, label in train)
counts = {c: Counter() for c in class_docs}
for text, label in train:
    counts[label].update(text.split())

def score(text, label, alpha=1.0):
    total = sum(counts[label].values())
    result = log(class_docs[label] / len(train))
    for w, n in Counter(text.split()).items():
        if w in vocab:
            result += n * log((counts[label][w] + alpha) / (total + alpha * len(vocab)))
    return result

assert score("good movie", "+") > score("good movie", "-")

上面的代码在推断时跳过了词表外的未登录词(OOV);另一种常见做法是在训练时把低频词替换为 <UNK> 并在词表中保留该符号。无论选哪种方案,训练与测试必须保持一致——拉普拉斯平滑解决的是“词表内的词在某个类别中计数为 0”,并不会自动给词表之外的新词分配概率。

4. SVM:不仅要分对,还要留出间隔

设线性判别函数为 f(x)=wTx+bf(x)=w^Tx+b,二分类标签取 y∈{−1,+1}y\in\{-1,+1\}。几何上,超平面 wTx+b=0w^Tx+b=0 把空间一分为二,样本点 xx 到超平面的距离为 ∣wTx+b∣/∥w∥2\lvert w^Tx+b\rvert/\lVert w\rVert_2。支持向量机(SVM)希望两类样本不仅位于超平面两侧,而且离超平面最近的点也尽可能远。在间隔边界固定为 wTx+b=±1w^Tx+b=\pm1 的规范化约定下,最小化 12∥w∥22\frac12\lVert w\rVert_2^2 就对应于最大化两条边界之间的距离 2/∥w∥22/\lVert w\rVert_2。

现实文本数据往往不是严格线性可分的,软间隔线性 SVM 将间隔最大化与训练误差合写为:

min⁡w,b 12∥w∥22+C∑i=1nmax⁡(0,1−yif(xi)).\min_{w,b}\ \frac12\lVert w\rVert_2^2+C\sum_{i=1}^n\max(0,1-y_if(x_i)).

其中 ℓhinge(y,f(x))=max⁡(0,1−yf(x))\ell_{\text{hinge}}(y,f(x))=\max(0,1-yf(x)) 称为合页损失(hinge loss):

  • yf(x)>0yf(x)>0 说明预测符号与真实标签同号,分类结果正确;
  • 但只有当 yf(x)≥1yf(x)\ge 1(样本落在间隔边界上或正确一侧的间隔之外)时,hinge loss 才等于 0;
  • 若 0<yf(x)<10<yf(x)<1,虽然分对了类别,但距离超平面太近、间隔不足,仍会产生 1−yf(x)1-yf(x) 的损失。

例1: 设 w=(1,−1)T,b=0w=(1,-1)^T, b=0,正例标签 y=+1y=+1。

  • 对样本 x(1)=(0.8,0.3)Tx^{(1)}=(0.8,0.3)^T:预测分数 f(x(1))=0.8−0.3=0.5>0f(x^{(1)})=0.8-0.3=0.5>0,分类正确,但 yf(x(1))=0.5<1yf(x^{(1)})=0.5<1,因此 hinge loss 为 1−0.5=0.51-0.5=0.5。
  • 对样本 x(2)=(2,1)Tx^{(2)}=(2,1)^T:预测分数 f(x(2))=2−1=1f(x^{(2)})=2-1=1,满足 yf(x(2))≥1yf(x^{(2)})\ge 1,hinge loss 为 00。

目标函数里的超参数 C>0C>0 控制对间隔违约的惩罚力度:**CC 越大,越不允许训练样本侵入间隔,边界越贴近训练点;CC 越小,正则项 12∥w∥22\frac12\lVert w\rVert_2^2 占比越重,允许更多训练样本违约以换取更宽的间隔。** 切勿把 CC 的方向记反。

当输入空间确实需要非线性边界时,核方法将内积 xTzx^Tz 替换为 Mercer 核函数 K(x,z)K(x,z),隐式映射到高维特征空间:

  • 线性核:K(x,z)=xTzK(x,z)=x^Tz,适合高维稀疏文本(如 TF-IDF 特征),速度快且强基线效果好;
  • 多项式核:K(x,z)=(xTz+1)ρK(x,z)=(x^Tz+1)^\rho,ρ\rho 为多项式阶数;
  • RBF(高斯)核:K(x,z)=exp⁡(−∥x−z∥222σ2)K(x,z)=\exp\left(-\dfrac{\lVert x-z\rVert_2^2}{2\sigma^2}\right)(常简写为 e−γ∥x−z∥22e^{-\gamma\lVert x-z\rVert_2^2}),带宽参数决定局部影响范围。

在词表维度已经高达数万的文本分类中,特征本身往往接近线性可分,直接用线性 SVM 通常是性价比最高的第一选择。

5. ELM:随机固定隐藏层,输出层解线性最小二乘

极限学习机(Extreme Learning Machine, ELM)是一种单隐藏层前馈网络。与通过反向传播迭代更新全部权重的神经网络不同,ELM 把输入层到隐藏层的权重 aja_j 和偏置 bjb_j 随机采样后直接固定,只训练隐藏层到输出层的线性权重 β\beta。

设有 nn 个训练样本、LL 个隐藏神经元,激活函数为 g(⋅)g(\cdot),隐藏层输出矩阵 H∈Rn×LH\in\mathbb R^{n\times L} 的第 (i,j)(i,j) 项为:

Hij=g(ajTxi+bj),Hβ≈Y.H_{ij}=g(a_j^Tx_i+b_j),\qquad H\beta\approx Y.

由于 HH 已经固定,求输出权重 β\beta 就化简成一个标准线性最小二乘问题。通常 HH 不是方阵(样本数 nn 与隐藏节点数 LL 不相等),因此用 Moore–Penrose 伪逆写作 β=H+Y\beta=H^+Y,或者加入 L2 正则化(岭回归)以提高数值稳定性:

β=(HTH+λI)−1HTY.\beta=(H^TH+\lambda I)^{-1}H^TY.

例2: 设 2 个样本在 2 个隐藏节点上的激活矩阵与目标值为

H=(1011),Y=(13).H=\begin{pmatrix}1&0\\1&1\end{pmatrix},\qquad Y=\begin{pmatrix}1\\3\end{pmatrix}.

解线性方程组 β1=1\beta_1=1、β1+β2=3\beta_1+\beta_2=3,直接得 β=(1,2)T\beta=(1,2)^T。当样本数 n>Ln>L 且方程组超定不相容时,β=H+Y\beta=H^+Y 给出的正是使平方误差 ∥Hβ−Y∥22\lVert H\beta-Y\rVert_2^2 最小的最小二乘解。实际计算中应调用 SVD 或 QR 分解求解线性方程组,避免显式计算矩阵求逆。

6. 高斯过程:直接在函数空间建概率分布

参数模型把学习目标写成一组有限维权重 ww,而高斯过程(Gaussian Process, GP)直接对未知函数 f(x)f(x) 建立概率分布:任意有限个输入点上的函数值 (f(x1),…,f(xn))T(f(x_1),\dots,f(x_n))^T 都联合服从多元高斯分布。

一个高斯过程由均值函数 m(x)=E[f(x)]m(x)=\mathbb E[f(x)](常设为 0)和协方差核函数 k(x,x′)=Cov⁡(f(x),f(x′))k(x,x')=\operatorname{Cov}(f(x),f(x')) 完全决定。由训练输入构成的 Gram 核矩阵 Kij=k(xi,xj)K_{ij}=k(x_i,x_j) 必须半正定。例如常用的 RBF 核 k(x,x′)=σf2exp⁡(−∥x−x′∥222ℓ2)k(x,x')=\sigma_f^2\exp\left(-\dfrac{\lVert x-x'\rVert_2^2}{2\ell^2}\right) 中,长度尺度 ℓ\ell 越大,生成的函数越平缓;ℓ\ell 越小,函数随输入变化越剧烈。

在高斯过程回归中,设观测目标含独立高斯噪声 y=f(x)+εy=f(x)+\varepsilon,ε∼N(0,σn2)\varepsilon\sim\mathcal N(0,\sigma_n^2)。给定训练集核矩阵 KK、训练标签 yy,以及新样本 x∗x_* 与各训练样本的核向量 k∗=(k(x1,x∗),…,k(xn,x∗))Tk_*=(k(x_1,x_*),\dots,k(x_n,x_*))^T,潜在函数值 f∗=f(x∗)f_*=f(x_*) 的后验均值与方差有闭式解:

μ∗=k∗T(K+σn2I)−1y,\mu_*=k_*^T(K+\sigma_n^2I)^{-1}y,
Var⁡(f∗)=k(x∗,x∗)−k∗T(K+σn2I)−1k∗.\operatorname{Var}(f_*)=k(x_*,x_*)-k_*^T(K+\sigma_n^2I)^{-1}k_*.

若要预测包含观测噪声的新输出 y∗y_*,只需在 Var⁡(f∗)\operatorname{Var}(f_*) 上再加 σn2\sigma_n^2。

例3: 设两个训练点的核矩阵为 K=(10.50.51)K=\begin{pmatrix}1&0.5\\0.5&1\end{pmatrix},噪声方差 σn2=0.1\sigma_n^2=0.1,观测值 y=(1,−1)Ty=(1,-1)^T;新点满足 k∗=(0.5,0.25)Tk_*=(0.5,0.25)^T、k(x∗,x∗)=1k(x_*,x_*)=1。

  1. 先算 K+σn2I=(1.10.50.51.1)K+\sigma_n^2I=\begin{pmatrix}1.1&0.5\\0.5&1.1\end{pmatrix},行列式为 1.12−0.52=0.961.1^2-0.5^2=0.96。
  2. 解线性方程组 (K+σn2I)α=y(K+\sigma_n^2I)\alpha=y:注意到 (1.1−0.5)=0.6(1.1-0.5)=0.6,可得 α=(5/3, −5/3)T\alpha=(5/3,\ -5/3)^T。
  3. 预测均值:μ∗=k∗Tα=0.5×53+0.25×(−53)=512≈0.4167\mu_*=k_*^T\alpha=0.5\times\frac53+0.25\times\left(-\frac53\right)=\frac5{12}\approx0.4167。
  4. 潜在方差先算二次型:k∗T(K+σn2I)−1k∗=1.1(0.52+0.252)−2×0.5×0.5×0.250.96=0.218750.96=175768≈0.2279k_*^T(K+\sigma_n^2I)^{-1}k_*=\dfrac{1.1(0.5^2+0.25^2)-2\times0.5\times0.5\times0.25}{0.96}=\dfrac{0.21875}{0.96}=\dfrac{175}{768}\approx0.2279,因此 Var⁡(f∗)=1−0.2279≈0.7721\operatorname{Var}(f_*)=1-0.2279\approx0.7721。

高斯过程不仅给出点预测 μ∗\mu_*,还自然给出不确定性度量 Var⁡(f∗)\operatorname{Var}(f_*)。对 RBF 这类随距离衰减的核,当新点远离所有训练点时,k∗k_* 趋近于零,后验方差便接近先验方差 k(x∗,x∗)k(x_*,x_*)。但若用于分类任务,后验不再是高斯分布,需要通过 Laplace 近似或变分推断处理;同时精确求解 (K+σn2I)−1(K+\sigma_n^2I)^{-1} 需要 O(n3)O(n^3) 时间与 O(n2)O(n^2) 内存,主要受样本数限制;处理大样本时通常需要近似或稀疏方法。

7. 线性回归与传统模型选型

当任务目标是预测连续数值(例如评分数值或可读性分数)时,可以直接用线性回归 y^=wTx+b\hat y=w^Tx+b 最小化均方误差:

J(w,b)=12N∑i=1N(wTxi+b−yi)2,J(w,b)=\frac1{2N}\sum_{i=1}^N(w^Tx_i+b-y_i)^2,

并沿负梯度方向迭代更新 w←w−α∂J∂ww\leftarrow w-\alpha\dfrac{\partial J}{\partial w}。但线性回归的预测值在整个实数轴上取值,不受 [0,1][0,1] 约束,不能直接当作分类概率使用。

实际做文本建模时,建议固定同一套训练/验证集划分与评估指标,先跑通多项式朴素贝叶斯和 TF-IDF + 线性 SVM 两个轻量基线,看清错误集中在哪些样本,再决定是否引入非线性核、ELM 或神经模型。

自测

1. 在第 3 节的朴素贝叶斯例子中,测试文档换成 good good movie,归一化后的正面后验概率是多少?

good 出现 2 次,其条件概率平方后计入得分:s+=12(39)229=181s_+=\frac12\left(\frac39\right)^2\frac29=\frac1{81},s−=12(19)229=1729s_-=\frac12\left(\frac19\right)^2\frac29=\frac1{729}。两类得分之比为 9:19:1,因此正面后验概率升至 0.90.9。重复词会成倍放大条件独立模型中的证据。

2. 某样本真实标签 y=-1,SVM 预测值 f(x)=-0.2,分类方向已经正确,它的 hinge loss 是多少?

yf(x)=(−1)×(−0.2)=0.2<1yf(x)=(-1)\times(-0.2)=0.2<1,因此 max⁡(0,1−0.2)=0.8\max(0,1-0.2)=0.8。分类符号正确但尚未跨过间隔边界 yf(x)≥1yf(x)\ge 1,仍然会产生损失。