1. 问题的源起:词向量空间模型的局限性

文本信息处理的一个核心任务是度量文档之间的语义相似度。最基础且直观的方法是向量空间模型(Vector Space Model, VSM)

其基本思想十分简洁:给定一个由 个单词组成的词典和 篇文档组成的语料库,我们可以构建一个 词-文档矩阵 (term-document matrix)

在这个矩阵中:

  • 每一行代表一个单词 )。
  • 每一列代表一篇文档 )。
  • 矩阵中的元素 代表单词 在文档 中的重要性权重。这个权重最简单的可以是词频,但更常用的是 TF-IDF 值。

这样一来,每篇文档 都可以被表示成一个 维的列向量 。两篇文档的相似度,则可以通过计算它们对应向量的余弦相似度来衡量。

这个模型非常强大,至今仍是许多系统的基石。但它存在两个根本性的语义层面的问题:

  1. 同义词问题(Synonymy): 比如,“计算机”和“电脑”是同义词。但在VSM中,它们是两个不同的维度,是严格正交的。如果一篇文档用“计算机”,另一篇用“电脑”,即使它们讨论的是同一主题,它们的向量内积在这些维度上的贡献也为零。模型无法捕捉到这种语义上的等价性。

  2. 多义词问题(Polysemy): 比如,“bank”这个词,可以指“银行”,也可以指“河岸”。VSM会把所有上下文中出现的“bank”都映射到同一个维度上,混淆了其不同的含义,导致语义不精确。

LSA的提出,正是为了从根本上缓解这两个问题。它的核心洞察在于:直接在词汇层面上进行比较是不可靠的,我们应该在一个更抽象的“概念”或“主题”层面上进行比较。

2. LSA与奇异值分解 (SVD)

LSA认为,词-文档矩阵 中存在着大量的“噪声”,而真正有价值的语义结构,隐藏在一个更低维度的空间中。寻找这个空间的工具,就是奇异值分解(Singular Value Decomposition, SVD)

SVD是线性代数中一种强大的矩阵分解技术,它可以将任意一个 的矩阵 分解为三个矩阵的乘积:

  • (): 我们的原始词-文档矩阵
  • (): 这是一个正交矩阵。它的每一列 被称为左奇异向量。在LSA的语境下,我们可以将 理解为一个“词-主题”矩阵。它的每一列都代表一个抽象的、相互正交的“主题”或“概念”,而列向量中的元素则表示每个词汇对这个主题的贡献度。
  • (): 这是一个对角矩阵(或块对角矩阵)。其对角线上的元素 被称为奇异值。这些值是非负的,并且通常从大到小排列。每个奇异值 衡量了与之对应的第 个主题的重要性或“能量”。值越大,说明这个主题在整个语料库中的解释力度越强。
  • (): 也是一个正交矩阵,它的每一列 被称为右奇异向量。因此 的每一行是 。在LSA中,我们可以将 理解为一个“文档-主题”矩阵。它的每一列(即 的每一行)同样代表了上面由 定义的那些抽象主题,而列向量中的元素则表示每篇文档在这些主题上的分布情况。

所以,SVD的分解 X = UΣV^T 可以被解读为: “词与文档的关系(),可以被分解为‘词与主题的关系’()、‘各个主题的重要性’()以及‘文档与主题的关系’()这三者的结合。”

3. 使用截断SVD完成从原始空间到语义空间的映射

SVD本身只是一个精确的数学分解。LSA的“魔法”发生在降维这一步,也就是截断奇异值分解 (Truncated SVD)

我们假设语料库中真正核心的主题只有 个( 远小于 )。这意味着,那些较小的奇异值 可能对应的是一些噪声或者过于细节的语义变化。我们可以大胆地将它们丢弃,只保留前 个最大的奇异值,以及它们对应的左、右奇异向量。

这就得到了SVD的近似形式,也即是公式(17.13):

我们来严格定义截断后的矩阵:

  • :取 的前 列,尺寸为 。现在,每一行代表一个词,而这一行中的 个元素,就是这个词在 个核心主题上的坐标。这就是词的语义向量
  • :取 的左上角 的对角子矩阵。尺寸为 。它包含了前 个最重要的奇异值。
  • :取 的前 行,尺寸为 。现在,每一列代表一篇原始文档,而这一列中的 个元素,就是这篇文档在 个核心主题上的坐标。这就是文档的语义向量

现在,我们得到了最重要的东西:

  1. 词的 维语义表示:矩阵 的第 行,就是一个 维向量,它代表了单词 在这个新的语义空间中的表示。
  2. 文档的 维语义表示:矩阵 的第 列,就是一个 维向量,它代表了文档 在这个新的语义空间中的表示。这正如《机器学习方法》中所述:“将其左奇异矩阵与对角矩阵的乘积作为单词在话题向量空间的表示,将其右奇异矩阵与对角矩阵的乘积作为文本在话题向量空间的表示。”更常见的做法是,直接用 的列向量(或者说 的行向量)作为文档的表示,或者用 的列向量。两者都是有效的,后者考虑了主题的权重。

LSA如何解决VSM的问题?

  • 解决同义词问题:在原始语料中,“计算机”和“电脑”可能从未在同一篇文档中出现,但在大量文档中,它们总是和相似的词(如“CPU”、“编程”、“软件”)一起出现。SVD作为一个全局的矩阵分解方法,能够捕捉到这种共现模式。在降维过程中,它倾向于将“计算机”和“电脑”这两个原始维度,映射到 维语义空间中非常相近的位置。因此,它们的语义向量的余弦相似度会很高。
  • 解决多义词问题:对于“bank”,如果语料库中同时包含金融和地理两类主题的文档,SVD会生成至少两个与之相关的主题轴。一个可能由“银行”、“存款”、“利率”等词定义,另一个由“河岸”、“水”、“船”等词定义。“bank”这个词的最终语义向量,会是这两个主题向量的某种线性组合,从而在一定程度上消解了单一维度的歧义。

4. 一个简化的数值示例

为了让这个过程更具体,我们构想一个极小的例子。

假设我们的语料库有4篇文档,词典只有6个词:

  • : learning about machine learning
  • : deep learning is fun
  • : i love my cat
  • : my cat is fun

我们构建一个简单的词频矩阵 (这里不用TF-IDF以简化计算):

learning2100
machine1000
deep0100
fun0101
cat0011
love0010

直观上,我们可以看到 是关于“学习”的主题,而 是关于“猫”的主题。

现在,我们对 进行SVD,并选择 (因为我们直观地看到了两个主题)。通过计算(例如使用Python的numpy.linalg.svd),我们会得到 , ,

假设计算结果(为了说明,这里是示意值)给出的文档语义表示 如下:

(注意:实际SVD结果中可能有负值,这里为了解释性而简化)

每一列现在是对应文档的2维表示:

现在,我们计算文档间的余弦相似度。

  • Sim(): 向量 的夹角会非常小,相似度接近1。这成功捕捉到了它们都关于“学习”主题的深层联系,尽管它们共享的词只有一个(“learning”)。
  • Sim(): 向量 的夹角会接近90度,相似度接近0。这正确地分开了两个不相关的主题。

通过这个过程,LSA成功地超越了表面词汇的限制,在“主题”层面发现了文档之间的真正关系。