# 相似性查詢
別忘了設置
```py
>>> import logging
>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
```
如果你想看到記錄事件。
## [相似性界面](https://radimrehurek.com/gensim/tut3.html#similarity-interface "永久鏈接到這個標題")
在之前關于[Corpora和向量空間](https://radimrehurek.com/gensim/tut1.html)以及[主題和轉換的](https://radimrehurek.com/gensim/tut2.html)教程中,我們介紹了在向量空間模型中創建語料庫以及如何在不同向量空間之間進行轉換的含義。這種特征的一個常見原因是我們想要確定?**文檔對****之間**的**相似性**,或者**特定文檔與一組其他文檔**(例如用戶查詢與索引文檔)**之間**的**相似性**。
為了說明在gensim中如何做到這一點,讓我們考慮與之前的例子相同的語料庫(它最初來自Deerwester等人的[“潛在語義分析索引”](http://www.cs.bham.ac.uk/~pxt/IDA/lsa_ind.pdf)?1990年開篇?文章):
```py
>>> from gensim import corpora, models, similarities
>>> dictionary = corpora.Dictionary.load('/tmp/deerwester.dict')
>>> corpus = corpora.MmCorpus('/tmp/deerwester.mm') # comes from the first tutorial, "From strings to vectors"
>>> print(corpus)
MmCorpus(9 documents, 12 features, 28 non-zero entries)
```
按照Deerwester的例子,我們首先使用這個小的語料庫來定義一個二維LSI空間:
```py
>>> lsi = models.LsiModel(corpus, id2word=dictionary, num_topics=2)
```
現在假設用戶輸入查詢“人機交互”。我們希望按照與此查詢相關的遞減順序對我們的九個語料庫文檔進行排序。與現代搜索引擎不同,這里我們只關注可能相似性的一個方面 - 關于其文本(單詞)的明顯語義相關性。沒有超鏈接,沒有隨機游走靜態排名,只是布爾關鍵字匹配的語義擴展:
```py
>>> 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)]
```
此外,我們將考慮[余弦相似性](https://en.wikipedia.org/wiki/Cosine_similarity)?來確定兩個向量的相似性。余弦相似度是向量空間建模中的標準度量,但是無論向量表示概率分布,?[不同的相似性度量](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence#Symmetrised_divergence)可能更合適。
### [初始化查詢結構](https://radimrehurek.com/gensim/tut3.html#initializing-query-structures "永久鏈接到這個標題")
為了準備相似性查詢,我們需要輸入我們想要與后續查詢進行比較的所有文檔。在我們的例子中,它們與用于訓練LSI的九個文件相同,轉換為二維LSA空間。但這只是偶然的,我們也可能完全索引不同的語料庫。
```py
>>> index = similarities.MatrixSimilarity(lsi[corpus]) # transform corpus to LSI space and index it
```
> 警告
* `similarities.MatrixSimilarity`只有當整個向量集適合內存時,該類才適用。例如,當與此類一起使用時,一百萬個文檔的語料庫在256維LSI空間中將需要2GB的RAM。
* 如果沒有2GB的可用RAM,則需要使用`similarities.Similarity`該類。此類通過在磁盤上的多個文件(稱為分片)之間拆分索引,在固定內存中運行。它使用`similarities.MatrixSimilarity`和`similarities.SparseMatrixSimilarity`內部,所以它仍然很快,雖然稍微復雜一點。
索引持久性通過標準`save()`和`load()`函數處理:
```py
>>> index.save('/tmp/deerwester.index')
>>> index = similarities.MatrixSimilarity.load('/tmp/deerwester.index')
```
對于所有相似性索引類(`similarities.Similarity`,?`similarities.MatrixSimilarity`和`similarities.SparseMatrixSimilarity`)都是如此。同樣在下文中,索引可以是任何這些的對象。如果有疑問,請使用`similarities.Similarity`,因為它是最具擴展性的版本,并且它還支持稍后向索引添加更多文檔。
### [執行查詢](https://radimrehurek.com/gensim/tut3.html#performing-queries "永久鏈接到這個標題")
要獲得我們的查詢文檔與九個索引文檔的相似性:
```py
>>> sims = index[vec_lsi] # perform a similarity query against the corpus
>>> print(list(enumerate(sims))) # print (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)]
```
余弦測量返回范圍中的相似度(越大,越相似),因此第一個文檔的得分為0.99809301等。
使用一些標準的Python魔術,我們將這些相似性按降序排序,并獲得查詢 `人機交互` 的最終答案:
```py
>>> sims = sorted(enumerate(sims), key=lambda item: -item[1])
>>> print(sims) # print sorted (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
```
(我將原始文檔以“字符串形式”添加到輸出注釋中,以提高清晰度。)
這里要注意的是文件沒有。標準布爾全文搜索永遠不會返回2(`EPS用戶界面管理系統`)和4(`用戶感知響應時間與錯誤測量的關系`),因為他們不與 `人機交互` 分享任何常用詞。然而,在應用LSI之后,我們可以觀察到它們都獲得了相當高的相似性得分(第2個實際上是最相似的!),這更符合我們對它們與查詢共享 `computer-human` 相關主題的直覺。事實上,這種語義概括是我們首先應用轉換并進行主題建模的原因。
## [下一個在哪里](https://radimrehurek.com/gensim/tut3.html#where-next "永久鏈接到這個標題")
恭喜你,你已經完成了教程-現在你知道作品:-)深入到更多的細節如何gensim,您可以通過瀏覽[API文檔](https://radimrehurek.com/gensim/apiref.html),請參閱[維基百科的實驗](https://radimrehurek.com/gensim/wiki.html)或者是退房[分布式計算](https://radimrehurek.com/gensim/distributed.html)中gensim。
gensim是一個相當成熟的軟件包,已被許多個人和公司成功使用,用于快速原型制作和生產。這并不意味著它是完美的:
* 有些部分可以更有效地實現(例如,在C中),或者更好地利用并行性(多個機器內核)
* 新算法一直在發布;?幫助gensim通過[討論](https://groups.google.com/group/gensim)和[貢獻代碼](https://github.com/piskvorky/gensim/wiki/Developer-page)來跟上[](https://github.com/piskvorky/gensim/wiki/Developer-page)
* 您的**反饋非常受歡迎**和贊賞(而且不僅僅是代碼!):?[創意貢獻](https://github.com/piskvorky/gensim/wiki/Ideas-&-Features-proposals),?[錯誤報告](https://github.com/piskvorky/gensim/issues)或只考慮貢獻?[用戶故事和一般問題](https://groups.google.com/group/gensim/topics)。
在所有NLP(甚至機器學習)子域中,gensim沒有野心成為一個包羅萬象的框架。它的使命是幫助NLP從業者輕松地在大型數據集上嘗試流行的主題建模算法,并促進研究人員對新算法的原型設計。