LSA(LSI)算法簡介


前言

在信息檢索領域常用的檢索和索引算法有空間向量模型和隱語義模型。

傳統向量空間模型

向量空間模型是信息檢索領域最常用的檢索方法,其檢索過程是,將文檔集D中的所有文檔和查詢都表示成以單詞為特征的向量,特征值為每個單詞的TF-IDF值,然后使用向量空間模型(即計算查詢Q的向量和每個文檔的之間的相似度)來衡量文檔和查詢之間的相似度,從而得到和給定查詢最相關的文檔。

缺點

向量空間模型簡單的基於單詞的出現與否以及TF-IDF等信息來檢索,但是說了和寫了哪些單詞和真正要表達的意思之間有很大的區別,其中兩個最主要的阻礙是單詞的多義性(polysems)和同義性(synonymys)。多義性指的是一個單詞可能有多個意思,比如蘋果,既可以指的是水果蘋果,也可以指的是蘋果公司;而同義性指的是多個不同的詞可能表示同樣的意思,比如search和look up。同義詞和多義詞的存在使得單純基於單詞的檢索方法(比如空間向量模型等)的檢索准確度收到很大影響。

隱語義模型(latent semantic analysis-latent semantic indexing)

LSA潛在語義分析的目的,就是要找出在文檔和查詢中的真正含義,也就是潛在語義。我們希望找到一個模型,能夠獲取單詞之間的相似性。如果兩個單詞之間有很強的相關性,那么當一個單詞出現時,往往意味着另一個單詞也應該出現(同義詞);反之,如果查詢語句或者文檔中的某個單詞和其他單詞的相關性都不大,那么這個單詞可能表達的就是另外一個意思(比如在討論互聯網的文章中,apple更可能指的是apple公司,而不是水果)。

LSA(LSI)使用SVD(奇異值分解)對單詞文檔矩陣進行分解。SVD可以看作是從單詞-文檔矩陣中發現部相關的索引變量(因子),將原來的數據映射到語義空間內。在單詞-文檔矩陣中不相似的兩個文檔,,可能在語義空間內比較相似。

SVD,是對矩陣進行分解的一種方法,假設是一個t*d維的矩陣(單詞-文檔矩陣)X,可以將其分解成T*S*D,其中T為t*n維矩陣,S為n*n維對角矩陣,每個值為奇異值,D為d*n維矩陣。在對單詞文檔矩陣做SVD分解之后,我們只保存s中最大的K個奇異值,以及T和D中對應的k個奇異向量,k個奇異值構成新的對角矩陣S',則

X'=T'*S'*D'T形成了一個新的t*d矩陣。

假設索引文檔的集合如下:

A[ 1. 0. 0. 1. 1.]
  [ 1. 0. 1. 0. 1.]
  [ 0. 1. 0. 0. 0.]

對其進行分解后得到X=T*S*DT。其中T為:

[-0.71 -0.71 0. ]
[-0.71  0.71 0. ]
[ 0.     0.      1.]

S為:

 [ 2.24  0. 0]

 [0.   1.   0.]

 [0.   0.   1.]

D為:

[-0.63 0. -0.32 -0.32 -0.63]
[ 0.    0.   0.71   -0.71   0. ]
[-0.     1.     0.      0.     -0.]
[ 0.76 -0. -0.16 -0.16 -0.6 ]
[-0.12   0. 0.61 0.61 -0.49]

保留值最大的2個奇異值和其對應的奇異向量,得到的T’為

[-0.71 -0.71]
[-0.71  0.71]
[ 0.         0.]

S'為

[ 2.24        0. ]
[ 0.           1. ]

D’為:

[-0.63 0. -0.32 -0.32 -0.63]
[ 0.    0.   0.71   -0.71   0. ]

得到的新矩陣X'為:

[ 1.  0. -0. 1. 1.]
[ 1.  0.  1. 0. 1.]
[ 0.   0. 0. 0. 0.]

還原后的X’和X差別很大,這是因為我們認為之前X存在很大的噪音,X'是處理過同義詞和多義詞的結果。

在查詢時,對於給定的一個查詢,我們根據這個查詢中包含的單詞構造一個偽文檔,然后該偽文檔和D’中的每一行計算相似度(余弦相似度)來給定與查詢最相似的文檔。

詳細python代碼如下:

 1 import string
 2 import types
 3 from numpy import *
 4 from numpy.linalg import svd
 5 def main():
 6        A=array([
 7        [1.,0.,0.,1.,1.],
 8        [1.,0.,1.,0.,1.],
 9        [0.,1.,0.,0.,0.]
10       ])
11       print 'A',A
12       T,S,D=svd(A)
13       print 'T',T
14       print 'S',S
15       print 'D',D
16       print 'T'
17       for x in T:
18           print around(x,decimals=2)
19       print 'S'
20       for x in S:
21           print around(x,decimals=2)
22      print 'D'
23      for x in D: 
24         print around(x,decimals=2)
25       print '*'*100
26       k=2
27       S1=zeros(shape=(k,k))
28       S1[:k,:k]=diag(S[:k])
29       T=delete(T,s_[k:],axis=1)
30       D=delete(D,s_[k:],axis=0)
31       print 'T'
32       for x in T:
33           print around(x,decimals=2)
34       print 'S1',S1
35       print 'D'
36       for x in D:
37           print around(x,decimals=2)
38       B=dot(T,dot(S1,D))
39       print 'B',B
40       for x in B:
41           print around(x,decimals=2)
42   if __name__=='__main__':
43  43     main()

參考文獻:

[1] Indexing by Latent Semantic Analysis.Scott Deerwester, Susan T. Dumais, George W.Furnas, Thomas K.Landauer, Richard Harshman.

[2] Latent Semantic Analysis Note.Zhou Li

[3] 推薦系統實踐.項亮

友情參考:http://www.cnblogs.com/kemaswill/archive/2013/04/17/3022100.html

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM