1. 程式人生 > >Gensim Word2vec 使用教程

Gensim Word2vec 使用教程

本文主要基於Radim Rehurek的Word2vec Tutorial.

**

準備輸入

**

Gensim的word2vec的輸入是句子的序列. 每個句子是一個單詞列表

程式碼塊

例如:

>>> # import modules & set up logging
>>> import gensim, logging
>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
>>>
>>> 
sentences = [['first', 'sentence'], ['second', 'sentence']] >>> # train word2vec on the two sentences >>> model = gensim.models.Word2Vec(sentences, min_count=1)

將輸入視為Python的內建列表很簡單, 但是在輸入很大時會佔用大量的記憶體. 所以Gensim只要求輸入按順序提供句子, 並不將這些句子儲存在記憶體, 然後Gensim可以載入一個句子, 處理該句子, 然後載入下一個句子.

例如, 如果輸入分佈在硬碟上的多個檔案中, 檔案的每一行是一個句子, 那麼可以逐個檔案, 逐行的處理輸入:

>>> class MySentences(object):
...     def __init__(self, dirname):
...         self.dirname = dirname
... 
...     def __iter__(self):
...         for fname in os.listdir(self.dirname):
...             for line in open(os.path.join(self.dirname, fname)):
...                 yield line.split()
>>>
>>> 
sentences = MySentences('/some/directory') # a memory-friendly iterator >>> model = gensim.models.Word2Vec(sentences)

如果需要對檔案中的單詞做其他處理, 比如轉換為unicode, 轉換大小寫, 刪除數字, 抽取命名實體等, 所有這些都可以在MySentence迭代器中進行處理.

注意, word2vec會在整個句子序列上跑兩遍, 第一遍會收集單詞及其詞頻來夠愛走一個內部字典樹結構. 第二遍才會訓練神經網路. 如果你只能遍歷一邊資料, 則可以參考以下做法

>>> model = gensim.models.Word2Vec() # an empty model, no training
>>> model.build_vocab(some_sentences)  # can be a non-repeatable, 1-pass generator
>>> model.train(other_sentences)  # can be a non-repeatable, 1-pass generator

**

訓練

**
Word2vec有很多可以影響訓練速度和質量的引數.

第一個引數可以對字典做截斷. 少於min_count次數的單詞會被丟棄掉, 預設值為5

python
model = Word2Vec(sentences, min_count=10)  # default value is 5

另外一個是神經網路的隱藏層的單元數:

model = Word2Vec(sentences, size=200)  # default value is 100

大的size需要更多的訓練資料, 但是效果會更好. 推薦值為幾十到幾百.

最後一個主要的引數控制訓練的並行:

model = Word2Vec(sentences, workers=4) # default = 1 worker = no parallelization

worker引數只有在安裝了Cython後才有效. 沒有Cython的話, 只能使用單核.

記憶體

word2vec的引數被儲存為矩陣(Numpy array). array的大小為#vocabulary 乘以 #size大小的浮點數(4 byte)矩陣.

記憶體中有三個這樣的矩陣, 如果你的輸入包含100,000個單詞, 隱層單元數為200, 則需要的記憶體大小為100,000 * 200 * 4 * 3 bytes, 約為229MB.

另外還需要一些記憶體來儲存字典樹, 但是除非你的單詞是特別長的字串, 大部分記憶體佔用都來自前面說的三個矩陣.
評測

Gensim也支援相同的評測集:

>>> model.accuracy('/tmp/questions-words.txt')
-02-01 22:14:28,387 : INFO : family: 88.9% (304/342)
-02-01 22:29:24,006 : INFO : gram1-adjective-to-adverb: 32.4% (263/812)
-02-01 22:36:26,528 : INFO : gram2-opposite: 50.3% (191/380)
-02-01 23:00:52,406 : INFO : gram3-comparative: 91.7% (1222/1332)
-02-01 23:13:48,243 : INFO : gram4-superlative: 87.9% (617/702)
-02-01 23:29:52,268 : INFO : gram5-present-participle: 79.4% (691/870)
-02-01 23:57:04,965 : INFO : gram7-past-tense: 67.1% (995/1482)
-02-02 00:15:18,525 : INFO : gram8-plural: 89.6% (889/992)
-02-02 00:28:18,140 : INFO : gram9-plural-verbs: 68.7% (482/702)
-02-02 00:28:18,140 : INFO : total: 74.3% (5654/7614)

切記, 要根據自己的應用了需求來確定演算法的效能.

儲存和載入模型

儲存、載入模型的方法如下:

>>> model.save('/tmp/mymodel')
>>> new_model = gensim.models.Word2Vec.load('/tmp/mymodel')

另外, 可以直接載入由C生成的模型:

model = Word2Vec.load_word2vec_format('/tmp/vectors.txt', binary=False)
 # using gzipped/bz2 input works too, no need to unzip:
model=Word2Vec.load_word2vec_format('/tmp/vectors.bin.gz', binary=True)

線上訓練

可以在載入模型之後使用另外的句子來進一步訓練模型

model = gensim.models.Word2Vec.load('/tmp/mymodel')
model.train(more_sentences)

但是不能對C生成的模型進行再訓練.
使用模型
Word2vec支援數種單詞相似度任務:

model.most_similar(positive=['woman', 'king'], negative=['man'], topn=1)
[('queen', 0.50882536)]
model.doesnt_match("breakfast cereal dinner lunch".split())
'cereal'
model.similarity('woman', 'man')
.73723527

可以通過以下方式來得到單詞的向量:

model['computer']  # raw NumPy vector of a word
array([-0.00449447, -0.00310097,  0.02421786, ...], dtype=float32)