以下內容均來自: https://ptorch.com/news/11.html
word embedding也叫做word2vec簡單來說就是語料中每一個單詞對應的其相應的詞向量,目前訓練詞向量的方式最常使用的應該是word2vec(參考 http://www.cnblogs.com/bamtercelboo/p/7181899.html)
Word Embedding
在自然語言處理中詞向量是很重要的,首先介紹一下詞向量。
之前做分類問題的時候大家應該都還記得我們會使用one-hot
編碼,比如一共有5類,那么屬於第二類的話,它的編碼就是(0, 1, 0, 0, 0),對於分類問題,這樣當然特別簡明,但是對於單詞,這樣做就不行了,比如有1000個不同的詞,那么使用one-hot這樣的方法效率就很低了,所以我們必須要使用另外一種方式去定義每一個單詞,這就引出了word embedding
。
我們可以先舉三個例子,比如
- The cat likes playing ball.
- The kitty likes playing wool.
- The dog likes playing ball.
- The boy likes playing ball.
假如我們使用一個二維向量(a, b)來定義一個詞,其中a,b分別代表這個詞的一種屬性,比如a代表是否喜歡玩飛盤,b代表是否喜歡玩毛線,並且這個數值越大表示越喜歡,這樣我們就可以區分這三個詞了,為什么呢?
比如對於cat,它的詞向量就是(-1, 4),對於kitty,它的詞向量就是(-2, 5),對於dog,它的詞向量就是(3, -2),對於boy,它的詞向量就是(-2, -3),我們怎么去定義他們之間的相似度呢,我們可以通過他們之間的夾角來定義他們的相似度。
上面這張圖就顯示出了不同的詞之間的夾角,我們可以發現kitty和cat是非常相似的,而dog和boy是不相似的。
而對於一個詞,我們自己去想它的屬性不是很困難嗎,所以這個時候就可以交給神經網絡了,我們只需要定義我們想要的維度,比如100,然后通過神經網絡去學習它的每一個屬性的大小,而我們並不用關心到底這個屬性代表着什么,我們只需要知道詞向量的夾角越小,表示他們之間的語義更加接近。
下面我們使用pytorch來實現一個word embedding
代碼
在pytorch里面實現word embedding
是通過一個函數來實現的:nn.Embedding
# -*- coding: utf-8 -*- import numpy as np import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variable word_to_ix = {'hello': 0, 'world': 1} embeds = nn.Embedding(2, 5) hello_idx = torch.LongTensor([word_to_ix['hello']]) hello_idx = Variable(hello_idx) hello_embed = embeds(hello_idx) print(hello_embed)
這就是我們輸出的hello這個詞的word embedding,代碼會輸出如下內容,接下來我們解析一下代碼:
Variable containing: 0.4606 0.6847 -1.9592 0.9434 0.2316 [torch.FloatTensor of size 1x5]
首先我們需要word_to_ix = {'hello': 0, 'world': 1}
,每個單詞我們需要用一個數字去表示他,這樣我們需要hello的時候,就用0來表示它。
接着就是word embedding
的定義nn.Embedding(2, 5)
,這里的2表示有2個詞,5表示5維度,其實也就是一個2x5的矩陣,所以如果你有1000個詞,每個詞希望是100維,你就可以這樣建立一個word embedding
,nn.Embedding(1000, 100)
。如何訪問每一個詞的詞向量是下面兩行的代碼,注意這里的詞向量的建立只是初始的詞向量,並沒有經過任何修改優化,我們需要建立神經網絡通過learning
的辦法修改word embedding
里面的參數使得word embedding
每一個詞向量能夠表示每一個不同的詞。
hello_idx = torch.LongTensor([word_to_ix['hello']]) hello_idx = Variable(hello_idx)
接着這兩行代碼表示得到一個Variable
,它的值是hello
這個詞的index
,也就是0。這里要特別注意一下我們需要Variable,因為我們需要訪問nn.Embedding
里面定義的元素,並且word embeding
算是神經網絡里面的參數,所以我們需要定義Variable
。
hello_embed = embeds(hello_idx)
這一行表示得到word embedding
里面關於hello
這個詞的初始詞向量,最后我們就可以print出來。