斯坦福自然語言處理_第三講(Part 1)


本次課程的主講人是Richard Socher,第三講的重點是對word2vec的回顧和深入理解,包括在數據降維中用到的SVD(Singular Value Decomposition,奇異值分解)的原理、實現以及存在的問題。之後會詳細介紹本次課程的重點——GloVe(2014,其作者就包括了Stanford cs224 的兩位主講人Richard Socher和Manning教授)。

對詞向量的深入探究

  • Finish word2vec

  • What does word2vec capture

  • How could we capture this essence more effectively?

  • How can we analyze word vectors?

    複習回顧:word2vec的主要思想

    • 遍歷整個語料庫中的每一個單詞

    • word2vec中存在一個窗口(window)的概念,對於每一個窗口中的中心詞(window’s center)我們要預測它的窗口內的上下文單詞(surrounding words)

      p(oc)=exp(uoTvc)w=1Vexp(uwTvc)p(o|c) = \displaystyle \frac{exp({u_{o}}^Tv_{c})}{\sum_{w=1}^V exp({u_{w}}^Tv_{c})}

      在該式中,oo是輸出的上下文單詞中確切的某一個(outside words),c是中心詞(center word),vcv_{c}uou_{o}是中心詞和上下文單詞的向量形式表示。

    • 接下來對每一個這樣的窗口做隨機梯度下降(Stochastic Gradient Descent)

    Case study

    Alt

    如上圖所示這樣的一個語句,此時我們選取"deep”作爲中心詞,我們首先計算第一個外部單詞(outside word) “I” 的概率。

    p(Ideep)=exp(uITvdeep)w=1Vexp(uwTvc)p(I|deep)=\displaystyle\frac{exp(u_{I}^{T}v_{deep})}{\sum_{w=1}^{V}exp({u_{w}}^Tv_{c})}

    其中分子部分是上下文單詞"I"的向量表示uIu_{I}和中心詞"deep"的向量表示vdeepv_{deep}做點乘,如果向量uu和向量vv越相似,其點乘後的內積越大;分母部分是遍歷詞彙表中的每一個單詞,將它們與中心詞點乘後累加求和。這裏用softmax對分子分母取指數形式,將計算得到的數值轉化爲一種概率分佈。

    同樣,我們計算第二個單詞"like"的概率,諸如此類。

    以上是以“deep”作爲中心詞,計算上下文單詞的出現概率,計算完成後,窗口右移,以"learning"作爲中心詞計算上下文單詞的概率,以此類推。

    在訓練一開始的時候,對詞進行表示的所有向量都是隨機的,然後對這些向量進行求導,爲了最終能夠最大化概率,對每一個窗口進行隨機梯度下降。但是每一個窗口最多隻有2m+12m+1個詞,因此θJt(θ)∇θJt(θ) 會非常稀疏.

    【分析】

    在上述式子中,分母要遍歷語料庫詞彙表中每一個單詞,將其與中心詞進行點乘求和,當詞彙表非常大時,需要很多的計算資源。而且很多單詞與其他詞從未併發出現過。

    【解決方法】

    實際上,我們只需要對預測出來的窗口中的上下文單詞與原本單詞進行對比,因此每次更新只更新WW矩陣的少數列(對uuvv的完全嵌入),或者爲每個詞向量建立一個哈希映射,在哈希映射中鍵(key)是詞的字符串表示,值(value)是詞的向量表示。

    You could also implement this as essentially a hash where you have keys and values.The values are the vectors,and the keys are the word strings.

    近似:負採樣(任務1)

    每次梯度更新都需要計算一遍中心詞向量和其他詞向量的內積,這是一個不小的計算量,我們重新觀察下式,會發現分子部分的計算非常簡單,即兩個上百維向量做點乘,這一部分計算非常快;但是遍歷整個語料庫所得到的每一個窗口,對每一個詞求概率時,在分母部分都需要做一個巨大的求和,並且很多詞和其他單詞從未併發出現過。

    p(oc)=exp(uoTvc)w=1Vexp(uwTvc)p(o|c) = \displaystyle \frac{exp({u_{o}}^Tv_{c})}{\sum_{w=1}^V exp({u_{w}}^Tv_{c})}

    因此負採樣的策略產生了,他隨機抽取一定數目的隨機詞(儘量在中心詞上下文中沒出現過的詞),然後最小化中心詞和他們出現的概率,最大化中心詞和上下文詞出現的概率。

    因此在這裏佈置了任務1,用負採樣來實現skip-gram。

    Main idea: train binary logistic regressions for a true pair(center word and word in its context window) versus a couple of noise pairs(the center word paired with a random word)

    主要思想:訓練一對真實對的二元邏輯迴歸(其實也就是一個二分類器,中心詞和上下文窗口中的單詞)與幾對噪聲對(中心詞與隨機詞配對)

    總體目標函數: J(θ)=1Tt=1TJt(θ)J(\theta)=\displaystyle\frac{1}{T}\sum_{t=1}^{T}J_{t}(\theta) ,其中T在這裏對應着遍歷語料庫的每一個窗口

    Jt(θ)=log σ(uoTvc)+i=1kEjP(w)[logσ(ujTvc)]J_{t}(\theta)=log \:\sigma(u_{o}^Tv_{c})+\displaystyle\sum_{i=1}^{k}\mathbb{E}_{j \sim P(w)}[log \sigma(-u_{j}^Tv_c)]

​ k就是我們採用的負採樣的個數,下標t代表的就是某個窗口。該式中的第一項是中心詞和窗體中上下文單詞併發出現的對數概率,這裏的Sigmoid 函數 σ(x)=11+ex\sigma(x)=\displaystyle\frac{1}{1+e^{-x}} ,圖像如下,可以看到在趨於正無窮或負無窮時,函數趨近平滑狀態,並且該函數輸出範圍在(0,1)之間,因此通常用於表徵事件概率,函數具有非常好的對稱性。

Alt

​ 對向量之間進行點乘,所得到的內積可以表徵詞之間的相關性,而上述目標函數就是要最大化中心詞與其上下文單詞的相關概率,最小化與其他未併發出現詞語的相關概率。因此,每次的梯度更新只需要更新對應向量即可,不需要對所有向量進行計算,以此大大減少了計算量。

Word2vec improves objective function by putting similar words nearby in space.

Word2vec 通過把相似的詞語放在同一個地方來最大化目標函數。

Alt

對word2vec的總結概括

  • 遍歷整個語料庫的每一個單詞
  • 將每一個單詞作爲中心詞,預測其上下文單詞
  • 每一次計算可以捕獲到一個併發出現的單詞
    • 爲什麼不直接捕獲詞與詞之間的併發計數呢?

詞共現矩陣

(Yes,We can!)

可以用一個詞共現矩陣XX來實現。

基於統計共現矩陣的方法早在word2vec之前就已經存在,主要分爲兩種,一種是將窗口視爲訓練單位,另一種是對整個文檔構建一個完全的詞併發矩陣。

  • 如果在整個文檔級別上進行統計,會得到一些綜合性主題(general topics),最終導向"潛在語義分析"(Latent Semantic Analysis,LSA)“
  • 如果類似於word2vec,在基於窗口級別上統計詞性和語義共現,可以同時捕獲到句法(POS)和語義信息。

示例:基於窗口的共現矩陣

  • 本例中窗口半徑爲1(更常用的窗體半徑是5-10)

  • 在如下句子上統計共現次數:

    • I like deep learning.
    • I like NLP.
    • I enjoy flying.

    得到詞共現矩陣如下:

  • 這種樸素共現向量出現的問題:

    • 矩陣的大小隨詞彙表的增大而劇增

    • 也因此向量具有非常高的維度,需要佔用很大的存儲空間

    • 隨後的分類模型會出現稀疏性問題

      -> 模型缺少魯棒性(robust)

  • 解決辦法:低維向量

    • 以一個固定的,低維向量來存儲"最"最要信息:一個密集向量

    • 通常在25-1000維,類似於word2vec

    • 怎麼實現降維呢?

      ——SVD(Singular Value Decomposition)

Basically,we’ll have this X hat matrix,which is going to be our best rank k approximation to our original co-occurrence matrix X.And we will have three simple matrices with orthonormal columns.U we often call also left-singular vectors and we have here S the diagonal matrix containing all the singular values usually from largest to smallest.And we have our matrix V here,our orthonormal rows.

這種方法在代碼中的表現也同樣簡單明瞭:

import numpy as np
import matplotlib.pyplot as plt
la = np.linalg
words = ["I" , "like" , "enjoy" , "deep" , "learning" , "NLP" , "flying" , "."]
X = np.array([
    [0,2,1,0,0,0,0,0],
    [2,0,0,1,0,1,0,0],
    [1,0,0,0,0,0,1,0],
    [0,1,0,0,1,0,0,0],
    [0,0,0,1,0,0,0,1],
    [0,1,0,0,0,0,0,1],
    [0,0,1,0,0,0,0,1],
    [0,0,0,0,1,1,1,0]
])
U, s, Vh = la.svd(X, full_matrices=False)
for i in range(len(words)):
    plt.scatter(U[i, 0], U[i, 1])
    plt.text(U[i, 0], U[i, 1], words[i])
plt.show()


在pycharm中執行如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章