TF-IDF原理及word2vec詳解Keras實現CBOW和Skip-Gram

weixin_40699243發表於2020-10-23

文字處理的Roadmap:
https://zhuanlan.zhihu.com/p/70361361
1.TF-IDF? 特徵工程+分類器
2.embedding:word2vec
3.GPT,BERT
4.表徵學習(Deep learning is representation learning)
5.RNN(Recurrent Neural Networks)

TF-IDF原理概述

在一份給定的檔案裡,詞頻(term frequency, TF)指的是某一個給定的詞語在該檔案中出現的次數。這個數字通常會被歸一化(分子一般小於分母區別於IDF),以防止它偏向長的檔案。(同一個詞語在長檔案裡可能會比短檔案有更高的詞頻,而不管該詞語重要與否)

逆向檔案頻率 (inverse document frequency, IDF) 是一個詞語普遍重要性的度量。某一特定詞語的IDF,可以由總檔案數目除以包含該詞語之檔案的數目,再將得到的商取對數得到。

某一特定檔案內的高詞語頻率,以及該詞語在整個檔案集合中的低檔案頻率,可以產生出高權重的TF-IDF。因此,TF-IDF傾向於過濾掉常見的詞語,保留重要的詞語。

綜上TF-IDF的主要思想是:如果某個詞或短語在一篇文章中出現的頻率TF高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。TF-IDF實際上是:TF * IDF,TF為詞頻,IDF反文件頻率。

詞頻(TF) = 某個詞在文章中的出現次數 / 文章總詞數
逆文件頻率(IDF) = log(詞料庫的文件總數/包含該詞的文件數+1)
TF-IDF = 詞頻(TF) * 逆文件頻率(IDF)

Word2vec
運用神經網路將V維的詞向量 通過權重矩陣Vd轉換為 d維詞向量。輸入為word bag中V個詞中的一個詞,已經轉換為V維 one-hot編碼, 通過權重矩陣W, 得到輸出1d維的H, 再經過softmax d*V維轉換成為V維的詞向量。輸出含義:條件概率
還可以用訓練好的H權重,將V維的one-hot詞向量轉化為d維的詞向量。

CBOW和Skip-Gram
在這裡插入圖片描述
在這裡插入圖片描述
CBOW
Continuous Bag-of-Words

原理介紹:
https://zhuanlan.zhihu.com/p/44599645
http://www.360doc.cn/mip/895906230.html
假設目標詞 前後各取k個詞,即視窗的大小是k,那麼CBOW模型預測的將是
在這裡插入圖片描述
練CBOW模型,該模型的結構如下圖:在這裡插入圖片描述
問題:
輸入層到隱藏層以圖2為例,輸入層是四個詞的one-hot向量表示,分別為 在這裡插入圖片描述
(維度都為V x 1,V是模型的訓練本文中所有詞的個數),記輸入層到隱藏層的權重矩陣為 W(維度為V x N,N是認為給定的詞向量維度),隱藏層的向量為h (維度為N x 1),那麼 其實這裡就是一個簡單地求和平均。
在這裡插入圖片描述
隱藏層到輸出層
記隱藏層到輸出層的權重矩陣為W’ (U) (維度為N x V),輸出層的向量為 (維度為V x 1),那麼
在這裡插入圖片描述
注意,輸出層的向量y與輸入層的向量為x雖然維度是一樣的,但是y並不是one-hot向量,並且向量 y中的每個元素都是有意義的。後將1V的向量softmax歸一化處理得到新的1V向量,在V個取值中概率值最大的數字對應的位置所表示的詞就是預測結果。

負取樣
負取樣實際上是取樣負例來幫助訓練的手段,其目的與層次softmax一樣,是用來提升模型的訓練速度。我們知道,模型對正例的預測概率是越大越好,模型對負例的預測概率是越小越好。由於正例的數量少,很容易保證每個正例的預測概率儘可能大,而負例的數量特別多,所以負取樣的思路就是根據某種負取樣的策略隨機挑選一些負例,然後保證挑選的這部分負例的預測概率儘可能小。所以,負取樣策略是對模型的效果影響很大,word2vec常用的負取樣策略有均勻負取樣、按詞頻率取樣等等。

程式碼實現:
https://blog.csdn.net/qq_34862636/article/details/103834058
training輸入輸出是什麼
在這裡插入圖片描述
CBOW是用某一個詞的上下文(前面幾個和後面幾個)去預測它本身。
右邊:
第一個input層, 假設window設定為5,那麼就是用前5個詞和後5個詞去預測當前詞,所以模型的輸入是上下文,也就是10個詞。
第一個Embedding層表示將要對映的詞向量維度為128,那就成了10*128的張量。
第一個lambda層,其做的是加法,將10個128維的詞向量同一維度直接加在一起形成了一個128維的張量。
左邊:
第二個輸入層輸入的就是當前詞,也就是1個詞。
第二個lambda層做的是抽樣,隨機構造15個跟當前詞不一樣的詞作為負樣本。
第三個lambda層將輸入的當前詞和負樣本拼接到一起。嵌入2次,分別得到W和b,也就是softmax_weights和softmax_bias
在第四個lambda層將右邊第一個lambda輸出的input_vecs_sum的向量推展一維,才能和softmax_weights進行dot,完成Dense(Wx+b)和Softmax的操作。
最後整個模型的輸出的是softmax的值,其有16維實際上是模型預測當前詞是正例(1個)和負例(抽樣的15個)的概率值,這就做到了通過輸入上下文來識別當前詞,且識別範圍(解空間)由原先的所有詞,限制到了負取樣個數+1內,這就大大地加快了訓練速度。而我們所需要的詞向量就是右邊的Embeding層,也就是第一個嵌入層的權重。

 具體程式碼參考連結 程式碼:

 data_generator(): #訓練資料生成器
	    x,y = [],[]
	    for sentence in corpus:
	        sentence = [0]*window + [word2id[w] for w in sentence if w in word2id] + [0]*window
	        #上面這句程式碼的意思是,因為我們是通過滑窗的方式來獲取訓練資料的,那麼每一句語料的第一個詞和最後一個詞
	        #如何出現在中心位置呢?答案就是給它padding一下,例如“我/喜歡/足球”,兩邊分別補視窗大小個pad,得到“pad pad 我 喜歡 足球 pad pad”
	        #那麼第一條訓練資料的背景詞就是['pad', 'pad','喜歡', '足球'],中心詞就是'我'
	        for i in range(window, len(sentence)-window):
	            x.append(sentence[i-window: i]+sentence[i+1: window+i+1])
	            y.append([sentence[i]]+get_negtive_sample(sentence[i], nb_word, nb_negative))
	
	    x,y = np.array(x),np.array(y)
	    z = np.zeros((len(x), nb_negative+1))
	    z[:,0]=1
	    return x,y,z			

``

如何用,比如用訓練好的weight值計算詞向量相似度的方法:

model.save_weights('word2vec.model')

#embedding層的權重永遠在模型的第一層
embeddings = model.get_weights()[0]

def most_similar(w):
    v = embeddings[word2id[w]]
    sims = np.dot(embeddings, v)
    sort = sims.argsort()[::-1]
    sort = sort[sort > 0]
    return [(id2word[i],sims[i]) for i in sort[:10]]

import pandas as pd
pd.Series(most_similar(u'科學'))

Skip-Gram

Skip-Gram的模型圖與CBOW恰好相反,如圖4所示。
在這裡插入圖片描述
從圖中可以看出,Skip-Gram模型預測的是 在這裡插入圖片描述
,由於圖中詞wt 前後只取了各兩個詞,所以視窗的總大小是2。假設詞 wt前後各取k個詞,即視窗的大小是k,那麼Skip-Gram模型預測的將是
在這裡插入圖片描述
輸入層到隱藏層
輸入層是詞的one-hot向量表示,分別為 xt(維度都為V x 1,V是模型的訓練本文中所有詞的個數),記輸入層到隱藏層的權重矩陣為 W (維度為V x d,d是認為給定的詞向量維度),隱藏層的向量為 (維度為d x 1),那麼
在這裡插入圖片描述
隱藏層到輸出層

記隱藏層到輸出層的權重矩陣為 U(維度為d x V),輸出層的向量為 y (維度為V x 1),那麼
在這裡插入圖片描述
在程式碼實現層面,加入負取樣的方法,首先輸入一箇中心詞,要從一群正確的周圍詞和負樣本中,去使模型預測這些周圍詞的概率最大化,因此模型的輸出是一個multi-hot向量(因為預測結果有多個正確的周圍詞),這裡就不能再使用softmax去計算概率,而應該用sigmoid去分別計算每一個周圍詞的概率。這是skip-gram與CBOW模型上最顯著的不同。
(sigmoid函式也叫Logistic函式,用於隱層神經元輸出,取值範圍為(0,1),它可以將一個實數對映到(0,1)的區間,可以用來做二分類。在這裡插入圖片描述
)(Softmax 迴歸模型是解決多類迴歸問題的演算法, 在這裡插入圖片描述
)

參考程式碼

假如window=2, 輸出sigmoid為4

def data_generator(): #訓練資料生成器
    x,y = [],[]

    for sentence in corpus:
        sentence = [0]*window + [word2id[w] for w in sentence if w in word2id] + [0]*window
        #上面這句程式碼的意思是,因為我們是通過滑窗的方式來獲取訓練資料的,那麼每一句語料的第一個詞和最後一個詞
        #如何出現在中心位置呢?答案就是給它padding一下,例如“我/喜歡/足球”,兩邊分別補視窗大小個pad,得到“pad pad 我 喜歡 足球 pad pad”
        #那麼第一條訓練資料的背景詞就是['pad', 'pad','喜歡', '足球'],中心詞就是'我'
        for i in range(window, len(sentence)-window):
            X.append([sentence[i]])
            surrounding = sentence[i-window: i]+sentence[i+1: window+i+1]+ge
            y.append(surrounding+get_negtive_sample(surrounding, nb_word, nb_negative))    x,y = np.array(x),np.array(y)
    z = np.zeros((len(x), nb_negative+len(surrounding)))
    z[:,:len(surrounding)]=1
    return x,y,z

x 為中心詞訓練語料,y 是周圍詞+nb_negative 個負樣本,因為我們是將正確的周圍詞放在 y 的最前面,因此在構造 z 時,把標籤 1 放在每條 label 資料的前len(surrounding)位。輸出 z[0],可以看到是[1,1,1,…,0]。

RNN

Recurrent Neural Network Model https://blog.csdn.net/qq_40589923/article/details/79436259
Vanishing gradients with RNNs https://blog.csdn.net/qq_40589923/article/details/79436714(梯度消失GR/LSTM和梯度爆炸gradient
clipping)
Long Short Term Memory (LSTM) https://blog.csdn.net/qq_40589923/article/details/79436802

相關文章