1.word2vec詞向量原理解析
word2vec,即詞向量,就是一個詞用一個向量來表示。是2013年Google提出的。word2vec工具主要包含兩個模型:跳字模型(skip-gram)和連續詞袋模型(continuous bag of words,簡稱CBOW),以及兩種高效訓練的方法:負采樣(negative sampling)和層序softmax(hierarchical softmax)。word2vec詞向量可以較好地表達不同詞之間的相似和類比關系。word2vec是一個NLP工具,它可以將所有的詞向量化,這樣詞與詞之間就可以定量的去度量他們之間的關系,挖掘詞之間的聯系。
NLP(自然語言處理)里面,最細粒度的是詞語,詞語組成句子,句子再組成段落、篇章、文檔。所以處理 NLP 的問題,首先要先處理詞語。詞語,是人類的抽象總結,是符號形式的(比如中文、英文、拉丁文等等),所以需要把他們轉換成數值形式,或者說——嵌入到一個數學空間里,這種嵌入方式,就叫詞嵌入(word embedding),而 Word2vec,就是詞嵌入( word embedding) 的一種。簡單點來說就是把一個詞語轉換成對應向量的表達形式,來讓機器讀取數據。
2.gensim訓練中文詞向量
如果在以詞為基本單元輸入的自然語言處理任務中,都避免不了使用詞的表示,詞的表示有很多種,這里主要介紹的就是詞向量,word2vec是目前比較通用的訓練詞向量的工具,使用Gensim模塊,可以使詞向量的訓練變的簡單,那么我們知道對於word2vec來說,不論的Skip-Gram models還是CBOW models,他們的輸入以及輸出都是以單詞為基本單位的,只是他們對應的輸入以及輸出不一樣:
- Skip-Gram models:輸入為單個詞,輸出目標為多個上下文單詞;
- CBOW models:輸入為多個上下文單詞,輸出目標為一個單詞;
我們從上面可以看出,無論是Skip-Gram models還是CBOW models基本的單元都是詞,那么我們獲取到的語料,必須要經過分詞處理以后才能用於詞向量的訓練語料。
對於詞向量的訓練,語料越大訓練出來的結果越好(非常重要)
3.word2vec類
參數表這一列,等號右邊的值表示默認值
sentences (iterable of iterables, optional) – 供訓練的句子,可以使用簡單的列表,但是對於大語料庫,建議直接從磁盤/網絡流迭代傳輸句子。參閱word2vec模塊中的BrownCorpus,Text8Corpus或LineSentence。
corpus_file (str, optional) – LineSentence格式的語料庫文件路徑。
size (int, optional) – word向量的維度。
window (int, optional) – 一個句子中當前單詞和被預測單詞的最大距離。
min_count (int, optional) – 忽略詞頻小於此值的單詞。
workers (int, optional) – 訓練模型時使用的線程數。
sg ({0, 1}, optional) – 模型的訓練算法: 1: skip-gram; 0: CBOW.
hs ({0, 1}, optional) – 1: 采用hierarchical softmax訓練模型; 0: 使用負采樣。
negative (int, optional) – > 0: 使用負采樣,設置多個負采樣(通常在5-20之間)。
ns_exponent (float, optional) – 負采樣分布指數。1.0樣本值與頻率成正比,0.0樣本所有單詞均等,負值更多地采樣低頻詞。
cbow_mean ({0, 1}, optional) – 0: 使用上下文單詞向量的總和; 1: 使用均值,適用於使用CBOW。
alpha (float, optional) – 初始學習率。
min_alpha (float, optional) – 隨着訓練的進行,學習率線性下降到min_alpha。
seed (int, optional) – 隨機數發生器種子。
max_vocab_size (int, optional) – 詞匯構建期間RAM的限制; 如果有更多的獨特單詞,則修剪不常見的單詞。 每1000萬個類型的字需要大約1GB的RAM。
max_final_vocab (int, optional) – 自動選擇匹配的min_count將詞匯限制為目標詞匯大小。
sample (float, optional) – 高頻詞隨機下采樣的配置閾值,范圍是(0,1e-5)。
hashfxn (function, optional) – 哈希函數用於隨機初始化權重,以提高訓練的可重復性。
iter (int, optional) – 迭代次數。
trim_rule (function, optional) – 詞匯修剪規則,指定某些詞語是否應保留在詞匯表中,修剪掉或使用默認值處理。
sorted_vocab ({0, 1}, optional) – 如果為1,則在分配單詞索引前按降序對詞匯表進行排序。
batch_words (int, optional) – 每一個batch傳遞給線程單詞的數量。
compute_loss (bool, optional) – 如果為True,則計算並存儲可使用get_latest_training_loss()檢索的損失值。
callbacks (iterable of CallbackAny2Vec, optional) – 在訓練中特定階段執行回調序列。
4.開始訓練
只需要給Word2Vec
類賦上參數,就可以直接訓練了。其中common_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’]]
可以看到整體格式是[['A','B'],['C','D','E']]
,其中這個list表示所有的文本(此處表示2個文本,里面的A,B等表示單詞,如果是中文則表示分詞的結果
在示例1中,第8行和第10行都是用來保存訓練模型的(簡稱save和format_save),而兩者之間的相同點就是:都可以復用,即載入之后可以得到對應單詞的詞向量;不同點是:save保存的模型,載入之后可以繼續在此基礎上接着訓練(后文會介紹),而format_save保存的模型不能,但有個好處就是如果s設置binary=False則保存后的結果可以直接打開查看(一共有12個詞向量,每個詞向量100維)
(1)查看詞表相關信息
model = Word2Vec.load('./MyModel') # 對於訓練好的模型,我們可以通過下面這前三行代碼來查看詞表中的詞,頻度,以及索引位置, # 最關鍵的是可以通過第四行代碼判斷模型中是否存在這個詞 for key in model.wv.vocab: print(key) print(model.wv.vocab[key]) print('human' in model.wv.vocab) print(len(model.wv.vocab)) #獲取詞表中的總詞數
控制台輸出:
human Vocab(count:2, index:4, sample_int:579459575) interface Vocab(count:2, index:5, sample_int:579459575) computer Vocab(count:2, index:6, sample_int:579459575) survey Vocab(count:2, index:7, sample_int:579459575) user Vocab(count:3, index:1, sample_int:463795800) system Vocab(count:4, index:0, sample_int:396841800) response Vocab(count:2, index:8, sample_int:579459575) time Vocab(count:2, index:9, sample_int:579459575) eps Vocab(count:2, index:10, sample_int:579459575) trees Vocab(count:3, index:2, sample_int:463795800) graph Vocab(count:3, index:3, sample_int:463795800) minors Vocab(count:2, index:11, sample_int:579459575) True 12
(2)獲取對應的詞向量及維度
# 示例3 獲取對應的詞向量及維度 model = Word2Vec.load('./MyModel') print(model.wv.vector_size) #輸出詞向量的維度 print(model['human']) #輸出human這個詞的詞向量 print(model['good'])
(3)wiki+hotel語料訓練詞向量
from gensim.models import word2vec import gensim #分詞結果split_result_txt包下多個txt合並,將分割符由/替換成空格 def review_corpus_merge(): for i in range(1, 10): review_split_txt_path = 'split_result_txt/split_txt_' + str(i) + '.txt' fenci_result_corpus_path = 'fenci_result_corpus/hotel_review_corpus.txt' #讀取文件 f = open(review_split_txt_path, 'r', encoding='utf-8') for line in f.readlines(): review = line.split("/") review_kongge = " ".join(review) if (len(review_kongge.strip()) != 0): # strip()函數刪除空格與換行符,刪除空行 #向文件中追加寫入 f = open(fenci_result_corpus_path, 'a', encoding='utf-8') f.write('\n' + review_kongge.strip()) f.close() #review_corpus_merge() 這個函數運行一次即可 def train_word2vec(filename): text = gensim.models.word2vec.LineSentence(filename) #參數說明:text訓練語料,size設置訓練的詞向量為300維,min_count表示詞頻小於10的詞匯不訓練,sg=1表示使用skip-gram #hs=1表示使用hierarchical softmax訓練模型,workers訓練模型使用的線程數 word2vec = gensim.models.word2vec.Word2Vec(text, size=300, window=10, min_count=10, sg=1, hs=1, iter=8, workers=25) word2vec.save('../word2vec_model/word2vec_hotel') word2vec.wv.save_word2vec_format('../word2vec_model/word2vec_hotel.txt', binary=False) print('語料數:', word2vec.corpus_count) print('詞表長度:', len(word2vec.wv.vocab)) #首先先單獨訓練酒店語料庫 train_word2vec('../fenci_result_corpus/hotel_review_corpus.txt') # 在原有的酒店語料庫中添加wiki百科語料庫,進行進一步訓練 loaded_model = gensim.models.word2vec.Word2Vec.load('../word2vec_model/word2vec_hotel') # 加載模型 text_add = gensim.models.word2vec.LineSentence('../fenci_result_corpus/wiki_corpus') loaded_model.build_vocab(sentences=text_add, update=True) loaded_model.train(sentences=text_add, total_examples=loaded_model.corpus_count, epochs=loaded_model.iter) loaded_model.save('../word2vec_model/word2vec_hotel_wiki') loaded_model.wv.save_word2vec_format('../word2vec_model/word2vec_hotel_wiki.txt', binary=False) print('語料數:', loaded_model.corpus_count) print('詞表長度:', len(loaded_model.wv.vocab))
訓練結果:
5.追加訓練
FileNotFoundError: [Errno 2] No such file or directory: 'word2vec_model/word2vec_hotel_3.wv.vectors.npy'
這是文件保存的路徑有問題,應該檢查文件的路徑地址,考慮目錄的層級結構,是否少了../等
最終訓練模型保存為4個文件:
word2vec_hotel_wiki,
word2vec_hotel_wiki.trainables.syn1.npy,
word2vec_hotel_wiki.trainables.syn1neg.npy,
word2vec_hotel_wiki.wv.vectors.npy
import gensim #加載已訓練好的模型 loaded_model = gensim.models.word2vec.Word2Vec.load('../word2vec_model/word2vec_hotel_wiki') # 加載模型 #獲取要追加訓練的語料 text_add = gensim.models.word2vec.LineSentence('../fenci_result_corpus/hotel_review_corpus_add02.txt') loaded_model.build_vocab(sentences=text_add, update=True) loaded_model.train(sentences=text_add, total_examples=loaded_model.corpus_count, epochs=loaded_model.iter) #訓練好的模型重新保存 loaded_model.save('../word2vec_model/word2vec_hotel_3') loaded_model.wv.save_word2vec_format('../word2vec_model/word2vec_hotel_3.txt', binary=False) print('語料數:', loaded_model.corpus_count) print('詞表長度:', len(loaded_model.wv.vocab))
參考文獻:
https://blog.csdn.net/liuchenbaidu/article/details/106289334
https://www.jianshu.com/p/3c6c53ec1512 推薦
https://blog.csdn.net/The_lastest/article/details/81734980 必看