隐性语义索引(LSI)原理与实现

隐性语义索引(Latent Semantic Idexing, LSI),也叫Latent Semantic Analysis(LSA),是信息检索领域一类非常重要的技术思想。它通过对词项-文档矩阵的奇异值分解,在理论上成功地解决了潜在语义(或者叫隐性语义)的检索问题。本文将介绍关于LSI的原理和实现方法。

隐含语义问题

基于关键词的文档检索是IR中最简单,也是最普遍的技术手段。一般来说,基本做法是:当查询的词(一个或多个)与文档中的词相匹配时,该文档被“命中”,如果是多关键词查询,则遵循匹配的词项越多文档的检索排名越靠前的原则。这种思路非常经典,Salton等人在70年代就据此提出了至今仍非常有效的向量空间模型(VSM),即将文档和查询解析为由词项的存在性构成的二进制的特征向量,计算向量的内积(或者是计算cos相似度等等)即可得到用于检索排序的得分。更进一步地,为了使检索排名更加准确,随后又在二进制向量的基础上构建了词项的权重算法 t f i d f 和其各种变形。

总的来说,依赖关键词匹配与否的做法是有效而实用的。但是随着信息量的爆炸式增长,信息的结构越发复杂,完全靠匹配判断就显得有所不足了。举个例子,我查找一个词“加密”,那你说假如一个文档中存在“密码”,“信息安全”,“隐私保护”,“解密”这些词,那么即便它没有“加密”这个词,是不是也应该被检索出?而且应该排名还不会太差。不难发现,这里面的关键是存在“隐性语义”的问题,具体地:

  1. 词a和词b在形式上可能完全不同,但在语义上是相近的,甚至是几乎一样的。比如“中国”和“China”,“电脑”和“计算机”,“北邮”和“北京邮电大学”等等);
  2. 词a和词b在形式上完全相同,但在语义上是几乎无关的。比如“苹果”和”Mac”, “ios”在一起时的含义与“苹果”和“农药”,“梨”, 在一起时的含义几乎是完全无关的。

关于隐含语义,有一个最基本的原则:在大型的文档集中,两个词的语义越相近,它们共现的概率也就越大。这样,我们可以利用对于词项和文档之间关系的分析,得到概念与词项之间的关系。这里的概念其实也叫主题,比如上面说的“中国”和“China”,“电脑”和“计算机”等等虽然形式上不同,却是属于同一主题的。

以上就是LSI的动机了,接下来,我们一步步推导,如何利用词项和文档之间关系的分析,得到概念与词项之间的关系。

奇异值分解的作用

从词项到概念,很容易想到降维的方法,即把表达同一个概念的多个词项通过降维的方式映射到一个维度上。这一点和PCA(主成分分析)的基本思想是一致的:PCA能实现降维是因为不同的数据维度之间存在相关关系,比如 x 越大, y 也越大这种情况,这种相关关系在坐标系上的直观体现就是可以先转换坐标系,再将这些点映射到低维的超平面上;而词项的检索也是一样,不同词项之间也可能存在着相关关系,比如,如果词 a 出现,则词 b 以极大的概率出现,相应的,我们自然想到可以用类似于PCA的降维方式对词项-文档矩阵降维,使得每个文档对应的词向量的维度降低。而维度降低之后的元素则不是词项了,我们把它叫做“概念”(或者叫“主题”)。降维是LSI的核心思想,只不过他的出发点不是要加速计算,而是解决如何将一个个的词,映射为统一的语义(概念、主题)。实际上,LSI的处理方法与PCA在最后一步是有所不同的,看完本文你会发现,对于搜索算法的复杂度来说,LSI并未真正降维,而是将每个维度的词变换为一个词义。换句话说,LSI实现的是一种概念匹配,而不是VSM所依据的词项匹配。

注1:关于主成分分析(PCA)的详细介绍可以参照我的博客:主成分分析(PCA)原理与实现

注2:关于奇异值分解(SVD)的详细介绍可以参照我的博客:矩阵的分解:满秩分解和奇异值分解

如果不是非常熟悉,建议可以先理解一下PCA和SVD,再看LSI.

假设现在有词项-文档矩阵(记为 A ),它由 m 个词项, n 个文档构成,为形象起见,我画出下表:

  d 1 d 2 d 3 d 4 d 5 d 6
cloud 1 0 1 0 1 0
server 1 0 1 0 0 1
hadoop 0 0 1 0 1 0
distribute 1 0 1 0 1 0
money 0 1 0 0 0 1
bank 0 1 0 1 0 1
tax 0 1 0 1 0 0

表中的数据是我故意这样设置的,大家一眼就能看出来,它分为了2个概念,一个是计算机学科的,一个是经济学的。这样方便后面的计算举例。

和PCA的方法一样,现在对 A 做奇异值分解。关于奇异值分解的原理和实现,我在之前的博客 中已经给出了详细的阐述,这里略过,直接给出结论:

(5) A = U m × m Σ m × n V n × n T

拿上面表格中的例子来说,奇异值分解为如下的形式:

(6) A = U Σ V T = ( 0.55 0.16 1.52 1.34 0.31 0.18 0.71 0.47 0.13 0.67 0.28 0.36 0.33 0 0.38 0.13 0.35 0.63 0.52 0.21 0 0.55 0.16 0.15 0.13 0.31 0.18 0.71 0.11 0.49 0.26 0.57 0.56 0.20 0 0.13 0.68 0.08 0.03 0.31 0.64 0 0.05 0.46 0.55 0.40 0.04 0.57 0 ) ( 3.0 0 0 0 0 0 0 2.45 0 0 0 0 0 0 1.35 0 0 0 0 0 0 0.84 0 0 0 0 0 0 0.56 0 0 0 0 0 0 0.3 0 0 0 0 0 0 ) ( 0.52 0.10 0.65 0.06 0.49 0.23 0.08 0.67 0.13 0.47 0.19 0.53 0.27 0.27 0.01 0.47 0.49 0.63 0.65 0.17 0.10 0.51 0.43 0.31 0.46 0.51 0.46 0.49 0.17 0.20 0.12 0.43 0.58 0.26 0.52 0.36 )

上式的计算可以通过Python的Numpy库直接计算得到,代码如下:

import numpy as np

A = np.array([[1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 0, 1], [0, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 1], [0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 0]])

U, Sigma, VT = np.linalg.svd(A)

print(U)
print(Sigma)
print(VT)

至于分解的意义,放到LSI中,可以这样理解:奇异值构成的对角矩阵 Σ 中(假设 Σ 秩为 r ),那么这 r 个元素其实代表了 r 个概念,而相应的值则代表了 r 个概念在文档集中的用于区分文档的显著程度。根据信息检索中数据的特征提取的原则,当然是区分程度越好的特征越应该被当做索引项。为了起到降维的作用,我们再次选取较大的 k 个特征值保留,而将剩下的 r k 个特征值变为0。那么现在 A 的SVD分解可以近似的写成下面的形式:

(7) A = U m × m Σ k × k V n × n T

拿上面表格中的例子来说,我把奇异值3和2.44留下,再的置为0. 然后重新计算 A ,为示区别,记为 A

(8) A = U Σ V T = ( 0.55 0.16 1.52 1.34 0.31 0.18 0.71 0.47 0.13 0.67 0.28 0.36 0.33 0 0.38 0.13 0.35 0.63 0.52 0.21 0 0.55 0.16 0.15 0.13 0.31 0.18 0.71 0.11 0.49 0.26 0.57 0.56 0.20 0 0.13 0.68 0.08 0.03 0.31 0.64 0 0.05 0.46 0.55 0.40 0.04 0.57 0 ) ( 3 0 0 0 0 0 0 2.45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ( 0.52 0.10 0.65 0.06 0.49 0.23 0.08 0.67 0.13 0.47 0.19 0.53 0.27 0.27 0.01 0.47 0.49 0.63 0.65 0.17 0.10 0.51 0.43 0.31 0.46 0.51 0.46 0.49 0.17 0.20 0.12 0.43 0.58 0.26 0.52 0.36 ) = ( 0.89 0.10 1.12 0.08 0.89 0.18 0.70 0.35 0.86 0.23 0.63 0.50 0.62 0.10 0.78 0.08 0.62 0.10 0.89 0.10 1.12 0.08 0.89 0.18 0.08 0.83 0.06 0.58 0.06 0.71 0.07 1.14 0.03 0.80 0.12 0.97 0.01 0.77 0.05 0.54 0.13 0.64 ) = A

观察一下这个新的 A 矩阵和 A 的区别:

  • 形状是一样的,可见LSI降维的目的只是整合概念,计算的复杂度并没有降低;
  • 文档中不曾出现的词项也是有权重的,只是会小一点,比如词hadoop没有出现在文档1中,但是你看他的权重现在是0.62,说明还是很相关的;
  • 新矩阵的每个元素 A [ i ] [ j ] 实际上代表词 t i 在文档 d j 中的词义权重,而并非 A 中的存在性;

做完以上步骤,LSI的主要工作就完成了,我们得到了很重要的一个东西:词义-文档矩阵,也就是上式中近似分解计算出来的 A 。其中每个列向量代表了一个文档,这个文档的每个元素由“词义”决定,而并非最初用的存在性(即0或1)。

文档相似度的计算

现在要解决的问题是如何利用 A 计算查询和文档的相关度。基于关键词的检索,从具体的应用上来说分为两种:一是通过关键词查找相关文档;二是通过文档之间由关键词构成的向量计算文档之间的相似度。无论是哪一种方法,道理是一样的,都是计算两个向量之间的相似度。那就先来看看文档相似度的计算:这个很简单,直接根据新生成的概念-文档矩阵 A 中的两个行向量,计算其相似度即可(比如计算内积或者余弦相似度)。那么通过关键词构成的查询向量查询文档呢?一样的做法,将查询向量看成一个“伪文档”,和真实的文档集放在一起做SVD,再如同计算文档之间的相似度那样,计算即可。

总结

综上所述,我们可以清晰地总结出LSI的优缺点:

优点:

  • 算法原理很简单,一次奇异值分解即可;
  • 对于隐私语义的检索,实验发现确实效果不错;

缺点:

  • 每一次查询都要重新计算一次SVD,而SVD是十分消耗计算资源的;
  • 概念数量 k 的选择并不容易;
  • LSI得到的不是一个概率模型,缺乏统计基础,结果难以直观的解释;

猜你喜欢

转载自blog.csdn.net/guoziqing506/article/details/81007364
今日推荐