本文介紹python
- wordvec的概念
- 語言模型訓練的兩種模型CBOW+skip gram
- word2vec 優化的兩種方法:層次softmax+負採樣
- gensim word2vec默認用的模型和方法
未經許可,不要轉載。網絡
機器學習的輸入都是數字,而NLP都是文字; 爲了讓機器學習應用在NLP上,須要把文字轉換爲數字,把文字嵌入到數學空間。機器學習
1. 詞表示:
- 詞的獨熱表示:onehot (詞之間是孤立的)
- onehot:
- 思想:假設詞表大小爲N, 則每一個單字表示爲N維向量; 每一個單字只有1位爲1,其餘爲0;茫茫0海中一個1
- 缺點:詞之間是孤立的;維度太大
- 詞的分佈式表示:(能描述詞之間的語義關係)
- 基於矩陣的分佈式表示
- 基於聚類的分佈式表示
- 基於神經網絡的分佈表示,詞嵌入 word embedding
- 將01表示改成浮點數表述;降維
- word2vec是用神經網絡訓練語言模型(NNLM)過程當中獲得的參數.
- 其餘概念
- 語言模型: 就是一段文字成爲句子的機率; 常常用的ngram, n=2或3
2. NNLM 神經網絡語言模型
用神經網絡訓練語言模型,常見有兩種; 用上下文預測term(CBOW), 用term預測上下文(skip-gram),結構通常是簡單三層網絡,一個輸入層、一個隱含層、一個輸出層。分佈式
2.1 CBOW 連續詞袋模型
- 變量:詞表大小V, 要嵌入到N維空間中,C/2是窗口大小,即上下文取幾個term(不算當前term);- N通常取50~300
- 步驟:參考自 https://www.zhihu.com/question/44832436
- input layer:窗口內的C個詞的onehot表示
- input layer -> hidden layer:(V維表示降到N維表示)
- 經過權重矩陣\(W_{V\times N}\) ,將 \(V \times C\)映射爲 $N \times C $
- hidden layer + 激活函數:C個詞表示爲1個詞
- hidden layer -> output layer:1個N維詞還原到高維V維中;
- 經過權重矩陣\(W_{N\times V}^{'}\) ,將 \(N \times 1\)映射爲 \(V\times 1\)
- output layer + softmax 激活函數,將值歸一化到0~1之間 y
- 用BP+梯度降低優化cost function y和真實y之間的距離,迭代優化參數 \(W、W^{'}\)
- 收斂result:y是V維向量,每一個元素取值0~1, 將最大元素值,還原爲onehot編碼,就是最終結果了。
2.2 skip-gram 語言模型
思路同CBOW, 只是輸入是1個詞,輸出是C個詞;
通常用BP訓練獲得參數,預測用一次前向傳播;函數
3. word2vec用的優化方法
word2vec結合了CBOW, skip-gram的方法 訓練獲得參數\(W\), 但在計算中作了不少優化;
能夠看到,NNLM計算中,兩個問題致使計算量大;性能
- 詞表維度大;
- softmax計算量大;
下面介紹兩種優化方法;學習
3.1 hierarchical softmax 層次softmax
/ˌhī(ə)ˈrärkikəl/優化
爲了解決NNLM中softmax過程的計算性能問題,一般有幾種優化技巧:
- 將常見的單詞組合(word pairs)或者詞組做爲單個「words」來處理
- 對高頻次單詞進行抽樣來減小訓練樣本的個數
- 對優化目標採用「negative sampling」方法,這樣每一個訓練樣本的訓練只會更新一小部分的模型權重,從而下降計算負擔
參考自:https://www.jianshu.com/p/56554a63410f
3.2.1 對高頻詞抽樣
主要思想是少訓練沒有區分度的高頻term;
對於咱們在訓練原始文本中遇到的每個單詞,它們都有必定機率被咱們從文本中刪掉,而這個被刪除的機率與單詞的頻率有關。詞頻越高(stopword),抽樣越少;
- 抽樣率 \(P(w_{i}) = (\sqrt{\frac{Z(w_i)}{t}}+1)\times \frac{t}{Z(w_i)} = \sqrt{\frac{t}{Z(w_i)}} + \frac{t}{Z(w_i)}\) ,其中
- \(Z(w_i)\)是詞在語料中的出現機率,反比關係,越高頻詞抽的越少;
- \(t\)是設定的閾值,正比關係,\(t\)越大,不一樣頻率單詞的採樣機率差別越大; gensim word2vec中默認值是0.001
- 抽樣率直觀理解
import numpy as np
import matplotlib.pyplot as plt
x = np.array(range(1, 100)) / 1000.0
t1 = 0.001
t2 = 0.0001
y1 = np.power(t1/x, 0.5) + t1/x
y2 = np.power(t2/x, 0.5) + t2/x
plt.plot(x, y1, '-', label='t=0.001')
plt.plot(x, y2, '-', label='t=0.0001')
plt.legend()
3.2.2 負採樣 Negative sampling
- 問題:在NNLM中對於每一個樣本w, 都要更新一次hidden->output的參數陣\(W^{'}_{N\times V}\),計算量很大;好比詞表大小V=10000, N=300, 那麼權重矩陣有300萬個參數;
- 思想:若是每次只更新目標詞(正例 positive word)和少數幾個負例(negative words), 那麼計算量會顯著減小; 好比若是咱們每次只更新M=1+5個,則更新了6*300=1800, 1800/300萬=0.06%; 計算量減小了3個數量級。
- negative words如何選擇:根據詞表中出現的機率,出現機率越高,被選做負樣本的機率越高;
- \(P(w_i) = \frac{f(w_i)^{3/4}}{\sum_{j=0}^{v}{f(w_j)^{3/4}}}\), 其中\(f(w_j)\)是出現的機率,3/4是經驗值,比線性關係更弱化了些;
4. gensim word2vec默認參數(CBOW+負採樣)
默認用了CBOW模型,採用高頻詞抽樣+負採樣進行優化;
from gensim.models import Word2Vec
word2vec.Word2Vec(sentences=None, size=100, alpha=0.025, window=5, min_count=5, max_vocab_size=None, sample=0.001, seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5, ns_exponent=0.75, cbow_mean=1, iter=5, null_word=0, trim_rule=None, sorted_vocab=1, batch_words=10000, compute_loss=False, callbacks=(), max_final_vocab=None)
- 上下文窗口大小:window=5
- 忽略低頻次term:min_count=5
- 語言模型是用CBOW仍是skip-gram?sg=0 是CBOW
- 優化方法是用層次softmax仍是負採樣:hs=0 是負採樣
- 負採樣樣本數: negative=5 (通常設爲5-20)
- 負採樣採樣機率的平滑指數:ns_exponent=0.75
- 高頻詞抽樣的閾值 sample=0.001