gensim使用方法以及例子


gensim是一個Python的自然語言處理庫,能夠將文檔根據TF-IDF,LDA,LSI等模型轉換成向量模式,此外,gensim還實現了word2vec,能夠將單詞轉換為詞向量。

 

1. corpora和dictionary

1.1 基本概念和用法

corpora是gensim中的一個基本概念,是文檔集的表現形式。corpora就是一個二維矩陣。舉例:

1 hurry up
2 rise up

這兩篇文檔總共就3個詞,hurry,rise,up。如果將這3個詞映射到數字,比如說hurry, rise, up分別對應1,2,3,那么上述的文檔集的一種表現形式可以是:

1 1,0,1
2 0,1,1

 這種方法只考慮詞頻,不考慮詞語間的位置關系。因為第一個文檔中的兩個詞分別編號1,3且都只出現了一次,所以第1個和第3個為1,第2個為0。

在實際運行中,單詞數量極多(上萬甚至10萬級別),而一篇文檔的單詞數是有限的,這時采用密集矩陣來表示的話,會造成極大的內存浪費,所以gensim內部是用稀疏矩陣的形式來表示。

 

如何將文檔轉化為上述形式?

這里就要提到詞典的感念(dictionary)。詞典是所有文檔中所有單詞的集合,而且記錄了各詞的出現次數等信息。

對於字符串形式的文檔,首先要將字符串分割成詞語列表。如:"hurry up"要分割成['hurry', 'up']。對於中文來講,一般用jieba。

將文檔分割成詞語之后,使用dictionary = corpora.Dictionary(texts)生成詞典,並可以使用save函數將詞典持久化。

生成詞典后corpus = [dictionary.doc2bow(text) for text in texts]轉化為向量形式

 

例1:

 

例2:

from gensim import corpora
from collections import defaultdict
documents = ["Human machine interface for lab abc computer applications",
             "A survey of user opinion of computer system response time",
             "The EPS user interface management system",
             "System and human system engineering testing of EPS",
             "Relation of user perceived response time to error measurement",
             "The generation of random binary unordered trees",
             "The intersection graph of paths in trees",
             "Graph minors IV Widths of trees and well quasi ordering",
             "Graph minors A survey"]

# 去掉停用詞
stoplist = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stoplist]
         for document in documents]

# 去掉只出現一次的單詞
frequency = defaultdict(int)
for text in texts:
    for token in text:
        frequency[token] += 1
texts = [[token for token in text if frequency[token] > 1]
         for text in texts]

dictionary = corpora.Dictionary(texts)   # 生成詞典

# 將文檔存入字典,字典有很多功能,比如
# diction.token2id 存放的是單詞-id key-value對
# diction.dfs 存放的是單詞的出現頻率
dictionary.save('/tmp/deerwester.dict')  # store the dictionary, for future reference
corpus = [dictionary.doc2bow(text) for text in texts]
corpora.MmCorpus.serialize('/tmp/deerwester.mm', corpus)  # store to disk, for later use

注意最后的corpora.MmCorpus.serialize將持久化到磁盤中。相反,可以用

corpus = corpora.MmCorpus('/tmp/deerwester.mm')

來從磁盤中讀取corpus。

除了MmCorpus以外,還有其他格式,例如SvmLightCorpus, BleiCorpus, LowCorpus等,用法類似。

 

1.2 dictionary的其他一些用法

dictionary.filter_n_most_frequent(N) 
過濾掉出現頻率最高的N個單詞

dictionary.filter_extremes(no_below=5, no_above=0.5, keep_n=100000) 
1.去掉出現次數低於no_below的 
2.去掉出現次數高於no_above的。注意這個小數指的是百分數 
3.在1和2的基礎上,保留出現頻率前keep_n的單詞

dictionary.filter_tokens(bad_ids=None, good_ids=None) 
有兩種用法,一種是去掉bad_id對應的詞,另一種是保留good_id對應的詞而去掉其他詞。注意這里bad_ids和good_ids都是列表形式

dictionary.compacity() 
在執行完前面的過濾操作以后,可能會造成單詞的序號之間有空隙,這時就可以使用該函數來對詞典來進行重新排序,去掉這些空隙。

 

1.3 分批處理和分布式計算結果的匯總

文本的規模很大時,造成內存不足以容納文本的情況,就需要將所有文本分批處理,最后再將各批次計算得到的結果進行匯總。分布式計算時也有類似的需求。

這里假設在兩個批次中,分別生成了dict1,corpus1以及dict2,corpus2. 

第一步,首先將兩個詞典合並。當然,如果是先統一生成詞典再分批生成詞向量的話,可以跳過這一步,因為詞典是一樣的。

dict2_to_dict1 = dict1.merge_with(dict2) 

要注意的是,得到的dict2_to_dict1並不是生成后的詞典,而是dict2中的單詞序號到這些詞在合並后詞典新序號的映射表。而dict1本身成為合並后的新詞典。

第二步,合並corpus。

如果之前跳過了第一步,即dict1就是dict2的話,可以直接進行合並。合並有兩種方式,一種是

 merged_corpus = [x for x in corpus1] + [x for x in corpus2]

另外一種,則需使用內置的itertools類 

merged_corpus = itertools.chain(corpus1, corpus2)
merged_corpus = [x for x in merged_corpus]

如果之前的詞典也是分批生成的話,則需要對corpus2進行一定的處理 

new_corpus2 = dict2_to_dict1[corpus2]
merged_corpus = itertools.chain(corpus1, new_corpus2)
merged_corpus = [x for x in merged_corpus] 

這樣,就把分批處理得到的dict和corpus都合並起來了。

 

 

2. models

在models中,可以對corpus進行進一步處理,比如使用TF-IDF模型,LDA模型,LSI模型,非常強大。

在按照之前的方法生成了corpus和dictionary以后,就可以生成模型了。

tfidf_model = models.TfidfModel(corpus) 

注意,目前只是生成了一個模型,但這是類似於生成器,並不是將對應的corpus轉化后的結果。對tf-idf模型而言,里面存儲有各個單詞的詞頻,文頻等信息。想要將文檔轉化成TF-IDF模式表示的向量,還要使用如下命令:

corpus_tfidf = tfidf_model[corpus]

對於LDA和LSI模型,用法有所不同 :

lsi_model = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)
corpus_lsi = lsi_model[corpus_tfidf]

可以看到,這里除了corpus以外,還多了num_topic的選項。這是指潛在主題(topic)的數目,也等於轉成LSI模型以后每個文檔對應的向量長度。轉化以后的向量在各項的值,即為該文檔在該潛在主題的權重 。因此LSI和LDA的結果可以看做該文檔的文檔向量,用於后續的分類,聚類等算法。值得注意的是,id2word是所有模型都有的選項,可以指定使用的詞典。

由於這里num_topics=2,所以可以用作圖的方式直觀的顯現出來。

可以很清楚的看到,9個文檔可以看成兩類,分別是前5行和后4行。

 

 

來自:https://blog.csdn.net/u014595019/article/details/52218249 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM