詞向量入門

胖墩哥發表於2020-05-27

詞向量

one hot 編碼

在自然語言處理中,為了將自然語言轉化為計算機所能識別的語言,就要對它重新編碼,起初使用one hot編碼。

一共能產生14901維。

問題:佔用太大空間,詞和詞之間的相識度無法體現。也就是所說的稀疏化。

one hot程式碼如下:

from sklearn.preprocessing import OneHotEncoder
# lables = ['ni','號','ni','meimei']
lables = [0,1,0,4]
lables = np.array(lables).reshape(len(lables),-1)
enc =   OneHotEncoder()
enc.fit(lables)
target = enc.transform(lables).toarray()

print(target)

詞向量編碼思想

我們需要將上面的one hot 編碼轉化為如圖所示的編碼:

主要有兩種假說,今天我們只談當今的主流思想: Distributed models

Word2Vec

Word2vec 是程式碼專案的名字,只是計算詞嵌入(word embedding)的一個工具,是CBOW和Skip-Gram這兩個模型的合體,目前這套工具完全開源。

CBOW是利用詞的上下文預測當前的單詞;而Skip-Gram則是利用當前詞來預測上下文。

Word2Vec程式碼

# 訓練模型定義
from gensim.models import Word2Vec
model = Word2Vec(sentences, sg=1, size=100,  window=5,  min_count=5,  negative=3, sample=0.001, hs=1, workers=4)

# 訓練後的模型儲存與載入
model.save("model_name")

# 載入模型
model = Word2Vec.load("model_name")

# 模型的使用

#詞向量加減
model.most_similar(positive=['woman', 'king'], negative=['man'])
#輸出[('queen', 0.50882536), ...]
    
# 尋找指定詞語最相似的詞語
print model.most_similar('morning', topn=1)


model.doesnt_match("breakfast cereal dinner lunch".split())
#輸出'cereal'
 
# 計算詞語的相似度
model.similarity('woman', 'man')
#輸出0.73723527
 
model['computer']  # raw numpy vector of a word
#輸出array([-0.00449447, -0.00310097,  0.02421786, ...], dtype=float32)

Word2Vec引數描述:

1.sg=1是skip-gram演算法,對低頻詞敏感;預設sg=0為CBOW演算法。

2.size是輸出詞向量的維數,值太小會導致詞對映因為衝突而影響結果,值太大則會耗記憶體並使演算法計算變慢,一般值取為100到200之間。

3.window是句子中當前詞與目標詞之間的最大距離,3表示在目標詞前看3-b個詞,後面看b個詞(b在0-3之間隨機)。

4.min_count是對詞進行過濾,頻率小於min-count的單詞則會被忽視,預設值為5。

5.negative和sample可根據訓練結果進行微調,sample表示更高頻率的詞被隨機下采樣到所設定的閾值,預設值為1e-3。

6.hs=1表示層級softmax將會被使用,預設hs=0且negative不為0,則負取樣將會被選擇使用。

7.workers控制訓練的並行,此引數只有在安裝了Cpython後才有效,否則只能使用單核。

Embedding

Word2Vec中從輸入到隱層的過程就是Embedding的過程。 Embedding的過程就是把多維的onehot進行降維的過程,是個深度學習的過程。滿足:

  1. 嵌入層向量長度可設定
  2. 對映過程是全連線
  3. 嵌入層的值可訓練
  4. 由高維度對映到低緯度,減少引數量

參考部落格:Word2VecEmbeddingSkip-gram的原理負取樣

相關文章