け日記

最近はPythonでいろいろやってます

論文メモ: GloVe: Global Vectors for Word Representation

前々回の投稿でGloVeで単語ベクトルを計算しましたが、今回の投稿ではその提案論文を整理したいと思います。

nlp.stanford.edu

ohke.hateblo.jp

GloVe: Global Vectors for Word Representation

@inproceedings{pennington2014glove,
  author = {Jeffrey Pennington and Richard Socher and Christopher D. Manning},
  booktitle = {Empirical Methods in Natural Language Processing (EMNLP)},
  title = {GloVe: Global Vectors for Word Representation},
  year = {2014},
  pages = {1532--1543},
  url = {http://www.aclweb.org/anthology/D14-1162},
}

Abstract

グローバルなMatrix Factorizationとローカルなコンテキストウィンドウを組み合わせることでいいとこ取りを目指してます。

1 Introduction

これまで単語のベクトル表現を獲得する方法は大きく2つで、それぞれ固有の問題を持っています。

  • 文書全体の単語の共起行列からMatrix Factorizationすることで獲得する、カウントベースな方法
    • ここで使う行列には、単語-文書 (ex.LSA) と 単語-単語 (ex. Hyperspace Analogue to Language: HLA) の2パターンがある
    • "the"や"a"などの頻出単語の影響を除去するために、エントロピや相関係数で正規化する
  • 単語の前後 (ウィンドウ) の出現単語を予測することで獲得する、予測ベースな方法 (ex. skip-gram word2vec)

グローバルにlogbilinearを適用することでいいとこ取りができないだろうか?
グローバルな単語-単語の共起を、重み付き最小2乗で学習するモデルを提案する。

3 The GloVe Model

Global Vectorsで新しいベクトル表現を作ります。

  • 単語-単語の共起カウントを行列  X とする
    •  X_{ij} は単語iの文脈で何回単語jが現れたのかを表す (非対称行列)
    •  X_{i}=\sum_{k}X_{ik} で、単語iの文脈で現れた総単語数
  •  P_{ij}=P(j|i)=X_{ij}/X_{i} は、単語iの文脈で単語j現れる確率を表す

i="ice", j="stream"で例示しながら、提案モデルの原理となる共起確率の比について説明していきます。

  • 文脈に現れる単語k="solid" なら P(k|ice) > P(k|steam) となる → P(k|ice)/P(k|steam) >> 1.0
    • つまり、"solid"が現れやすいのは、"steam"よりも"ice"の文脈
    • 逆に k="gas" なら P(k|ice) < P(k|steam) → P(k|ice)/P(k|steam) << 1.0
    • もしkが"water"や"fashion"のような一般的な言葉であれば、P(k|ice)とP(k|steam)の差は小さくなる → P(k|ice)/P(k|steam) ≒1.0
  • こうみると、P(k|ice)/P(k|steam) が1から遠いほど関連が強く、1に近いほど関連が弱い、という関係が表されている
    • 2単語の共起確率そのものではなく、別のある単語 (k) を介したときの共起確率の比が重要ではないか

この2つの単語 (i, j) および文脈単語 (k) を使って定式化を行う。

  •  w \in \mathbb{R}^{d} は、単語iと単語jのベクトル
  •  \tilde{w} \in \mathbb{R}^{d} は、文脈単語k (複数) のベクトル (4.2で議論する?)


F(w_{i},w_{j},\tilde{w_{k}})=\frac{P_{ik}}{P_{jk}}

上の関数Fをモデル化していきます。

まずはパラメータを単純にします。
単語ベクトルは線形構造なのでベクトル間の差として表現できます。加えて、転置・内積によって左辺のパラメータを1つにまとめることで、シンプルになります。


F((w_{i}-w_{j})^{T}\tilde{w_{k}})=\frac{P_{ik}}{P_{jk}}

Fについて  (\mathbb{R}, +)  (\mathbb{R_{>0}}, \times) が準同型 (Wikipedia) を仮定すると、以下のように変形できます。


F((w_{i}-w_{j})^{T}\tilde{w_{k}})=\frac{F(w_{i}^{T}\tilde{w_{k}})}{F(w_{j}^{T}\tilde{w_{k}})}
\Leftrightarrow F(w_{i}^{T}\tilde{w_{k}})=P_{ik}=\frac{X_{ik}}{X_{i}}

F=expとおくと以下の形になります。


w_{i}^{T}\tilde{w_{k}}=log(P_{ik})=log(X_{ik})-log(X_{i})

で、最後に  log(X_{i})  w_{i} のバイアス  b_{i}  \tilde{w_{k}} のバイアス  \tilde{b_{k}} にします。

  • 共起行列の対数を因数分解する発想はLSAに近い


w_{i}^{T}\tilde{w_{k}}+b_{i}+\tilde{b_{k}}=log(X_{ik})

上で得られた式を、最小二乗法で単語ベクトルを求めるための損失関数として定義すれば、学習タスクに落とし込めます。

  • Vはボキャブラリサイズ (単語の種類数)


J=\sum_{i,j=1}^V f(X_{ij})(w_i^T\tilde{w_j} + b_i + \tilde{b_j} - logX_{ij})^2

関数  f は重みをつけるためのもので、コーパス全体で頻出するワード (助詞や指示語など) の重みを低くします。

  •  x_{max}  \alpha をハイパーパラメータとして選択する必要がある
    •  \alpha は、1よりも3/4の方が性能は良かった

f:id:ohke:20181101230625p:plain

4 Experiments

単語類推タスク

"a is to b as c is to ?"を類推するタスクです。word2vecのときと同じですね。
タスクは意味的な類推 (例えば"Athens is to Greece as Berlin is to
?"で、表中ではSem.) と構文的な類推 (例えば"dance is to dancing as fly is to __?"で、表中ではSyn.) の2種類があります。
タスクでは  w_{b}-w_{a}+w_{c} のベクトルと、最もコサイン類似度が近い単語ベクトルを計算することによって導出されます。

GloVeと他のモデルを比較した表が以下です (Table 2抜粋) 。いずれもGloVeが最も高い精度をマークしています。

  • word2vec (SG) もやっぱり強くて、従来の他の方法よりもかなり良い精度を示している
  • GloVeなら420億単語の巨大なコーパスでも学習でき、かつ、相応の精度向上が実現できている
    • 単純なSVD-L (対数のSVD) ではトークンサイズが増えると性能劣化が見られるため (56.6%→38.4%) 、GloVeで追加した重み関数fが効いていると思われる

f:id:ohke:20181102161844p:plain

その他、類似単語や名前エンティティ認識のタスクにおいても、他のモデルよりも概ね一貫して高い精度をマークしました。

ベクトル次元数とコンテキストサイズ

ベクトル次元数とコンテキストサイズを変更した場合の、単語類推タスク (トークン数60億) の精度を下表 (Figure 2抜粋) を示します。

  • ベクトルの次元数は200くらいで頭打ちになる (下表a)
  • 構文類推サブタスク (Syntactic) では、単語の左側のみを文脈単語とするAsymmetricな方法の方が精度は高かった
    • またウィンドウサイズを広げすぎると、精度が落ちるという傾向も見られる
    • 構文は単語の順序と強く依存している、という直感と一致する結果と言える
  • 意味類推サブタスク (Semantic) では、ウィンドウサイズを広げれば、精度が上がり続ける傾向が見られる
    • 意味的に関連する単語は、前後に広く分散しているため

f:id:ohke:20181102180325p:plain

コーパスのサイズ

サイズ (トークン数) が異なる4つのコーパスで、単語類推タスクを行ったときの結果が下表です (Figure 3抜粋) 。

  • コーパスサイズが大きくなれば、構文類推サブタスクの精度はコーパスが大きくなるほど良くなり続ける傾向
  • 意味類推サブタスクの精度は、コーパスのサイズと単純に比例していない (Wiki2014よりもGigaword5の方が精度は低い)
    • 意味類推サブタスクは、先の例のように地域 (市や国) を使ったテストが多く、Wikipediaの方がこのテストセットには適していた
    • Gigawordは更新が止まったコーパスなので、古い・誤ったデータによって結果が悪くなった

f:id:ohke:20181102182317p:plain

学習速度

学習も速く、類推タスクにおいて、同じ学習時間でCBOW・Skip-Gramよりも高い精度をマークしてます (Figure 4抜粋) 。

  • CBOWはnegative sample数が10を超えると精度を落としていく
    • negative sampleで近似に使っている分布が、実際と離れている可能性がある

f:id:ohke:20181102183827p:plain

まとめ

GloVeを実際に利用するにあたって、検討しないといけなさそうな点を最後にまとめておきます。

  • コーパスが精度に大きな影響を与えるので、自分の適用しようとしているタスクに適しているかどうかは確かめる必要がある
    • こういう時にどうやって適切かどうかを可視化すべきなのか?がわかっていない
  • 意味的な関連性が重要なら、ウィンドウサイズは大きめに設定する (順序は気にしなくて良い)
  • ベクトルサイズは学習時間とのトレードオフだが、長めに設定する