gensim-自然語(yǔ)言處理(NLP)

Gensim是一款開(kāi)源的第三方Python工具包,用于從原始的非結(jié)構(gòu)化的文本中,無(wú)監(jiān)督地學(xué)習(xí)到文本隱層的主題向量表達(dá)。?

支持包括TF-IDF,LSA,LDA,和word2vec在內(nèi)的多種主題模型算法,?

支持流式訓(xùn)練,并提供了諸如相似度計(jì)算,信息檢索等一些常用任務(wù)的API接口

1.基本概念

語(yǔ)料(Corpus):一組原始文本的集合,用于無(wú)監(jiān)督地訓(xùn)練文本主題的隱層結(jié)構(gòu)。語(yǔ)料中不需要人工標(biāo)注的附加信息。在Gensim中,Corpus通常是一個(gè)可迭代的對(duì)象(比如列表)。每一次迭代返回一個(gè)可用于表達(dá)文本對(duì)象的稀疏向量。

向量(Vector):由一組文本特征構(gòu)成的列表。是一段文本在Gensim中的內(nèi)部表達(dá)。

稀疏向量(SparseVector):通常,我們可以略去向量中多余的0元素。此時(shí),向量中的每一個(gè)元素是一個(gè)(key, value)的元組

模型(Model):是一個(gè)抽象的術(shù)語(yǔ)。定義了兩個(gè)向量空間的變換(即從文本的一種向量表達(dá)變換為另一種向量表達(dá))。

2.步驟一:訓(xùn)練語(yǔ)料的預(yù)處理

由于Gensim使用python語(yǔ)言開(kāi)發(fā)的,為了減少安裝中的繁瑣,直接使用anaconda工具進(jìn)行集中安裝,?

輸入:pip install gensim,這里不再贅述。

訓(xùn)練語(yǔ)料的預(yù)處理指的是將文檔中原始的字符文本轉(zhuǎn)換成Gensim模型所能理解的稀疏向量的過(guò)程。

通常,我們要處理的原生語(yǔ)料是一堆文檔的集合,每一篇文檔又是一些原生字符的集合。在交給Gensim的模型訓(xùn)練之前,我們需要將這些原生字符解析成Gensim能處理的稀疏向量的格式。由于語(yǔ)言和應(yīng)用的多樣性,我們需要先對(duì)原始的文本進(jìn)行分詞、去除停用詞等操作,得到每一篇文檔的特征列表。例如,在詞袋模型中,文檔的特征就是其包含的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的每一個(gè)元素對(duì)應(yīng)一篇文檔。

接下來(lái),我們可以調(diào)用Gensim提供的API建立語(yǔ)料特征(此處即是word)的索引字典,并將文本特征的原始表達(dá)轉(zhuǎn)化成詞袋模型對(duì)應(yīng)的稀疏向量的表達(dá)。依然以詞袋模型為例:

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)]

到這里,訓(xùn)練語(yǔ)料的預(yù)處理工作就完成了。我們得到了語(yǔ)料中每一篇文檔對(duì)應(yīng)的稀疏向量(這里是bow向量);向量的每一個(gè)元素代表了一個(gè)word在這篇文檔中出現(xiàn)的次數(shù)。值得注意的是,雖然詞袋模型是很多主題模型的基本假設(shè),這里介紹的doc2bow函數(shù)并不是將文本轉(zhuǎn)化成稀疏向量的唯一途徑。在下一小節(jié)里我們將介紹更多的向量變換函數(shù)。

最后,出于內(nèi)存優(yōu)化的考慮,Gensim支持文檔的流式處理。我們需要做的,只是將上面的列表封裝成一個(gè)Python迭代器;每一次迭代都返回一個(gè)稀疏向量即可。

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())

3.步驟二:主題向量的變換

對(duì)文本向量的變換是Gensim的核心。通過(guò)挖掘語(yǔ)料中隱藏的語(yǔ)義結(jié)構(gòu)特征,我們最終可以變換出一個(gè)簡(jiǎn)潔高效的文本向量。

在Gensim中,每一個(gè)向量變換的操作都對(duì)應(yīng)著一個(gè)主題模型,例如上一小節(jié)提到的對(duì)應(yīng)著詞袋模型的doc2bow變換。每一個(gè)模型又都是一個(gè)標(biāo)準(zhǔn)的Python對(duì)象。下面以TF-IDF模型為例,介紹Gensim模型的一般使用方法。

首先是模型對(duì)象的初始化。通常,Gensim模型都接受一段訓(xùn)練語(yǔ)料(注意在Gensim中,語(yǔ)料對(duì)應(yīng)著一個(gè)稀疏向量的迭代器)作為初始化的參數(shù)。顯然,越復(fù)雜的模型需要配置的參數(shù)越多。

from gensim import models

tfidf = models.TfidfModel(corpus)

其中,corpus是一個(gè)返回bow向量的迭代器。這兩行代碼將完成對(duì)corpus中出現(xiàn)的每一個(gè)特征的IDF值的統(tǒng)計(jì)工作。

接下來(lái),我們可以調(diào)用這個(gè)模型將任意一段語(yǔ)料(依然是bow向量的迭代器)轉(zhuǎn)化成TFIDF向量(的迭代器)。需要注意的是,這里的bow向量必須與訓(xùn)練語(yǔ)料的bow向量共享同一個(gè)特征字典(即共享同一個(gè)向量空間)。

doc_bow = [(0, 1), (1, 1)]

print tfidf[doc_bow] # [(0, 0.70710678), (1, 0.70710678)]

注意,同樣是出于內(nèi)存的考慮,model[corpus]方法返回的是一個(gè)迭代器。如果要多次訪問(wèn)model[corpus]的返回結(jié)果,可以先將結(jié)果向量序列化到磁盤(pán)上。

我們也可以將訓(xùn)練好的模型持久化到磁盤(pán)上,以便下一次使用:

tfidf.save("./model.tfidf")

tfidf = models.TfidfModel.load("./model.tfidf")

Gensim內(nèi)置了多種主題模型的向量變換,包括LDA,LSI,RP,HDP等。這些模型通常以bow向量或tfidf向量的語(yǔ)料為輸入,生成相應(yīng)的主題向量。所有的模型都支持流式計(jì)算。關(guān)于Gensim模型更多的介紹,可以參考這里:API Reference(https://radimrehurek.com/gensim/apiref.html)

4.步驟三:文檔相似度的計(jì)算

在得到每一篇文檔對(duì)應(yīng)的主題向量后,我們就可以計(jì)算文檔之間的相似度,進(jìn)而完成如文本聚類、信息檢索之類的任務(wù)。在Gensim中,也提供了這一類任務(wù)的API接口。

以信息檢索為例。對(duì)于一篇待檢索的query,我們的目標(biāo)是從文本集合中檢索出主題相似度最高的文檔。

首先,我們需要將待檢索的query和文本放在同一個(gè)向量空間里進(jìn)行表達(dá)(以LSI向量空間為例):

# 構(gòu)造LSI模型并將待檢索的query和文本轉(zhuǎn)化為L(zhǎng)SI主題向量

# 轉(zhuǎn)換之前的corpus和query均是BOW向量

lsi_model = models.LsiModel(corpus, id2word=dictionary, ? ? ? ? ?num_topics=2)

documents = lsi_model[corpus]

query_vec = lsi_model[query]

接下來(lái),我們用待檢索的文檔向量初始化一個(gè)相似度計(jì)算的對(duì)象:

index = similarities.MatrixSimilarity(documents)

我們也可以通過(guò)save()和load()方法持久化這個(gè)相似度矩陣:

index.save('/tmp/test.index')

index = similarities.MatrixSimilarity.load('/tmp/test.index')

注意,如果待檢索的目標(biāo)文檔過(guò)多,使用similarities.MatrixSimilarity類往往會(huì)帶來(lái)內(nèi)存不夠用的問(wèn)題。此時(shí),可以改用similarities.Similarity類。二者的接口基本保持一致。

最后,我們借助index對(duì)象計(jì)算任意一段query和所有文檔的(余弦)相似度:

sims = index[query_vec]

#返回一個(gè)元組類型的迭代器:(idx, sim)

5.補(bǔ)充

TF-IDF

TF-IDF(注意:這里不是減號(hào))是一種統(tǒng)計(jì)方法,用以評(píng)估一字詞對(duì)于一個(gè)文件集或一個(gè)語(yǔ)料庫(kù)中的其中一份文件的重要程度。?

字詞的重要性隨著它在文件中出現(xiàn)的次數(shù)成正比增加,但同時(shí)會(huì)隨著它在語(yǔ)料庫(kù)中出現(xiàn)的頻率成反比下降。TF-IDF加權(quán)的各種形式常被搜索引擎應(yīng)用,作為文件與用戶查詢之間相關(guān)程度的度量或評(píng)級(jí)。?

1. 一個(gè)詞預(yù)測(cè)主題能力越強(qiáng),權(quán)重就越大,反之,權(quán)重就越小。我們?cè)诰W(wǎng)頁(yè)中看到“原子能”這個(gè)詞,或多或少地能了解網(wǎng)頁(yè)的主題。我們看到“應(yīng)用”一次,對(duì)主題基本上還是一無(wú)所知。因此,“原子能“的權(quán)重就應(yīng)該比應(yīng)用大。?

2. 應(yīng)刪除詞的權(quán)重應(yīng)該是零。

LDA文檔主題生成模型

LDA是一種文檔主題生成模型,包含詞、主題和文檔三層結(jié)構(gòu)。

所謂生成模型,就是說(shuō),我們認(rèn)為一篇文章的每個(gè)詞都是通過(guò)“以一定概率選擇了某個(gè)主題,并從這個(gè)主題中以一定概率選擇某個(gè)詞語(yǔ)”這樣一個(gè)過(guò)程得到。文檔到主題服從多項(xiàng)式分布,主題到詞服從多項(xiàng)式分布。

LDA是一種非監(jiān)督機(jī)器學(xué)習(xí)技術(shù),可以用來(lái)識(shí)別大規(guī)模文檔集或語(yǔ)料庫(kù)中潛藏的主題信息。它采用了詞袋的方法,這種方法將每一篇文檔視為一個(gè)詞頻向量,從而將文本信息轉(zhuǎn)化為了易于建模的數(shù)字信息。

但是詞袋方法沒(méi)有考慮詞與詞之間的順序,這簡(jiǎn)化了問(wèn)題的復(fù)雜性,同時(shí)也為模型的改進(jìn)提供了契機(jī)。每一篇文檔代表了一些主題所構(gòu)成的一個(gè)概率分布,而每一個(gè)主題又代表了很多單詞所構(gòu)成的一個(gè)概率分布.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容