
Hidden Markov Model (HMM) —— 隐马尔可夫模型
系统讲解隐马尔可夫模型(HMM)的完整数学原理与三大核心算法:从马尔可夫链到双重随机过程的演进出发,定义HMM的五元组参数(Q, V, π, A, B);详细推导估值问题、解码问题和学习问题;并通过词性标注、语音识别等经典应用场景展示HMM的实践价值。
阅读文章ZHY's Blog
A UNIVERSE OF IDEAS · BY ZHANG HAOYI
让好奇心 点亮知识宇宙
在代码、模型与思想之间自由漫游。这里持续记录人工智能、机器学习、软件工程与成长实践,让每次阅读都成为一次新的发现。
ARTICLE NOTE
线性回归是机器学习系列的第一个模型,也是整个机器学习大厦的”第一块基石”。它看起来简单——不过是一条”最佳拟合直线”——但其背后蕴含的思想却贯穿了后续所有模型:定义损失函数、优化目标、处理过拟合,这三步曲将在逻辑回归、SVM、神经网络乃至梯度提升树中反复重现。
本文的核心脉络遵循”从纯净到修正”的演进逻辑。我们首先从最小二乘法(OLS)出发,推导其矩阵形式的闭式解,并明确揭示其致命缺陷——当特征存在多重共线性或特征数超过样本数时,XTX 不可逆,模型崩塌。紧接着,我们引入Ridge回归(L2正则化),通过在 XTX 对角线加上 λI,不仅使矩阵永远可逆,还实现了系数收缩;随后是Lasso回归(L1正则化),其几何特性和软阈值算子使其能够将无关特征系数精确置零,实现特征选择;最后,ElasticNet 融合二者优势,在相关特征分组场景中表现稳健。
在模型评价环节,我们对比了 MSE/RMSE 与 MAE 对异常值的敏感性差异——这不仅是评价指标的选择问题,其背后”平方 vs 绝对值”的数学本质,将直接决定模型在具体业务场景中的行为偏好。
Note读完本文,你将彻底理解”线性模型家族”的完整谱系。
而本文铺垫的”损失函数设计 + 正则化修正”这一分析框架,将是我们后续解读逻辑回归和 SVM 等模型时反复使用的核心方法论。
线性回归试图找到一个线性方程,来描述自变量 X 与因变量 y 之间的关系。对于单变量情况,就是一条直线:
y=w1x+w0
其中 w1 是斜率,w0 是截距。在机器学习中,我们统称为模型的权重(weights) 。
对于多元情况,可以写成矩阵形式:
y=Xw
其中 X 是 n×p 的设计矩阵(每行一个样本,每列一个特征),w 是 p×1 的权重向量。
给定一条直线,每个数据点都有一个残差(residual):真实值与预测值之差。我们需要一个指标来衡量“总体残差”的大小。
最经典的做法是:最小化残差平方和。这就是最小二乘法(Ordinary Least Squares, OLS)。
损失函数为:
L(w)=∑i=1n(yi−Xiw)2=∥y−Xw∥22
现在我们来手推这个最小化问题的解析解。
首先展开损失函数:
L(w)=(y−Xw)T(y−Xw)=yTy−yTXw−wTXTy+wTXTXw
由于 yTXw 和 wTXTy 都是标量且互为转置(相等),所以:
L(w)=yTy−2wTXTy+wTXTXw
对 w 求梯度:
∇wL(w)=−2XTy+2XTXw
关于矩阵的梯度(求导):对于整理后的损失函数 L(w)=yTy−2wTXTy+wTXTXw
- 第1项 yTy:与 w 无关,梯度为 0。
- 第2项 −2wTXTy:这可以看成 −2⋅wTa 的形式(其中 a=XTy)。使用公式 ∇w(wTa)=a,所以这一项梯度为 −2a=−2XTy。
- 第3项 wTXTXw:这是典型的二次型 wTAw,其中 A=XTX,且 A 是对称矩阵。使用公式 ∇w(wTAw)=(A+AT)w=2Aw,所以这一项梯度为 2XTXw。
三项相加,立即得到:∇wL(w)=−2XTy+2XTXw
令梯度为零:
−2XTy+2XTXw=0
XTXw=XTy
这就是著名的正规方程(Normal Equation) 。当 XTX 可逆时:
w=(XTX)−1XTy
关于闭式解的存在前提这个闭式解要求 XTX 是满秩的(即特征之间不存在完全共线性)。如果特征数量大于样本数量(p>n),或者存在多重共线性,XTX 就是奇异矩阵,无法求逆。
1import numpy as np2import matplotlib.pyplot as plt3
4class LinearRegression:5 """手动实现线性回归(最小二乘法)"""6
7 def __init__(self):8 self.w = None9 self.intercept_ = None10
11 def fit(self, X, y):12 """13 X: shape (n_samples, n_features)14 y: shape (n_samples,)15 """16 # 添加一列全1,用于处理截距项17 X_b = np.c_[np.ones((X.shape[0], 1)), X] # (n, p+1)18
19 # 正规方程求解20 # w = (X^T X)^(-1) X^T y21 self.w = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y22
23 self.intercept_ = self.w[0]24 self.coef_ = self.w[1:]25 return self26
27 def predict(self, X):28 X_b = np.c_[np.ones((X.shape[0], 1)), X]29 return X_b @ self.w30
31# 生成示例数据32np.random.seed(42)33X = 2 * np.random.rand(100, 1)34y = 4 + 3 * X + np.random.randn(100, 1)35
36# 训练模型37model = LinearRegression()38model.fit(X, y.flatten())39print(f"截距: {model.intercept_:.4f}")40print(f"系数: {model.coef_[0]:.4f}")41# 输出: 截距: 4.2221, 系数: 2.770942
43# 可视化44X_test = np.array([[0], [2]])45y_pred = model.predict(X_test)46plt.scatter(X, y, alpha=0.6)47plt.plot(X_test, y_pred, 'r-', linewidth=2)48plt.xlabel("X")49plt.ylabel("y")50plt.show()当 XTX 不可逆时(特征数 > 样本数,或存在多重共线性),OLS 无法求解。即使可逆,模型也可能过拟合 —— 在训练集上表现很好,但在新数据上很差。
正则化(Regularization) 的核心思想是:在损失函数中加入一个惩罚项,限制模型参数的大小,从而防止过拟合。
Ridge 回归(又称 L2 正则化)在 OLS 损失函数上增加了权重平方和作为惩罚项:
Lridge(w)=∥y−Xw∥22+λ∥w∥22
其中 λ≥0 是正则化强度超参数。
写成展开形式:
Lridge(w)=yTy−2yTXw+wTXTXw+λwTw
对 w 求梯度:
∇wLridge(w)=−2XTy+2XTXw+2λw
令梯度为零:
(XTX+λI)w=XTy
w=(XTX+λI)−1XTy
Ridge 能处理不可逆矩阵的根本原因即使 XTX 不可逆,加上 λI 后矩阵一定可逆(因为 λ>0 时,XTX+λI 是正定矩阵)。这就是 Ridge 能处理不可逆矩阵的根本原因。
Ridge 等价于在以下约束下最小化残差平方和:
∑j=1pwj2≤t
在二维空间中,L2 约束区域是一个圆形。圆形的边界是光滑的,最优解可能落在圆周的任何位置,但很难正好落在坐标轴上,因此 Ridge 通常不会将系数压缩到 0 —— 它做的是收缩(shrinkage),而不是选择(selection)。
1class RidgeRegression:2 """手动实现Ridge回归(L2正则化)"""3
4 def __init__(self, alpha=1.0):5 self.alpha = alpha # 即 lambda6 self.w = None7
8 def fit(self, X, y):9 X_b = np.c_[np.ones((X.shape[0], 1)), X]10 n_features = X_b.shape[1]11
12 # Ridge闭式解: (X^T X + alpha * I)^(-1) X^T y13 # 注意:截距项通常不参与正则化,这里为了简便对所有参数都加了惩罚14 I = np.eye(n_features)15 self.w = np.linalg.inv(X_b.T @ X_b + self.alpha * I) @ X_b.T @ y16 return self17
18 def predict(self, X):19 X_b = np.c_[np.ones((X.shape[0], 1)), X]20 return X_b @ self.w21
22# 对比不同alpha的效果23from sklearn.datasets import make_regression24X, y = make_regression(n_samples=50, n_features=10, noise=0.1, random_state=42)25
26for alpha in [0, 0.1, 1, 10]:27 model = RidgeRegression(alpha=alpha)28 model.fit(X, y)29 coef_norm = np.linalg.norm(model.w[1:]) # 忽略截距30 print(f"alpha={alpha:4.1f}, 系数L2范数={coef_norm:.4f}")31# 输出: alpha越大,系数范数越小(收缩越强)Lasso(Least Absolute Shrinkage and Selection Operator)使用 L1 正则化,惩罚项是权重的绝对值之和:
Llasso(w)=∥y−Xw∥22+λ∥w∥1=∥y−Xw∥22+λ∑j=1p∣wj∣
与 Ridge 不同,Lasso 的损失函数在 wj=0 处不可微,因此没有简单的闭式解。
1. 几何解释
Lasso 等价于在约束 ∑j=1p∣wj∣≤t 下最小化残差平方和。
在二维空间中,L1 约束区域是一个菱形。菱形的顶点在坐标轴上。当目标函数的等高线(椭圆)与约束区域相切时,切点很可能落在菱形的顶点上,此时对应的系数就被压缩为 0。
随着维度增加,多维菱形的“角”越来越多,系数被置零的概率就越大。这就是 Lasso 能够自动进行特征选择的原因——它会产生稀疏解。
2. L1 产生稀疏解而 L2 不产生的原因
总结:L1 的几何形状有“角”,所以容易产生零系数。
在3.3节现有推导基础上,我从专业角度为你补充了三块核心内容,旨在将“跳跃的数学步骤”彻底展开,并赋予其直观的统计含义。请查收修订后的完整 3.3节:
虽然 Lasso 没有闭式解,但在单变量情况下,我们可以推导出解析解。
考虑单变量 Lasso 问题(没有截距):
minw21(y−Xw)2+λ∣w∣
其中 X 和 y 都是标量(为简单起见,假设 XTX=1,即特征已标准化)。
目标是:
minw21(y−Xw)2+λ∣w∣
次梯度(Subgradient)条件的完整展开
由于绝对值函数在 w=0 处不可导,我们需要引入次梯度 ∂∣w∣。对于绝对值函数,其次导数为:
∂∣w∣=⎩⎨⎧{1},[−1,1],{−1},w>0w=0w<0令 z=XTy 且利用标准化条件 XTX=1,损失函数的次梯度为:
∂wLlasso=−X(y−Xw)+λ∂∣w∣=(w−z)+λ∂∣w∣
根据凸优化的最优性条件(0∈∂f(w)),分三种情况讨论:
综合三种情况,得到软阈值算子(Soft-Thresholding Operator):
S(z,λ)=sign(z)⋅max(∣z∣−λ,0)
其中 z=XTy(在标准化特征下,z 也等于普通最小二乘的单变量解 wOLS)。
z 的统计直觉与“软阈值”的物理意义z 的本质:在标准化特征下,z=XTy 实际上就是特征 X 与响应变量 y 的协方差(相关性)。它衡量了当前特征对预测结果的边际贡献强度。
阈值的逻辑:
- 如果相关性 ∣z∣≤λ,说明该特征的贡献强度被正则化惩罚完全“淹没”,模型判定其为噪声,系数直接置零(实现特征筛选)。
- 如果相关性 ∣z∣>λ,说明该特征有效,但系数不是直接取 z,而是向零收缩 λ 的量(减去 λ)。这种“收缩”不同于 Ridge 的等比缩放,它是绝对值上的硬性削减,因此得名“软阈值”(Soft-Thresholding)。
代码实现:
1def soft_threshold(z, lam):2 """软阈值算子"""3 return np.sign(z) * np.maximum(np.abs(z) - lam, 0)4
5# 演示6z_values = np.linspace(-3, 3, 100)7for lam in [0, 0.5, 1, 2]:8 s_values = [soft_threshold(z, lam) for z in z_values]9 plt.plot(z_values, s_values, label=f'λ={lam}')10plt.axhline(0, color='black', linewidth=0.5)11plt.axvline(0, color='black', linewidth=0.5)12plt.xlabel('z')13plt.ylabel('S(z, λ)')14plt.legend()15plt.title('软阈值算子')16plt.show()对于多维 Lasso,通常使用坐标下降法(Coordinate Descent) 求解。核心思想是每次只优化一个参数,固定其他所有参数。这样一来,原本复杂的 p 维优化问题,就被拆解成了无数个一维的单变量 Lasso 问题。
在第 t 轮迭代中,当我们准备更新第 j 个特征对应的权重 wj 时:
即在坐标下降法中,软阈值算子会逐坐标地对特征进行“相关性截断”,从而在多维场景中高效地产生稀疏解。这使得 Lasso 在超高维数据(p≫n)中依然具备强大的特征选择能力。
对于 Lasso 的第 j 个坐标更新:
wj(new)=S(n1∑i=1nXij(yi−∑k=jXikwk),λ)
即计算当前残差与第 j 个特征的相关性,然后应用软阈值。
和 Ridge 回归的直观对比:
- Ridge 的坐标更新是给系数乘以一个小于 1 的固定比例(如 (0.9 \times w_j)),系数只会无限逼近 0,但永远到不了 0。
- Lasso 的坐标更新是硬生生的“阈值截断”,只要贡献潜力不够大,系数直接精确等于 0。 这个“绝对零”的特性,就是坐标下降法让 Lasso 产生稀疏解的工程实现。
scikit-learn 的 Lasso 实现默认就使用坐标下降法。
1from sklearn.linear_model import Lasso2from sklearn.datasets import make_regression3
4X, y = make_regression(n_samples=100, n_features=20, n_informative=5, noise=0.1, random_state=42)5
6# 注意:alpha越大,稀疏性越强7for alpha in [0.01, 0.1, 1]:8 lasso = Lasso(alpha=alpha, max_iter=10000)9 lasso.fit(X, y)10 n_nonzero = np.sum(np.abs(lasso.coef_) > 1e-6)11 print(f"alpha={alpha:.2f}, 非零系数个数={n_nonzero}")12# alpha越大,非零系数越少(越稀疏)ElasticNet 结合了两者的优点。
ElasticNet 的损失函数为:
Lelastic(w)=2n1∥y−Xw∥22+α⋅ρ∥w∥1+2α(1−ρ)∥w∥22
其中:
l1_ratio):L1 和 L2 的混合比例
ElasticNet 也可以用坐标下降法求解。scikit-learn 的 ElasticNet 默认使用坐标下降。
1from sklearn.linear_model import ElasticNet2
3X, y = make_regression(n_samples=100, n_features=20, n_informative=5, noise=0.1, random_state=42)4
5for l1_ratio in [0, 0.5, 1]:6 enet = ElasticNet(alpha=0.1, l1_ratio=l1_ratio)7 enet.fit(X, y)8 n_nonzero = np.sum(np.abs(enet.coef_) > 1e-6)9 print(f"l1_ratio={l1_ratio:.1f}, 非零系数个数={n_nonzero}")10# l1_ratio=0 (Ridge): 全部非零11# l1_ratio=0.5: 部分稀疏12# l1_ratio=1 (Lasso): 最稀疏MSE=n1∑i=1n(yi−y^i)2
MSE 是线性回归最常用的损失函数。它对大误差给予更大的惩罚(平方放大)。
RMSE=MSE=n1∑i=1n(yi−y^i)2
RMSE 只是 MSE 开方,量纲与原始数据一致,更易解释。
MAE=n1∑i=1n∣yi−y^i∣
MAE 是线性的,所有误差被同等对待。
这是三者最核心的区别:
| 指标 | 对异常值的敏感性 | 原因 |
|---|---|---|
| MSE/RMSE | 非常敏感 | 平方运算放大了大误差的影响 |
| MAE | 相对鲁棒 | 绝对值不放大误差 |
代码实现:
1from sklearn.metrics import mean_squared_error, mean_absolute_error2
3# 模拟正常数据和异常值4y_true = np.array([1, 2, 3, 4, 5])5y_pred_normal = np.array([1.1, 1.9, 3.2, 3.8, 5.1])6y_pred_outlier = np.array([1.1, 1.9, 3.2, 3.8, 50]) # 最后一个点是异常预测7
8print("=== 正常情况 ===")9print(f"MSE: {mean_squared_error(y_true, y_pred_normal):.4f}")10print(f"RMSE: {np.sqrt(mean_squared_error(y_true, y_pred_normal)):.4f}")11print(f"MAE: {mean_absolute_error(y_true, y_pred_normal):.4f}")12
13print("\n=== 存在异常预测 ===")14print(f"MSE: {mean_squared_error(y_true, y_pred_outlier):.4f}")15print(f"RMSE: {np.sqrt(mean_squared_error(y_true, y_pred_outlier)):.4f}")16print(f"MAE: {mean_absolute_error(y_true, y_pred_outlier):.4f}")17# 可以看到:MSE/RMSE被异常值大幅拉高,而MAE变化相对温和总结
方法 正则项 闭式解 稀疏性 适用场景 OLS 无 ✅ (XTX)−1XTy ❌ 特征数 < 样本数,无共线性 Ridge L2: λ∥w∥22 ✅ (XTX+λI)−1XTy ❌ 多重共线性,特征相关 Lasso L1: λ∥w∥1 ❌(坐标下降) ✅ 特征选择,高维数据 ElasticNet L1 + L2 ❌(坐标下降) ✅(可控) 相关特征分组,兼顾选择与稳定 核心要点回顾
- 最小二乘法的闭式解 w=(XTX)−1XTy 是线性回归的基石,但要求 XTX 可逆。
- Ridge(L2) 通过在 XTX 对角线加 λ 保证矩阵可逆,系数收缩但不归零。
- Lasso(L1) 的稀疏性来自两个层面:
- 几何:L1 约束是菱形,更容易在坐标轴上相切
- 算法:软阈值算子 S(z,λ)=sign(z)max(∣z∣−λ,0) 会将小系数直接置零
- ElasticNet 结合 L1 和 L2,在特征选择的同时保持分组稳定性。
- MSE/RMSE 对异常值敏感(平方放大误差),MAE 相对鲁棒(绝对值不放大)。
按顺序完成这组文章,循序渐进地掌握主题
发现错误、内容过时或有改进想法?欢迎告诉我
根据本文分类与标签,为你推荐可能感兴趣的内容

系统讲解隐马尔可夫模型(HMM)的完整数学原理与三大核心算法:从马尔可夫链到双重随机过程的演进出发,定义HMM的五元组参数(Q, V, π, A, B);详细推导估值问题、解码问题和学习问题;并通过词性标注、语音识别等经典应用场景展示HMM的实践价值。
阅读文章
系统讲解期望最大化(EM)算法的完整数学原理:从极大似然估计在隐变量存在时的困境出发,推导E步与M步的迭代框架;基于Jensen不等式证明ELBO证据下界与收敛性;通过二硬币模型与高斯混合模型(GMM)两个完整实例展示EM的具体计算流程;揭示K-Means是EM在硬分配下的特例这一深层联系。
阅读文章
系统讲解K-Means聚类的核心原理与算法细节,涵盖Lloyd交替优化算法的收敛性分析、K-Means作为EM算法特例的理论联系(硬分配 vs 软分配)、K-Means++初始化策略的D²采样机制与O(log K)近似保证,以及肘部法则与轮廓系数的选择K值方法及其局限。
阅读文章请使用微信扫描二维码分享
当前文章会保持在原页面