Python之利用 gensim的word2vec進行酒店評論+wiki百科語料聯合詞向量訓練


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,他們的輸入以及輸出都是以單詞為基本單位的,只是他們對應的輸入以及輸出不一樣:

  1. Skip-Gram models:輸入為單個詞,輸出目標為多個上下文單詞;
  2. 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 必看


免責聲明!

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



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