轉自:公子天的技術博客 html
Gensim是一款開源的第三方Python工具包,用於從原始的非結構化的文本中,無監督地學習到文本隱層的主題向量表達。它支持包括TF-IDF,LSA,LDA,和word2vec在內的多種主題模型算法,支持流式訓練,並提供了諸如類似度計算,信息檢索等一些經常使用任務的API接口。python
訓練語料的預處理指的是將文檔中原始的字符文本轉換成Gensim模型所能理解的稀疏向量的過程。git
一般,咱們要處理的原生語料是一堆文檔的集合,每一篇文檔又是一些原生字符的集合。在交給Gensim的模型訓練以前,咱們須要將這些原生字符解析成Gensim能處理的稀疏向量的格式。github
因爲語言和應用的多樣性,Gensim沒有對預處理的接口作出任何強制性的限定。一般,咱們須要先對原始的文本進行分詞、去除停用詞等操做,獲得每一篇文檔的特徵列表。例如,在詞袋模型中,文檔的特徵就是其包含的word:算法
texts = [['human', 'interface', 'computer'], ['survey', 'user', 'computer', 'system', 'response', 'time'], ['eps', 'user', 'interface', 'system'], ['system', 'human', 'system', 'eps'], ['user', 'response', 'time'], ['trees'], ['graph', 'trees'], ['graph', 'minors', 'trees'], ['graph', 'minors', 'survey']]
其中,corpus的每個元素對應一篇文檔。api
接下來,咱們能夠調用Gensim提供的API創建語料特徵(此處便是word)的索引字典,並將文本特徵的原始表達轉化成詞袋模型對應的稀疏向量的表達。依然以詞袋模型爲例:函數
from gensim import corpora dictionary = corpora.Dictionary(texts) corpus = [dictionary.doc2bow(text) for text in texts] print corpus[0] # [(0, 1), (1, 1), (2, 1)]
到這裏,訓練語料的預處理工做就完成了。咱們獲得了語料中每一篇文檔對應的稀疏向量(這裏是bow向量);向量的每個元素表明了一個word在這篇文檔中出現的次數。值得注意的是,雖然詞袋模型是不少主題模型的基本假設,這裏介紹的doc2bow
函數並非將文本轉化成稀疏向量的惟一途徑。在下一小節裏咱們將介紹更多的向量變換函數。工具
最後,出於內存優化的考慮,Gensim支持文檔的流式處理。咱們須要作的,只是將上面的列表封裝成一個Python迭代器;每一次迭代都返回一個稀疏向量便可。學習
class MyCorpus(object): def __iter__(self): for line in open('mycorpus.txt'): # assume there's one document per line, tokens separated by whitespace yield dictionary.doc2bow(line.lower().split())
對文本向量的變換是Gensim的核心。經過挖掘語料中隱藏的語義結構特徵,咱們最終能夠變換出一個簡潔高效的文本向量。優化
在Gensim中,每個向量變換的操做都對應着一個主題模型,例如上一小節提到的對應着詞袋模型的doc2bow
變換。每個模型又都是一個標準的Python對象。下面以TF-IDF模型爲例,介紹Gensim模型的通常使用方法。
首先是模型對象的初始化。一般,Gensim模型都接受一段訓練語料(注意在Gensim中,語料對應着一個稀疏向量的迭代器)做爲初始化的參數。顯然,越複雜的模型須要配置的參數越多。
from gensim import models tfidf = models.TfidfModel(corpus)
其中,corpus是一個返回bow向量的迭代器。這兩行代碼將完成對corpus中出現的每個特徵的IDF值的統計工做。
接下來,咱們能夠調用這個模型將任意一段語料(依然是bow向量的迭代器)轉化成TFIDF向量(的迭代器)。須要注意的是,這裏的bow向量必須與訓練語料的bow向量共享同一個特徵字典(即共享同一個向量空間)。
doc_bow = [(0, 1), (1, 1)] print tfidf[doc_bow] # [(0, 0.70710678), (1, 0.70710678)]
注意,一樣是出於內存的考慮,model[corpus]
方法返回的是一個迭代器。若是要屢次訪問model[corpus]
的返回結果,能夠先講結果向量序列化到磁盤上。
咱們也能夠將訓練好的模型持久化到磁盤上,以便下一次使用:
tfidf.save("./model.tfidf") tfidf = models.TfidfModel.load("./model.tfidf")
Gensim內置了多種主題模型的向量變換,包括LDA,LSI,RP,HDP等。這些模型一般以bow向量或tfidf向量的語料爲輸入,生成相應的主題向量。全部的模型都支持流式計算。關於Gensim模型更多的介紹,能夠參考這裏:API Reference
在獲得每一篇文檔對應的主題向量後,咱們就能夠計算文檔之間的類似度,進而完成如文本聚類、信息檢索之類的任務。在Gensim中,也提供了這一類任務的API接口。
以信息檢索爲例。對於一篇待檢索的query,咱們的目標是從文本集合中檢索出主題類似度最高的文檔。
首先,咱們須要將待檢索的query和文本放在同一個向量空間裏進行表達(以LSI向量空間爲例):
# 構造LSI模型並將待檢索的query和文本轉化爲LSI主題向量 # 轉換以前的corpus和query均是BOW向量 lsi_model = models.LsiModel(corpus, id2word=dictionary, num_topics=2) documents = lsi_model[corpus] query_vec = lsi_model[query]
接下來,咱們用待檢索的文檔向量初始化一個類似度計算的對象:
index = similarities.MatrixSimilarity(documents)
咱們也能夠經過save()
和load()
方法持久化這個類似度矩陣:
index.save('/tmp/deerwester.index') index = similarities.MatrixSimilarity.load('/tmp/deerwester.index')
注意,若是待檢索的目標文檔過多,使用similarities.MatrixSimilarity
類每每會帶來內存不夠用的問題。此時,能夠改用similarities.Similarity
類。兩者的接口基本保持一致。
最後,咱們藉助index
對象計算任意一段query和全部文檔的(餘弦)類似度:
sims = index[query_vec] # return: an iterator of tuple (idx, sim)