.. _sec_glove: グローバルベクトル(GloVe)による単語埋め込み ============================================= コンテキストウィンドウ内での単語同士の共起は、豊かな意味情報を含んでいる可能性がある。たとえば、大規模コーパスでは、単語 “solid” は “steam” よりも “ice” と共起しやすい一方で、単語 “gas” は “ice” よりも “steam” とより頻繁に共起するだろう。さらに、このような共起の大域的なコーパス統計は事前に計算できるため、より効率的な学習につながる。単語埋め込みのためにコーパス全体の統計情報を活用するため、まず :numref:`subsec_skip-gram` のスキップグラムモデルを、共起回数のような大域的なコーパス統計を用いて解釈し直そう。 .. _subsec_skipgram-global: 大域的コーパス統計を用いたスキップグラム ---------------------------------------- スキップグラムモデルにおいて、単語 :math:`w_i` が与えられたときの単語 :math:`w_j` の条件付き確率 :math:`P(w_j\mid w_i)` を :math:`q_{ij}` と表すと、次式を得る。 .. math:: q_{ij}=\frac{\exp(\mathbf{u}_j^\top \mathbf{v}_i)}{ \sum_{k \in \mathcal{V}} \exp(\mathbf{u}_k^\top \mathbf{v}_i)}, ここで、任意のインデックス :math:`i` に対して、ベクトル :math:`\mathbf{v}_i` と :math:`\mathbf{u}_i` はそれぞれ中心語および文脈語として単語 :math:`w_i` を表す。また、\ :math:`\mathcal{V} = \{0, 1, \ldots, |\mathcal{V}|-1\}` は語彙のインデックス集合である。 コーパス中で複数回出現しうる単語 :math:`w_i` を考える。コーパス全体で、\ :math:`w_i` が中心語として取られるすべてのコンテキストウィンドウに含まれる文脈語は、単語インデックスの *多重集合* :math:`\mathcal{C}_i` を形成する。多重集合とは、\ *同じ要素が複数回現れることを許す* 集合である。各要素について、その出現回数を *重複度* と呼ぶ。例として、単語 :math:`w_i` がコーパス中で2回出現し、その2つのコンテキストウィンドウで :math:`w_i` を中心語とする文脈語のインデックスがそれぞれ :math:`k, j, m, k` と :math:`k, l, k, j` であったとする。このとき、多重集合 :math:`\mathcal{C}_i = \{j, j, k, k, k, k, l, m\}` となり、要素 :math:`j, k, l, m` の重複度はそれぞれ 2, 4, 1, 1 である。 ここで、多重集合 :math:`\mathcal{C}_i` における要素 :math:`j` の重複度を :math:`x_{ij}` と表す。これは、コーパス全体において、同じコンテキストウィンドウ内で単語 :math:`w_j`\ (文脈語)と単語 :math:`w_i`\ (中心語)が共起する回数である。このような大域的なコーパス統計を用いると、スキップグラムモデルの損失関数は次式と等価になる。 .. math:: -\sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} x_{ij} \log\,q_{ij}. :label: eq_skipgram-x_ij さらに、\ :math:`x_i` を、\ :math:`w_i` が中心語として現れるコンテキストウィンドウ内のすべての文脈語の数、すなわち :math:`|\mathcal{C}_i|` と等しい量として定義する。中心語 :math:`w_i` が与えられたときに文脈語 :math:`w_j` を生成する条件付き確率を :math:`x_{ij}/x_i` として :math:`p_{ij}` とおくと、:eq:`eq_skipgram-x_ij` は次のように書き換えられる。 .. math:: -\sum_{i\in\mathcal{V}} x_i \sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij}. :label: eq_skipgram-p_ij :eq:`eq_skipgram-p_ij` では、\ :math:`-\sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij}` が、大域的コーパス統計から得られる条件付き分布 :math:`p_{ij}` と、モデル予測の条件付き分布 :math:`q_{ij}` のクロスエントロピーを計算している。さらにこの損失は、上で説明したように :math:`x_i` によって重み付けされている。:eq:`eq_skipgram-p_ij` の損失関数を最小化すると、予測された条件付き分布が大域的コーパス統計から得られる条件付き分布に近づく。 確率分布間の距離を測るために一般的に用いられるとはいえ、クロスエントロピー損失関数はここでは良い選択ではないかもしれない。第一に、 :numref:`sec_approx_train` で述べたように、\ :math:`q_{ij}` を適切に正規化するためのコストは語彙全体にわたる和を必要とし、計算量が大きくなりうる。第二に、大規模コーパスから得られる多数の稀な事象が、クロスエントロピー損失では過度に大きな重みを与えられてしまうことが多い。 GloVeモデル ----------- この観点から、\ *GloVe* モデルは、二乗損失に基づいてスキップグラムモデルに3つの変更を加える :cite:`Pennington.Socher.Manning.2014`: 1. 確率分布ではない変数 :math:`p'_{ij}=x_{ij}` と :math:`q'_{ij}=\exp(\mathbf{u}_j^\top \mathbf{v}_i)` を用い、両者の対数を取ることで、二乗損失項は :math:`\left(\log\,p'_{ij} - \log\,q'_{ij}\right)^2 = \left(\mathbf{u}_j^\top \mathbf{v}_i - \log\,x_{ij}\right)^2` となる。 2. 各単語 :math:`w_i` に対して2つのスカラーのモデルパラメータを追加する。すなわち、中心語バイアス :math:`b_i` と文脈語バイアス :math:`c_i` である。 3. 各損失項の重みを重み関数 :math:`h(x_{ij})` に置き換える。ここで :math:`h(x)` は区間 :math:`[0, 1]` で増加関数である。 これらをまとめると、GloVe の学習は次の損失関数を最小化することに等しい。 .. math:: \sum_{i\in\mathcal{V}} \sum_{j\in\mathcal{V}} h(x_{ij}) \left(\mathbf{u}_j^\top \mathbf{v}_i + b_i + c_j - \log\,x_{ij}\right)^2. :label: eq_glove-loss 重み関数としては、\ :math:`x < c`\ (たとえば :math:`c = 100`\ )のとき :math:`h(x) = (x/c) ^\alpha`\ (たとえば :math:`\alpha = 0.75`\ )、それ以外では :math:`h(x) = 1` とする選択が提案されている。この場合、\ :math:`h(0)=0` なので、\ :math:`x_{ij}=0` に対する二乗損失項は計算効率のため省略できる。たとえば、ミニバッチ確率的勾配降下法で学習する場合、各反復で *非ゼロ* の :math:`x_{ij}` をランダムにミニバッチとしてサンプリングし、勾配を計算してモデルパラメータを更新する。これらの非ゼロの :math:`x_{ij}` は事前計算された大域的コーパス統計であるため、このモデルは *Global Vectors* の略で GloVe と呼ばれる。 強調しておくべきなのは、単語 :math:`w_i` が単語 :math:`w_j` のコンテキストウィンドウに現れるなら、その逆も成り立つということである。したがって、\ :math:`x_{ij}=x_{ji}` である。非対称な条件付き確率 :math:`p_{ij}` に適合する word2vec とは異なり、GloVe は対称な :math:`\log \, x_{ij}` に適合する。したがって、GloVe モデルでは、任意の単語の中心語ベクトルと文脈語ベクトルは数学的に等価である。しかし実際には、初期化値が異なるため、学習後も同じ単語がこの2つのベクトルで異なる値を持つことがある。GloVe では、それらを出力ベクトルとして和を取る。 共起確率の比から GloVe を解釈する --------------------------------- GloVe モデルは別の観点からも解釈できる。 :numref:`subsec_skipgram-global` と同じ記法を用いて、\ :math:`p_{ij} \stackrel{\textrm{def}}{=} P(w_j \mid w_i)` を、コーパス中で単語 :math:`w_i` を中心語として与えたときに文脈語 :math:`w_j` を生成する条件付き確率とする。 :numref:`tab_glove` には、単語 “ice” と “steam” に対するいくつかの共起確率と、その比が大規模コーパスの統計に基づいて示されている。 :大規模コーパスから得られた単語同士の共起確率とその比(:cite:t:`Pennington.Socher.Manning.2014` の表1を改変) .. table:: label:``tab_glove`` ==================================== ======== ======== ====== ======== :math:`w_k`\ = solid gas water fashion ==================================== ======== ======== ====== ======== :math:`p_1=P(w_k\mid \textrm{ice})` 0.00019 0.000066 0.003 0.000017 :math:`p_2=P(w_k\mid\textrm{steam})` 0.000022 0.00078 0.0022 0.000018 :math:`p_1/p_2` 8.9 0.085 1.36 0.96 ==================================== ======== ======== ====== ======== :numref:`tab_glove` から次のことが観察できる。 - “ice” に関連し “steam” には関連しない単語 :math:`w_k`\ 、たとえば :math:`w_k=\textrm{solid}` については、8.9 のような大きな共起確率比が期待される。 - “steam” に関連し “ice” には関連しない単語 :math:`w_k`\ 、たとえば :math:`w_k=\textrm{gas}` については、0.085 のような小さな共起確率比が期待される。 - “ice” と “steam” の両方に関連する単語 :math:`w_k`\ 、たとえば :math:`w_k=\textrm{water}` については、1.36 のように1に近い共起確率比が期待される。 - “ice” と “steam” のどちらにも関連しない単語 :math:`w_k`\ 、たとえば :math:`w_k=\textrm{fashion}` については、0.96 のように1に近い共起確率比が期待される。 共起確率の比は、単語間の関係を直感的に表現できることがわかる。したがって、この比に適合するように、3つの単語ベクトルの関数を設計できる。中心語が :math:`w_i`\ 、文脈語が :math:`w_j` と :math:`w_k` であるときの共起確率比 :math:`{p_{ij}}/{p_{ik}}` に対して、何らかの関数 :math:`f` を用いてこの比に適合させたい。 .. math:: f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) \approx \frac{p_{ij}}{p_{ik}}. :label: eq_glove-f :math:`f` の設計には多くの可能性があるが、以下では妥当な選択だけを取り上げる。共起確率の比はスカラーであるため、\ :math:`f` もスカラー関数である必要がある。たとえば :math:`f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) = f\left((\mathbf{u}_j - \mathbf{u}_k)^\top {\mathbf{v}}_i\right)` のようにである。:eq:`eq_glove-f` で単語インデックス :math:`j` と :math:`k` を入れ替えると、\ :math:`f(x)f(-x)=1` が成り立たなければならない。したがって、1つの可能性は :math:`f(x)=\exp(x)` であり、すなわち .. math:: f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) = \frac{\exp\left(\mathbf{u}_j^\top {\mathbf{v}}_i\right)}{\exp\left(\mathbf{u}_k^\top {\mathbf{v}}_i\right)} \approx \frac{p_{ij}}{p_{ik}}. ここで、\ :math:`\exp\left(\mathbf{u}_j^\top {\mathbf{v}}_i\right) \approx \alpha p_{ij}` とおく。ここで :math:`\alpha` は定数である。\ :math:`p_{ij}=x_{ij}/x_i` なので、両辺の対数を取ると :math:`\mathbf{u}_j^\top {\mathbf{v}}_i \approx \log\,\alpha + \log\,x_{ij} - \log\,x_i` を得る。\ :math:`- \log\, \alpha + \log\, x_i` を適合させるために、中心語バイアス :math:`b_i` や文脈語バイアス :math:`c_j` のような追加のバイアス項を用いることができる。 .. math:: \mathbf{u}_j^\top \mathbf{v}_i + b_i + c_j \approx \log\, x_{ij}. :label: eq_glove-square :eq:`eq_glove-square` の二乗誤差を重み付きで測ると、:eq:`eq_glove-loss` の GloVe 損失関数が得られる。 まとめ ------ - スキップグラムモデルは、単語同士の共起回数のような大域的コーパス統計を用いて解釈できる。 - クロスエントロピー損失は、特に大規模コーパスでは、2つの確率分布の差を測るのに適した選択ではないかもしれない。GloVe は、事前計算された大域的コーパス統計に適合するように二乗損失を用いる。 - GloVe では、任意の単語について中心語ベクトルと文脈語ベクトルは数学的に等価である。 - GloVe は、単語同士の共起確率の比から解釈できる。 演習 ---- 1. 単語 :math:`w_i` と :math:`w_j` が同じコンテキストウィンドウ内で共起する場合、テキスト系列におけるそれらの距離をどのように用いて、条件付き確率 :math:`p_{ij}` を計算する方法を再設計できるか。ヒント: GloVe 論文 :cite:`Pennington.Socher.Manning.2014` の第4.2節を参照せよ。 2. 任意の単語について、その中心語バイアスと文脈語バイアスは GloVe において数学的に等価か。なぜか?