15分鐘入門Gensim
來自專欄機器學習演算法工程師
gensim簡介
作為自然語言處理愛好者,大家都應該聽說過或使用過大名鼎鼎的Gensim吧,這是一款具備多種功能的神器。
Gensim是一款開源的第三方Python工具包,用於從原始的非結構化的文本中,無監督地學習到文本隱層的主題向量表達。它支持包括TF-IDF,LSA,LDA,和word2vec在內的多種主題模型演算法,支持流式訓練,並提供了諸如相似度計算,信息檢索等一些常用任務的API介面
基本概念
- 語料(Corpus):一組原始文本的集合,用於無監督地訓練文本主題的隱層結構。語料中不需要人工標註的附加信息。在Gensim中,Corpus通常是一個可迭代的對象(比如列表)。每一次迭代返回一個可用於表達文本對象的稀疏向量。
- 向量(Vector):由一組文本特徵構成的列表。是一段文本在Gensim中的內部表達。
- 稀疏向量(SparseVector):通常,我們可以略去向量中多餘的0元素。此時,向量中的每一個元素是一個(key, value)的元組
- 模型(Model):是一個抽象的術語。定義了兩個向量空間的變換(即從文本的一種向量表達變換為另一種向量表達)。
步驟一:訓練語料的預處理
由於Gensim使用python語言開發的,為了減少安裝中的繁瑣,直接使用anaconda工具進行集中安裝,
輸入:pip install gensim,這裡不再贅述。訓練語料的預處理指的是將文檔中原始的字元文本轉換成Gensim模型所能理解的稀疏向量的過程。
通常,我們要處理的原生語料是一堆文檔的集合,每一篇文檔又是一些原生字元的集合。在交給Gensim的模型訓練之前,我們需要將這些原生字元解析成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的每一個元素對應一篇文檔。
接下來,我們可以調用Gensim提供的API建立語料特徵(此處即是word)的索引字典,並將文本特徵的原始表達轉化成詞袋模型對應的稀疏向量的表達。依然以詞袋模型為例:
from gensim import corporadictionary = 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 theres 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 modelstfidf = 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/test.index)index = similarities.MatrixSimilarity.load(/tmp/test.index)
注意,如果待檢索的目標文檔過多,使用similarities.MatrixSimilarity類往往會帶來內存不夠用的問題。此時,可以改用similarities.Similarity類。二者的介面基本保持一致。
最後,我們藉助index對象計算任意一段query和所有文檔的(餘弦)相似度:
sims = index[query_vec] #返回一個元組類型的迭代器:(idx, sim)
常見主題模型總結
TF-IDF
TF-IDF(注意:這裡不是減號)是一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。
字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降。TF-IDF加權的各種形式常被搜索引擎應用,作為文件與用戶查詢之間相關程度的度量或評級。1. 一個詞預測主題能力越強,權重就越大,反之,權重就越小。我們在網頁中看到「原子能」這個詞,或多或少地能了解網頁的主題。我們看到「應用」一次,對主題基本上還是一無所知。因此,「原子能「的權重就應該比應用大。2. 應刪除詞的權重應該是零。LDA文檔主題生成模型
LDA是一種文檔主題生成模型,包含詞、主題和文檔三層結構。
所謂生成模型,就是說,我們認為一篇文章的每個詞都是通過「以一定概率選擇了某個主題,並從這個主題中以一定概率選擇某個詞語」這樣一個過程得到。文檔到主題服從多項式分布,主題到詞服從多項式分布。
LDA是一種非監督機器學習技術,可以用來識別大規模文檔集或語料庫中潛藏的主題信息。它採用了詞袋的方法,這種方法將每一篇文檔視為一個詞頻向量,從而將文本信息轉化為了易於建模的數字信息。
但是詞袋方法沒有考慮詞與詞之間的順序,這簡化了問題的複雜性,同時也為模型的改進提供了契機。每一篇文檔代表了一些主題所構成的一個概率分布,而每一個主題又代表了很多單詞所構成的一個概率分布。
小結
gensim作為一款強大且開源的工具包非常值得我們花時間學習,如果對搜索引擎和自然語言處理感興趣,更需要深入學習。在學習過程中建議大家多關注一些牛人博客,並進行歸納。這裡只是拋磚引玉,想了解更多機器學習相關知識,請關注我們公眾號:機器學習演算法全棧工程師。
參考資料
公子天:https://www.cnblogs.com/iloveai/p/gensim_tutorial.html
官網:https://radimrehurek.com/gensim/推薦閱讀:
TAG:深度學習DeepLearning | 數據挖掘 | 自然語言處理 |