我已经把 $X X^\top$ 的特征值谱画出来了,用的是对数纵轴(semilogy),这样病态性会非常直观。 从图里你可以清楚看到几个关键信号。 第一,特征值呈现明显的“断崖式”下降。前面只有一小撮特征值在 $10^0$ 量级,之后迅速跌到 $10^{-15}$ 甚至更小,这说明有效秩远小于 $2V4。 第二,存在大量接近机器精度的特征值$(10^{-15}\sim10^{-30})$。这些方向在数值上线性相关或几乎相关,直接用 $(X X^\top)^{-1}$ 会极度不稳定,这也是你必须用 `pinv` 的根本原因。 第三,这种病态性来源非常“结构性”: * one-hot + 拼接导致特征高度稀疏; * 语料很小,2-gram 组合覆盖极不均匀; * 第一词和第二词的子空间本身就高度相关,进一步压低秩。 如果你愿意进一步玩,可以做三件事来加深直觉: 1)画累计能量曲线,看前 k 个特征值解释了多少能量; 2)对比不用拼接、而是求和(CBOW 风格)的 $X X^\top$; 3)给 $X X^\top + \lambda I$ 加不同 $\lambda$,观察谱被“抬平”的过程,这正是岭回归在干什么。 这个例子本身就是一个非常漂亮的“为什么语言模型里的线性回归天然病态”的最小玩具模型。 --- 上面这段代码已经直接给你画出了 **累计能量曲线**,逻辑非常简单,也很标准,方便你以后复用到别的实验里。 核心步骤可以总结为三行数学含义: 先对$X X^\top$ 做特征值分解,并按从大到小排序。 然后把每个特征值除以总和,得到“能量占比”。 最后对能量占比做累加,得到前 $k$ 个特征值能解释的总能量。 从你现在这个 toy 语料的结果可以直观看到几个现象(这也是这张图的价值): 前大约 10 个特征值已经解释了 80%–90% 的能量,说明有效自由度非常低。 到 15~20 个左右时,累计能量基本到 1,后面的维度几乎全是数值噪声或线性依赖方向。 这和你之前看到的谱“断崖”是完全一致的两个视角: 一个看的是单个方向的尺度, 一个看的是整体可解释性。 如果你下一步想更“教科书化”,可以顺手算一个有效秩(effective rank),或者把这条曲线和加了 $\lambda I$ 的情况对比一下,会非常直观地看到正则化在“拉直”谱结构。 --- 这张图其实把“病态性”和“正则化在干什么”一次性都讲清楚了,可以从两个层次来看。 先看 **λ = 0**(原始 $X X^\top$)。 累计能量曲线在前十几个维度内就迅速逼近 1,后面的维度几乎不再贡献能量。这意味着数据主要活在一个很低维的子空间里,其它方向要么是完全线性相关,要么只剩数值噪声。 对应的有效秩大约是 **13.4**,远小于名义维度 $2V$,这正是强病态、近奇异的典型信号。 再看 **加入 λI 之后的变化**。 当 λ 很小($10^{-3}$)时,曲线几乎不变,说明这种正则化不足以改变几何结构,只是数值上稍微稳定一点。 当 λ 增大到 $10^{-1}$ 时,曲线开始明显“变平”,前几个特征值的统治力减弱,能量被重新分配到更多维度上。 当 λ = 1 时,这种效果最明显:累计能量增长更接近线性,说明谱被抬高、压扁,小特征值不再接近 0,矩阵条件数大幅改善。 从几何角度说: 原始 $X X^\top$ 的椭球在很多方向上被压成“薄片”; 加上 λI 相当于给所有方向都加了一个统一的“厚度”,把几乎塌陷的方向撑起来。 从建模角度说: λ = 0 时模型几乎完全由少数高频 n-gram 决定; λ 增大后,模型被迫在更多上下文方向上分配权重,泛化性更强,但偏置也更大。 所以这张图本质上是在用一个极小的语言模型例子,把 **秩缺失 → 病态 → 伪逆 → 正则化的谱效应** 这一整条链路可视化了出来。