利用英文wiki數據訓練Doc2vec模型

1、語料庫準備
此處下載英文維基百科數據,是xml壓縮包的形式,下載文件,以enwiki-latest-pages-articles1.xml-p10p30302.bz2爲例:
由於是壓縮包,所以需要進行預處理,變成文本的形式。在cmd下切換到這個壓縮包文件存放的目錄下,運行命令:
python process_wiki.py enwiki-latest-pages-articles1.xml-p10p30302.bz2 wiki.en.text
其中,process_wiki.py是把xml處理成txt文件的程序,enwiki-latest-pages-articles1.xml-p10p30302.bz2是我的壓縮包名稱,wiki.en.text是生成的txt文件的名字,這樣就得到了一個去除多餘字符和標點符號的純單詞的語料庫。每篇文檔存儲爲一行。

這裏有個坑:在運行的時候一直報這個錯誤:UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\ue626’ in position 94025: illegal multibyte sequence
搜索發現幾乎都是一篇東西或者一個解決方法轉來轉去,基本上都是encode或者decode的時候在括號裏面加一個ignore參數,目的是想忽略掉無法編碼的字符,感覺不算是解決問題。折騰了很久,發現問題的原因在於Python 3裏面字符串的默認編碼是Unicode的,Windows下面新建的文本文件默認的編碼是gbk(Windows簡體中文版的系統默認編碼就是gbk),當把從網頁上讀取的內容寫到文本文件裏面去的時候,意味着把一個unicode的字符序列寫入到一個編碼是gbk的文件,最後就出錯了。徹底解決方法就是在打開一個文件的時候,指定文件的編碼,讓它以指定的編碼打開,如下:
在這裏插入圖片描述
最後出現如下結果,表示處理成功:
在這裏插入圖片描述
可以看到,一共得到了14890篇文章(語料庫),保存在對應目錄下的wiki_en.txt文件中,下面就利用它訓練doc2vec模型。

2、doc2vec訓練
利用gensim庫搭建訓練模型訓練英文維基百科的doc2vec模型。程序如下:
train_model.py

#python example to train doc2vec model (with or without pre-trained word embeddings)

import gensim.models as gm
import logging

#doc2vec 參數
vector_size = 256 # 詞向量長度,默認爲100
window_size = 15 # 窗口大小,表示當前詞與預測詞在一個句子中的最大距離是多少
min_count = 1 #可以對字典做截斷. 詞頻少於min_count次數的單詞會被丟棄掉, 默認值爲5
sampling_threshold = 1e-5 # 高頻詞彙的隨機降採樣的配置閾值,默認爲1e-3,範圍是(0,1e-5)
negative_size = 5 #如果>0,則會採用negativesampling,用於設置多少個noise words(一般是5-20)
train_epoch = 100 # 迭代次數
dm = 0 #0 = dbow; 1 = dmpv
worker_count = 1 # 用於控制訓練的並行數

#pretrained word embeddings
pretrained_emb = "toy_data/pretrained_word_embeddings.txt" #None if use without pretrained embeddings

#輸入語料庫
train_corpus = "toy_data/wiki_en.txt"

#模型輸出
save_model_name = 'wiki_en_doc2vec.model'
saved_path = "toy_data/model/wiki_en_doc2vec.model.bin"

#獲取日誌信息
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

#訓練 doc2vec 模型
docs = gm.doc2vec.TaggedLineDocument(train_corpus) #加載語料
model = gm.Doc2Vec(docs, size=vector_size, window=window_size, min_count=min_count, sample=sampling_threshold, workers=worker_count,\
                   hs=0, dm=dm, negative=negative_size, dbow_words=1, dm_concat=1, pretrained_emb=pretrained_emb, iter=train_epoch)

#保存模型
model.save(saved_path)

訓練過程:
在這裏插入圖片描述
訓練完成後得到這三個文件:
在這裏插入圖片描述
3、測試
infer_test.py

#python example to infer document vectors from trained doc2vec model
import gensim.models as gm
import codecs
import numpy as np

#parameters
model = "toy_data/model/wiki_en_doc2vec.model.bin"
test_docs = "toy_data/test.txt" # test.txt爲需要向量化的文本
output_file = "toy_data/test_vector.txt" #得到測試文本的每一行的向量表示

# 超參
start_alpha = 0.01
infer_epoch = 1000

#加載模型
m = gm.Doc2Vec.load(model)
test_docs = [x.strip().split() for x in codecs.open(test_docs, "r", "utf-8").readlines()]

#infer test vectors
output = open(output_file, "w")
for d in test_docs:
    output.write(" ".join([str(x) for x in m.infer_vector(d, alpha=start_alpha, steps=infer_epoch)]) + "\n")
output.flush()
output.close()
#print(len(test_docs)) #測試文本的行數

print(m.most_similar("party", topn=5)) # 找到與party單詞最相近的前5個

#保存爲numpy形式
test_vector = np.loadtxt('toy_data/test_vector.txt')
test_vector = np.save('toy_data/test_vector', test_vector)

完成的項目代碼地址:
https://github.com/2281123066/doc2vec

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章