計算機處理圖像的時候,本質上利用了圖像的像素數值信息。對自然語言來說,本身並沒有包含計算機擅長處理的數值信息,因此,需要通過一定的手段將「自然語言」量化,進而利用已有的機器學習方法對自然語言進行處理、分析和預測。
獨熱編碼也稱One-hot編碼 (一位有效碼),其方法是使用N位狀態寄存器來對N個狀態進行編碼,每個狀態都有它獨立的寄存器位,並且在任意時候,其中只有一位有效。比如有下面的狀態表:
轉化為獨熱編碼為(注意:這裡容易和數字電路中的真值表編號相混淆,請務必區分)
如果上面的indicator不是數值量,而是文本,則可以表示為:
對應的獨熱編碼可以編號為:
這樣處理的優缺點在哪?
首先是優點,很顯然,將一個word映射為一個數學向量,這便於我們後續進行各種機器學習算法的輸入處理。
缺點也很明顯:
在線性代數中,有稀疏矩陣的概念——大部分矩陣元素都為0. 上面的獨熱編碼正是特殊的1 x n維的稀疏矩陣,這樣就非常浪費空間,並且容易造成維度災難。因此,我們急切需要一種可以降低維度的方法。
Dristributed representationDristributed representation 的思路是通過訓練,將每個詞都映射到一個較短的詞向量上來。所有的這些詞向量就構成了向量空間,用普通的統計學的方法來研究詞與詞之間的關係。詞向量維度一般在訓練時指定。下圖說明了一個簡單示例:
詞彙表裡的詞用"Royalty","Masculinity", "Femininity"和"Age"4個維度來表示,King這個詞對應的詞向量可能是(0.99,0.99,0.05,0.7),此處,king這個詞從一個可能非常稀疏的向量空間,映射到現在這個四維向量所在的空間,這個過程就是詞嵌入(word embedding).
假如我們將詞的維度降低到2D,有研究表明:
國王 - 男性 + 是女性 = 女王,挺有道理的 。
出現這種現象的原因是,我們得到最後的詞向量的訓練過程中引入了詞的上下文。
Word2Vec (一個神經網絡模型)輸入是One-Hot Vector,Hidden Layer沒有激活函數,也就是線性的單元。Output Layer維度跟Input Layer的維度一樣,用的是Softmax回歸。當這個模型訓練好以後,我們並不會用這個訓練好的模型處理新的任務,真正需要的是這個模型通過訓練數據所學得的參數,如隱藏層的權重矩陣。
這個模型是如何定義數據的輸入和輸出?一般分為CBOW(Continuous Bag-of-Words 與Skip-Gram兩種模型。
CBOW模型的訓練輸入是某一個特徵詞的上下文相關的詞對應的詞向量,而輸出就是這特定的一個詞的詞向量。 Skip-Gram模型和CBOW的思路是反著來的,即輸入是特定一個詞的詞向量,而輸出是特定詞對應的上下文詞向量。CBOW對小型資料庫比較合適,而Skip-Gram在大型語料中表現更好。
通俗一點,CBOW解決的是這樣的問題:
而Skip-gram解決的是這樣的問題:
CBOW的訓練模型
處理步驟:
輸入:上下文單詞的onehot編碼,每個onehot編碼是1 x V的向量
每個onehot向量乘以V x N的權重矩陣
全部向量相加求平均得到隱藏層的特徵向量,這個向量是1 x N維的
隱藏層的特徵向量乘以N x V維的輸出權重矩陣,得到1 x V維的輸出向量
輸出向量通過激活函數處理,得到概率分布
概率最大的index所指示的單詞為預測出的中間詞
訓練完畢後,輸入層的每個單詞與矩陣W相乘得到的向量的就是我們想要的詞向量 (word embedding).
下面是一個簡單例子:
Skip-Gram的訓練模型
假如有一個句子 「The dog barked at the mailman」。首先選句子中間的一個詞作為輸入詞,例如選取 「dog」 作為input word.
有了input word以後,再定義一個叫做skipwindow的參數,它代表著從當前input word的一側(左邊或右邊)選取詞的數量。如果設置skipwindow=2,那麼最終獲得窗口中的詞(包括input word在內)就是['The', 'dog', 'barked', 'at']。skipwindow=2代表著選取左input word左側2個詞和右側2個詞進入窗口,所以整個窗口大小span=2x2=4。
另一個參數叫numskips,它代表著從整個窗口中選取多少個不同的詞作為output word,當skipwindow=2,numskips=2時,將會得到兩組 (input word, output word) 形式的訓練數據,即 ('dog', 'barked'),('dog', 'the')。
神經網絡基於這些訓練數據將會輸出一個概率分布,這個概率代表詞典中的每個詞是output word的可能性。例如,先拿一組數據 ('dog', 'barked') 來訓練神經網絡,那麼模型通過學習這個訓練樣本,會告訴我們詞彙表中每個單詞是「barked」的概率大小。模型的輸出概率代表著到詞典中每個詞有多大可能性跟input word同時出現。
Word2Vec的優缺點優點缺點Word2Vec中文語料實戰環境win10 + python3 依賴包:gensim與jieba (通過pip install 安裝)
語料庫《誅仙》小說 (部分)
文本預處理去除文本中可能存在的空白等,防止對訓練造成幹擾。
# 文本預處理
file = open('text.txt', 'w', encoding='utf-8')
with open('誅仙.txt', 'r', encoding='utf-8') as origin_file:
for line in origin_file:
line = line.strip()
file.write(line + '\n')
file.close()
中文分詞將停頓詞放在一個stop.txt文件中,這裡選取了部分停頓詞如下:
調用jieba庫進行詞語劃分.
# 分詞
import jieba
stop_words_file = 'stop.txt'
stop_words = []
with open(stop_words_file, 'r', encoding='utf-8') as origin_stop_words_file:
text = origin_stop_words_file.readlines()
for line in text:
line = line.strip()
stop_words.append(line)
origin_txt_file = 'text.txt'
target_file = open('text_cut.txt', 'w', encoding='utf-8')
with open(origin_txt_file, 'r', encoding='utf-8') as origin_file:
text = origin_file.readlines()
for line in text:
line =line.strip()
out_str = ''
word_list = jieba.cut(line, cut_all=False)
for word in word_list:
if word not in stop_words:
if word != '\t':
out_str += word
out_str += ' '
target_file.write(out_str.rstrip() + '\n')
target_file.close()
分詞結果:
訓練word2vec模型#coding:utf8
import gensim.models.word2vec as w2v
model_file_name = 'model'
#模型訓練,生成詞向量
sentences = w2v.LineSentence('text_cut.txt')
# 訓練參數:輸出詞的向量維數為20,訓練窗口為5,截斷頻次在5次以下的詞,4個並行任務
model = w2v.Word2Vec(sentences, size=1000, window=5, min_count=5, workers=4)
model.save(model_file_name)
模型測試import gensim
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning,module='gensim')
model = gensim.models.Word2Vec.load("model")
word = '金瓶兒'
result = model.similar_by_word(word)
print("跟 "+word+" 最相近的詞:")
for i in result:
print(i)
模型結果參考文獻[1] Muwen. (2021). [NLP] Understanding the essence of Word2vec. Retrieved from https://zhuanlan.zhihu.com/p/26306795
[2] Wuyiji. (2017). Use python-gensim to train word2vec model and understanding of gensim API. Retrieved from https://blog.csdn.net/sinat_26917383/article/details/69803018
[3] Gensim. (2021). models.word2vec – Word2vec embeddings. Retrieved from https://radimrehurek.com/gensim/models/word2vec.html