潜在语义分析
主题模型
在介绍PLSA之前,我们先来了解一下主题模型。主题是表达一个完整清晰语义的词的集合,通过主题抽取,可以很方便地获得一个语料集合上的主要语义信息。每个主题可以理解成一个在所有词汇上的权重,通过选择在一个猪体内具有高权重的若干个词汇,就可以形成主题语义信息的可视化。供用户理解。
作用
当我们试图通过VSM之类的方法,比较词来找到相关的文本时,存在着难以解决的局限性,那就是在搜索中我们实际想要去比较的不是词,而是隐藏在词之后的意义和概念。LSA试图去解决这个问题,它把词和文档都映射到一个“概念”空间,并在这个空间内进行比较。
当文档的作者写作的时候,对于词语有着非常宽泛的选择。不同的作者对于词语的选择有着不同的偏好,这样会导致概念的混淆。这种对于词语的随机选择在词-概念的关系中引入了噪音。
LSA创新地引入了语义维度,语义维度是文档集合上相同和相关信息的浓缩表示。如果将每一个维度对应表示到空间中的一个轴,则形成了一个语义维度空间。LSA的本质想法就是考虑词与词在文档中的共现,通过线性代数的方法来提取这些语义维度。然后实现文档在语义空间上的降维表示。显然,LSA的主要目的是发现隐含的予以模式,学到的语义维度的数量都远远小于词典空间中词汇的数量。因此,LSA滤除了同义词这样的一些噪音,并且还能够从全部的文档中找到最小的概念集合。
假设
就像VSM的正交假设那样,传统的潜在语义分析模型,也对文本存在着一些假设:
- 文档被表示为词的集合,词在文档中出现的位置对于LSA并不重要。
- 概念被表示成经常出现在一起的一些词的某种模式。例如"leash"(栓狗的皮带)、"treat"、"obey"(服从)经常出现在关于训练狗的文档中。
- 一个词被认为只有一个意思。
- 生成的主题向量之间是正交的。
索引词
在LSA中,我们需要索引词作为分解的材料。
作为索引词,有几个条件:
- 在2个或者2个以上文档中出现
- 不是本身没有意义的停用词
实现
LSA的第一步是要去创建词到标题(文档)的矩阵。在这个矩阵里,每一个索引词占据了一行,每一个文档占据一列。每一个单元(cell)包含了这个索引词出现在那个文档中的次数。例如,词"book"出现在文档T3中一次,出现在T4中一次,而"investing"在所有文档中都出现了一次。一般来说,在LSA中的矩阵会非常大而且会非常稀疏(大部分的单元都是0)。这是因为每个标题或者文档一般只包含所有词汇的一小部分。更复杂的LSA算法会利用这种稀疏性去改善空间和时间复杂度。
创建矩阵的关键代码如下:
def build(self):
self.keys = [k for k in self.wdict.keys() if len(self.wdict[k]) > 1] #所有出现的词被取出
self.keys.sort() #排序
self.A = zeros([len(self.keys), self.dcount]) #建立一个矩阵,其行数是词的个数,列数是文档个数
#所有的词和文档对所对应的矩阵单元的值被统计出来
for i, k in enumerate(self.keys):
for d in self.wdict[k]:
self.A[i, d] += 1 #创建出的矩阵
下面将创建的矩阵进行奇异值分解,分解为三个低维度的矩阵——词汇向量矩阵T
,对角阵S
,文档向量矩阵D
。
T,S,D = svd(self.A)
下面保留S
中最大的K
个奇异值(也就是对角值)使得其有:
self.A≈self.A_K=T_K*S_K*D_K
这样,D
和T
都被缩成了K
列,其中T
的每一列就是一个主题,而D
的每一行就是一个文档对应在这K
个主题向量上的系数表示。对于多个文档,这K
个主题向量是共享的,但是线性结合系数(也就是不同主题在不同文档上的权重)是特定的。主题向量每个维度(也就是cell)的数值表示该主题内对应词汇的权重。这样,我们就成功的表示了文本的潜在语义。
完整代码参照这里
问题
目前普遍使用的SVD分解方法是典型LSA空间的构造方法,主要步骤就是对文本集的词条-文本矩阵的奇异值分解并提取K
个最大的奇异值及其对应的奇异矢量构成新矩阵来近似表示原文本集的词条-文本矩阵。但是它也有很多不足。
- 首要的问题是词条-文本矩阵的SVD计算时间代价,SVD算法的时间代价是
O(N^2*K^3)
,其中N
是单词数和文本数的乘积,K
是LSA空间的维数(K值一般在100~300),N
随着文本数和单词数的增加迅速地增长,这就使得SVD算法不太合适于大规模动态变化的数据集。 - 其次是空间维数
K
值的选取问题。使用SVD分解目的是利用潜在的语义空间来表示词条和文本,它提取的潜在语义空间难以解释、调试和衡量,以至于难以确定最优的空间大小(即K
值的最佳大小),而降维因子K
值的选取直接关系到语义空间模型的效率,K
值过小则会使一些有用的信息丢失,K
值过大则会使运算量增加,根据不同的文本集和处理要求,最佳的K
值也不尽相同。
为了解决这些问题,Probabilistic LSA算法被提出。PLSA是一种基于生成概率的模型。不同于SVD追求矩阵间的最小方差和,PLSA遵循最大可能性的原则。