CS224n筆記1:自然語言處理簡介

關鍵詞:自然語言處理(NLP),詞向量(Word Vectors),奇異值分解(Singular Value Decompositon),Skip-gram,CBOW,負抽樣(Negative Sampling),層次Softmax(Hierachical Softmax),Word2Vec。

這章首先主要介紹自然語言處理(NLP)的概念,以及目前工作中所遇到的難點。緊接著,進一步討論詞語(words)的數值型向量表示概念。最后,我們討論幾種設計詞向量的主流方法。

1 自然語言處理簡介


我們首先簡單討論下什么是自然語言處理。

1.1 自然語言處理有什么特別之處?


人類語言(自然語言)有什么特別之處?人類語言是用來傳遞信息,表達意圖的特有系統,它不是由任何物理表現產生的。也就是說,它不同于視覺以及其他任何機器學習任務。
大部分詞僅僅是非語言實體的符號:這個詞是一個映射到特定思想或是事物的符號。
例如,單詞rocket是指一個rocket的概念,通過拓展可以把它當做rocket的一個實例。不過,也有一些例外,當我們使用單詞和字母表達信號時,例如Whooomppa。上述提到的語言符號,可以通過向大腦神經傳遞連續信號,編譯為一些形式:聲音,手勢,書寫等。

1.2 自然語言處理任務的一些例子


在自然語言處理中有不同層次的任務,從語音處理到語義和篇章層次的處理。自然語言處理的目的是能夠設計一個算法,使得計算機可以理解自然語言,從而去執行一些任務。下面為各種難度等級的任務實例:

簡單

  • 拼寫檢查(Spell Checking)
  • 關鍵詞搜索(Keyword Search)
  • 查找同義詞(Finding Synonyms)

中度

  • 從網站,文獻中解析信息(Parsing information from websites, documents, etc.)

困難

  • 機器翻譯(Machine Translation) - 例如,將中文文本翻譯為英文。
  • 語義分析(Semantic Analysis)- 查詢語句到底是什么意思?
  • 指代消解(Coreference)- 給定文檔中'他'或者'它'代指什么?

1.3 如何表示單詞?


貫穿所有的自然語言處理任務中,最重要的,也是無可爭論的共同點就是我們該如何表示一個單詞,讓它作為我們模型的輸入。為了讓自然語言處理任務處理地更好,首先我們需要定義單詞之間的相似性和差異性概念。使用詞向量(word vectors),我們可以很容易地把這種特性編譯到向量中去(使用距離方法,例如杰卡德距離,與余弦距離,歐幾里得距離等等)。

2 詞向量


英語中大約有1300萬字符,但是,它們之間都是無關的,相互獨立的嗎?比如,貓科動物(feline)和貓(cat),旅館(hotel)和汽車旅館(motel)?答案是并不都無關聯的。因此,我們希望把這些單詞字符一一編譯為向量,來表示‘單詞’(word)空間里的一個點。我們有很多的理由認為單詞字符的向量化至關重要,那么最直觀的理由就是:或許真的存在一些N維空間(例如N << 1300萬)能夠充分編譯我們語言的所有語義。每一個維度將會編譯我們言語中所傳達的含義。例如,語義維度可以指示時態,單復數,以及性別。
讓我們來研究一下我們的第一個詞向量,可以說是最簡單的詞向量:one-hot vector。one-hot vector 使用只有一個元素為1,其余都為0的向量,1位于該單詞所在的索引位置。在這個概念中,|V|是我們詞匯的大小。以這種方式編碼的詞向量形如下面的單詞表示形式:

我們把每一個單詞(word)表示為完全獨立的實體。就像我們之前所談論的,這種單詞的表示方法并沒有向我們提供任何相似(詞與詞之間的相似度)的概念。例如,

所以,或許我們可以嘗試削減R|V|空間的大小,從而找到一個子空間,用來編碼詞與詞之間的聯系。

3 基于奇異值分解(SVD)的方法


使用這類方法去尋找詞嵌入(word embeedings),或者說是詞向量(word vectors),我們首先需要遍歷一個大規模的數據集,以矩陣X的方式計算并存儲詞共現數(word co-occurrence counts),然后對X進行奇異值分解,得到USVT。接著,我們使用U的行向量作為我們詞典中所有單詞的詞嵌入(詞向量)。讓我們討論下關于X的選擇。

3.1 詞-文檔矩陣(Word-Document Matrix)


作為第一次嘗試,我們大膽地猜想相關的單詞將會出現同一篇文檔中。例如,banksbonds, stocks, money等單詞很有可能一起出現。但是banks, octopus, banana,以及hockey可能不會始終一起出現在同篇文檔中。我們基于這個事實,通過以下方法建立一個詞-文檔矩陣X:遍歷數十億的文檔,單詞i在文檔j中每出現一次,便將元素Xij加上1。顯然這是一個非常巨大的矩陣(R|V|×M),它與文檔的數量(M)成比例。所以,或許我們可以嘗試下一些更好的方法。

3.2 基于窗口的共現矩陣(Window based Co-occurrence Matrix)


上面的邏輯同樣適于這里,不過矩陣X存儲的是單詞與附近單詞的共現,從而得到一個關聯矩陣(affinity matrix)。在這種方法中,我們計算感興趣的那個單詞特定大小窗口里的每個單詞出現的次數。同樣,我們計算語料庫中所有單詞的這個數目。下面,我們展示一個樣例。假定我們的語料庫中僅包含三個句子,窗口大小為1:

  1. I enjoy flying.
  2. I like NLP.
  3. I like deep learning.

由此,形成的計數矩陣為:

3.3 共現矩陣奇異值分解(Applying SVD to the cooccurrence matrix)


現在,我們對X進行奇異值分解,觀察奇異值(矩陣S的對角線元素),然后根據我們期望捕獲到的方差占比在某個索引k處將其截斷:

然后,我們將U1:|V|,1:k的子矩陣作為我們的詞嵌入矩陣。這將會為我們詞匯表中每個單詞提供一個k維向量表示形式。
總結起來,一共分下面幾個步驟:

  • 生成一個|V|×|V|共現矩陣X
  • 對X進行奇異值分解,得到X = USVT
  • 選擇U的前k列,得到一個k維詞向量
  • 被前k維所捕獲到的方差為:上圖中的表達式

對X進行奇異值分解:

通過選擇前k個奇異向量進行降維:


這兩種方法都給我們提供了足以編碼語義和句法(詞性)信息的詞向量,但也存在了許多其它問題:

  • 新單詞的頻繁添加以及語料庫大小的變換使得矩陣的維數變換頻繁。
  • 大部分詞組不存在共現使得矩陣特別稀疏。
  • 矩陣維度過高,通常為10^6 × 10^6。
  • 訓練的開銷過大,呈二次型(如執行奇異值分解)。
  • 需要一些技巧解決詞頻的急劇失衡。

針對上述存在的一些問題,有以下解決方法:

  • 忽略一些虛詞,如“the”,“he”,“has”等。
  • 利用傾斜窗口——根據文檔中詞與詞之間的距離來加權共現次數。
  • 使用Pearson相關矩陣,并把負計數設置為0,而不是使用原來的計數方式。

在下面的章節中,基于迭代的方法能夠以更優雅的方式解決以上的一些問題。

基于迭代的方法 - Word2Vec

我們可以嘗試創建一個模型,一次性只能學習一次迭代,最終可以根據上下文語境給出一個詞出現的概率;而不是像之前一樣計算和存儲一些龐大數據集的全部信息(可能是數10億句)。

這一方法的主要思路就是:設計一個模型,用該模型的參數來表示詞向量,然后基于語料庫進行訓練。在每一次迭代中,我們評估模型的誤差,然后對參數進行更新。我們稱這種方法為‘反向傳播’誤差。模型和任務越簡單,模型訓練的速度越快。

[Collobert et al., 2011]設計NLP模型的第一步就是將每一個單詞轉化為向量的形式。在一些特殊任務中(命名實體識別,詞性標注等),他們不僅僅訓練模型的參數,還訓練更好的詞向量以追求更高的性能。

接下來,我們主要介紹一個更簡單的,更前沿的,基于概率方法的模型:word2vec。Word2vec是一個軟件包,主要包括:

2個算法: continuous bag-of-words (CBOW)和skip-gram。CBOW旨在根據上下文窗口語境預測中間詞。Skip-gram與之相反,他根據中心詞預測該詞的上下文語境。
2個訓練方法:negative sampling和hierarchical softmax。negative sampling通過負抽樣來定義一個目標詞。然而,hierarchical softmax通過使用一個高效的樹結構計算所有詞匯的概率來定義目標詞。

4.1 語言模型(Language Models)

首先,我們需要創建一個可以計算字符序列出現概率的模型。讓我們看下下面的例子:
"The cat jumped over the puddle."
一個好的語言模型可以賦予這個句子高的概率。因為這句話符合句法和語義,通俗一點,他是一句人話。相反,應該賦予"stock boil fish is toy"這句話低的概率,因為這句話不是人話,沒有任何意義。我們可以用以下數學表達式來表示給定n個單詞序列的概率:


我們假定每個單詞的出現時相互獨立的,那么上面的一元模型的概率可以拆散為以下形式:

然而,我們知道這有一些荒唐,因為下一個詞的出現高度依賴于先前的單詞序列。有可能導致那些愚蠢的,不像人話的句子被賦予的分數較高。因此,也許我們可以讓序列的概率取決于序列中一個單詞的成對概率和它旁邊一個單詞的概率。我們稱之為二元語言模型(bigram model),表示如下:

當然,這還是有點幼稚,因為我們只考慮一對相鄰的詞,而不是計算整個句子。但是,我們將會看到,這種表示方法使我們能夠前行的更遠。通過一個上下文大小為1的詞矩陣,我們基本上能夠獲取這些成對詞語的概率。但是,這需要計算和儲存一個海量數據集的全部信息。

既然我們已經明白如何理解一個擁有概率性質的字符序列,那么接下來,我們將會介紹一些可以自主學習這些概率的模型。

4.2 CBOW模型

一種方法是把{'The', 'cat', 'over', 'the', 'puddle'}作為上下文,來預測中心詞語'jumped'。我們稱這類模型為Bag of Words (CBOW)模型。

讓我們詳細地討論下CBOW模型。首先,我們設定一些已知的參數。這些已知參數為用于表示單詞的one-hot向量。我們用x(c)表示輸入的one_hot向量(上下文),用y(c)表示輸出。在CBOW模型中,只有一個輸出,所以我們稱y為已知中心詞的one-hot向量。接下來,讓我們定義模型中未知的參數。

我們創建兩個矩陣,v∈Rn×|V|u∈R|V|×n。n為詞嵌入向量的大小,v為輸入詞矩陣,其中,當wi為模型的一個輸入時,v的第i列為單詞wi的n維詞嵌入向量。我們把這個n×1向量定義為vi。相似的,u為輸出詞矩陣,當wi模型的一個輸出時,u的第j行為單詞wj的n維詞嵌入向量。我們把u的第j行定義為uj。請注意:我們實際上為每個單詞wi學習了兩個詞向量(輸入詞向量vi和輸出詞向量ui)。
CBOW模型參數:

  • wi: 詞匯V中的單詞i
  • v∈Rn×|V|: 輸入詞矩陣
  • vi: v的第i列,單詞wi的輸入詞向量表示
  • u∈R|V|×n: 輸出詞矩陣
  • ui: u的第i列,單詞wi的輸出詞向量表示

我們將模型的工作流程分解為以下幾個步驟:

  1. 獲取輸入的one-hot向量,窗口大小為m : (x(c-m),..., x(c-1), x(c+1),..., x(c+m)∈R|V|)。
  2. 我們得到輸入窗口語料的詞嵌入向量 (v(c-m)=vx(c-m), v(c-m+1)=vx(c-m+1), ... ,v(c+m)=vx(c+m)∈Rn)
  3. 求取這些向量的平均值,得到:
  1. 生成一個分數向量(score vector):z,由于向量之間越相似,其點積越高,所以相似的單詞將會離得更近以得到更高的分數。
  1. 利用Softmax函數將分數轉換為概率的形式:
  1. 我們期望預測的概率y_hat能夠與真實概率y相匹配,即巧好是目標單詞的one-hot向量。

既然我們已經了解了當我們擁有vu兩個矩陣后,我們的模型是怎么工作的。那么,我們該怎么去學習獲取這兩個未知參數矩陣呢?這時,我們需要創建一個目標函數。通常,當我們從某種真實概率中學習概率時,我們會借助信息理論來度量兩個分布之間的距離。這里,我們使用最常用的距離/損失度量,交叉熵。在離散情況下,使用交叉熵的靈感來自于下面的損失函數:

讓我們考慮下CBOW這個案例,y為one-hot向量。因此,上面的損失函數可以簡化為:

在這個公式中,c是指目標單詞one-hot向量為1的索引。假設我們的預測非常完美時,我們可以算得:

因此,對于一個完美的預測,不會得到懲罰或者損失。假設我們的預測很差,為0.01,則我們可以得到:

因此,我們可以看出對于概率分布,交叉熵為我們提供了一個很好的度量距離(誤差)的方法。因此,我們把我們模型的優化目標設置為:

我們采用隨機梯度下降法(stochastic gradient descent)更新所有相關的詞向量uc和vj

4.3 Skip-Gram模型 (CBOW)

另一種方法是創建一個模型,給定一個中心單詞'jumped',該模型能夠預測周邊單詞(上下文):'The', 'cat', 'over', 'the', 'puddle'。這里,我們稱單詞'jumped'為語境(context)。我們稱這類模型為Skip-Gram模型。

Skip—Gram模型和CBOW模型很相似,不過這里我們把x和y進行了交換,即CBOW中的x現在變為了y,反之亦然。我們用x表示輸入的one-hot向量(中心單詞),盡管這里只有一個單詞。用y(j)表示輸出向量。vu的定義和CBOW中的定義相同。

我們把Skip-Gram模型的工作流程拆分為以下6個步驟:

  1. 獲取中心單詞的one-hot輸入向量x∈R|V|
  2. 求取中心單詞的詞嵌入向量vc =vx ∈ Rn
  3. 計算分數向量z = uvc
  4. 通過Softmax函數將分數向量轉換為概率:

注意:每個上下文詞的概率為:

  1. 我們期望計算出的概率和真實概率y(c-m),..., y(c-1), y(c+1),..., y(c+m)相匹配。

正如CBOW模型那樣,我們同樣也需要定義一個目標函數來衡量我們的模型。最重要的一個區別是,在Skip-Gram模型中我們引入樸素貝葉斯假設來分解概率。簡單地說,就是一個強條件獨立假設。換句話說,給定中心單詞,所有的輸出單詞完全相互獨立。

通過目標函數,我們計算未知參數的相應梯度,以及在每次迭代中通過隨機梯度下降法更新這些未知參數。
注意:

注:在Skip-Gram模型中,只輸出了一個概率向量。Skip-Gram模型同等對待每一個背景詞:模型計算每一個背景詞的出現概率,和背景詞到中心詞的距離無關。

4.4 負抽樣(Negative Sampling)

接下來,讓我們探討一下目標函數。在$|V|$維數據上進行求和的計算量巨大!目標函數的任何更新后者計算將會消耗大量的時間。我們可以嘗試通過近似的方法去提高效率。

在每次訓練過程中,我們可以僅僅抽取幾個負樣本,而不是循環遍歷整個詞匯表!我們從一個噪聲分布({% math %}P_n(w){% endmath %})中抽樣,其概率與詞匯表中詞頻相匹配。如果把負抽樣機制應用到模型中,我們需要調整以下幾點:

  1. 目標函數
  2. 梯度
  3. 更新規則

雖然負抽樣基于Skip-Gram模型,但實際上它優化了一個不同的目標函數。(w, c)(w, c分別為單詞(word)和上下文(context))是否真的來自訓練數據集(即w, c是否分別對應為訓練集的中心詞(輸入)和背景詞(輸出)?記P(D = 1|w, c)為(w, c)來自語料庫數據的概率,相應的P(D = 0|w, c)為(w, c)不是來自語料庫的概率。首先,我們用sigmoid函數來模擬P(D = 0|w, c):

說明:sigmoid函數為softmax的1維特殊形式,可以用于表示概率。如下圖所示:

現在,我們建立了一個新的目標函數,試圖當(w, c)來自語料庫時最大化概率P(D = 1|w, c),當(w, c)不是來自語料庫時,最大化概率P(D = 0|w, c)。我們采用最大似然估計(MLE)來計算這兩個概率。(這里,我們記θ為模型的參數,在word2vec模型里對應著vu。)

所以最大化似然函數等同于最小化下面的負對數似然函數:

記Dfalse為錯誤(false)/負(negative)語料庫。當我們有一個句子,例如"stock boil fish is toy"。不自然的句子出現的概率應該很低。我們可以從詞庫里隨機抽取生成負樣本Dfalse

對于Skip-Gram模型,給定中心詞c觀察到上下文c-m+j的目標函數為:

對于CBOW模型,給定(上下文)背景詞向量,觀察到中心詞uc的目標函數為:

其中,負樣本服從Pn(w)分布。但是Pn(w)該是什么樣的呢?經過多次地討論以及實驗如何做出最好的近似,似乎一元文法模型(Unigram Model)的3/4次方的效果最好。為什么是3/4呢?下面的例子可能會幫助你理解一下:

is: 0.93/4 = 0.92
Constitution: 0.093/4 = 0.16
bombastic: 0.013/4 = 0.032

可以看出:"Bombastic"現在被抽到的可能性是之前的3倍,然而"is"僅僅提升了一點。

4.4 層次Softmax(Hierarchical Softmax)

在實踐中,層次softmax對低頻單詞的效果較好。然而負抽樣對高頻單詞以及低維向量的效果較好。

層次softmax采用二叉樹展示詞匯表中的所有單詞。樹的每一個葉子節點代表一個單詞,并且從根節點到葉節點的路徑是唯一的。在這個模型中,樹的每一個節點(除了根節點和葉節點)都對應著一個向量,這個向量需要模型去學習。

給定一個向量wi,單詞w的概率P(w | wi)等于從根節點隨機游走,最終到達葉節點w的概率。這種計算概率的方式的主要優點是花銷僅僅為O(log(|V|))。

用L(w)表示從根節點到葉節點w的節點數。例如(如下圖所示):

L(w2)為3。用n(w, i)表示路徑中第i個節點,對應的向量表示為vn(w,i)。所以n(w, 1)為根節點,n(w, L(w))為w的父節點。現在,對于每一個內層節點n,我們任意挑選一個子節點,用ch(n)表示(例如,總抽取左節點)。然后,我們可以計算概率:

σ(.)為sigmoid函數。

這個公式有點復雜,讓我們來好好地研究一下:

首先,我們根據從根節點(n(w,1))到葉節點(w)的路徑形狀計算每一項的乘積。如果我們假設ch(n)總是n的左節點,那么當路徑沿著左側行走時,[n(w, j+1) = ch(n(w, j))]為1,當沿著右側時,為-1。

此外,[n(w, j+1) = ch(n(w, j))]起到了正則化的作用(概率的公理化定義)。即在節點n處,向左和向右的概率相加為1:

同時正則化就像在原始softmax中那樣也保證了:

最后,我們使用點積計算輸入向量vwi和每個內節點向量vTn(w,j)的相似性。讓我們看下示例:在上圖中選取w2,我們必須通過兩個左節點和一個右節點才能從根節點到達w2,所以:

為了訓練模型,我們的目標依然是最小化負對數釋然-log P(w| w_i)。但是我們在訓練過程不再更新每個單詞的輸出向量,而是更新二叉樹中從根節點到葉節點路徑上的節點單詞的向量。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容