天天看點

gensim文檔-相似性查詢 相似性接口 初始化查詢結構 進行查詢 接下來是什麼?

原文連結

http://cloga.info/python/2014/01/28/Gensim_Similarity_Queries/

28 January 2014

如果你想要檢視logging事件不要忘記設定。

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
           

相似性接口

在前面語料與向量空間的教程及主題和轉換的教程中,我們涵蓋了什麼是在向量空間中建立一個語料庫以及如何在不同的向量空間間轉換。繞這樣一個圈子的原因是我們想要判斷一堆文檔的相似性,或者特定文檔與一組其他文檔的相似性(比如使用者查詢 vs. 索引文檔)。

為了展示gensim如何做到這一點,讓我們看一下前面例子中語料(最初來自Deerwester等的“Indexing by Latent Semantic Analysis” seminal 1990 article):

from gensim import corpora, models, similarities
dictionary = corpora.Dictionary.load('/tmp/deerwester.dict')
corpus = corpora.MmCorpus('/tmp/deerwester.mm') # 來自一篇教程“從字元到向量”
print corpus

MmCorpus(9 documents, 12 features, 28 non-zero entries)
           

遵循Deerwester的例子,我們首先使用這個小樣本語料定義一個二維的LSI空間:

現在假設使用者輸入查詢“Human computer interaction”。我們會想要以與查詢相似度降序排列我們的9個語料。與現代搜尋引擎不同,這裡我們隻關注可能相似的一個方面-文檔(詞)的表面抑郁相關。沒有超連結,靜态排名的随機遊走,隻有在布爾關鍵詞比對的語義擴充:

doc = "Human computer interaction"
vec_bow = dictionary.doc2bow(doc.lower().split())
vec_lsi = lsi[vec_bow] # convert the query to LSI space
print vec_lsi

[(0, -0.461821), (1, 0.070028)]
           

此外,我們将用餘弦相似性來決定兩個向量間的相似性。餘弦相似性是向量空間模型中的标準度量,但是,當向量代表機率分布時,不同的相似性度量可能更适合。

初始化查詢結構

要準備相似性查詢,我們需要輸入所有想要與随後的查詢比較的所有文檔。在這種情況下,還是用于訓練LSI的9個文檔被轉化為二維空間。但是,這隻是偶然,我們也可能索引不同的的語料。

警告

similarities.MatrixSimilarity這個類隻适用于所有語料可以放入記憶體的情況。例如,使用這個類,256維的LSI空間中的100萬文檔會需要2G的記憶體。

如果沒有2G的可用記憶體,你需要使用similarities.Similarity類。這個類通過在硬碟的多個檔案上分割索引,這些檔案稱為 shards,使用固定記憶體運作。它在内部使用similarities.MatrixSimilarity及similarities.SparseMatrixSimilarity,是以,仍然很快,盡管有點更加複雜。

索引的持久化通過标準的save()和load()函數處理:

index.save('/tmp/deerwester.index')
index = similarities.MatrixSimilarity.load('/tmp/deerwester.index')
           

所有的索引類都是這樣的(similarities.Similarity, similarities.MatrixSimilarity和similarities.SparseMatrixSimilarity)。接下來這些也是,索引可以是這類中的任何一個對象。如果不确定,使用similarities.Similarity,因為這是擴充性最好的版本,并且它還支援後續為索引添加更多的文檔。

進行查詢

獲得查詢文檔對9個索引文檔的相似性:

sims = index[vec_lsi] # 進行語料的相似查詢
print list(enumerate(sims)) # 列印(document_number, document_similarity) 2-tuples

[(0, 0.99809301), (1, 0.93748635), (2, 0.99844527), (3, 0.9865886), (4, 0.90755945),
(5, -0.12416792), (6, -0.1063926), (7, -0.098794639), (8, 0.05004178)]
           

餘弦度量傳回的的相似性在<-1,1>之前(越大越相似),是以,第一個文檔的總分為0.99809301。

使用類似的标準Python魔法,我們可以将相似性降序排列,獲得“Human computer interaction”查詢的最終答案:

sims = sorted(enumerate(sims), key=lambda item: -item[1])
print sims # 列印排序的 (document number, similarity score) 2-tuples

[(2, 0.99844527), # The EPS user interface management system
(0, 0.99809301), # Human machine interface for lab abc computer applications
(3, 0.9865886), # System and human system engineering testing of EPS
(1, 0.93748635), # A survey of user opinion of computer system response time
(4, 0.90755945), # Relation of user perceived response time to error measurement
(8, 0.050041795), # Graph minors A survey
(7, -0.098794639), # Graph minors IV Widths of trees and well quasi ordering
(6, -0.1063926), # The intersection graph of paths in trees
(5, -0.12416792)] # The generation of random binary unordered trees
           

(為了更清晰,我在輸出中用評論添加了原始文檔的”字元形式”。)

這裡注意的是第二号("The EPS user interface management system")及第四号("Relation of user perceived response time to error measurement")文檔永遠也不會傳回一個标準的布爾全文搜尋,因為它們與"Human computer interaction"沒有相同的詞。但是,應用LSI後,我們可以看到他們獲得了很高的相似性分數(二号實際上是最相似!),更好的反映了我們的直覺,他們與查詢都是關于“計算機-人類”這個話題。事實上,這句語言概括也是首先應用主題模組化的原因。

接下來是什麼?

祝賀你,你完成了教程-現在你知道了gensim如何工作:-)要研究更多細節,你需要看一下API文檔,檢視維基百科實驗或者看一下gensim中分布計算。

Gensim是相當成熟的包,被許多個人和公司成功應用,無論是快速原型還是在生産環境。 但是,這不意味這它是完美的:

  • 有許多部分應該更有效的實作(比如說用C),或者使用更好的并行機制(多核)
  • 新算法層出不窮;通過讨論幫助gensim保持更新并且貢獻代碼
  • 非常歡迎和感激你的回報(不僅僅是代碼!):貢獻思想、報告bug或者考慮共享使用者故事和一般問題

Gensim沒有野心稱為一個無所不包的架構,涉及所有NLP(甚至機器學習)的領域。它的使命是幫助NLP從業者輕松在大資料集上嘗試流行主題模組化算法,并且幫助研究者設計算法原型。