「ゼロから作るDeepLearning2」を読了しましたので、要点や自分なりの解釈をまとめておきます。
まとめていたら長編になってしまったため(それってまとまってなくね?)、前編と後編に分割することにしました。
自然言語と単語の分散表現
コンピュータに単語の意味を理解させる表現方法として、大きく分けて下記3つが考えられる。
シソーラスによる手法
カウントベースの手法
推論ベースの手法(word2vec)
簡単にそれぞれについて解説する。
シソーラスによる手法
基本的には類語辞書であり、「同じ意味の単語」や「意味の似た単語」が同じグループに分類される。
シソーラスを用いれば、car
の同意語にはautomobile
やmotorcar
などが存在することが分かる。
これは全て、人の手作業によって単語を関連づけている。
もっとも有名なシソーラスにWordNetというものがある。 WordNetを使用することで、類義語を取得したり、単語ネットワークを利用することができる。
しかし、シソーラスには下記のような問題点もある。
時代の変化に対応するのが困難
新しい単語などについていけない人の作業コストが高い
単語の追加などが発生する単語の細かなニュアンスを表現できない
「ヴィンテージ」と「レトロ」という単語ニュアンスを表現できない
カウントベースの手法
カウントベースの手法では コーパス(corpus) を利用する。 コーパスとは、大量のテキストデータのことを表す。 例えば、WikipediaやGoogle Newsなどのテキストデータが挙げられる。
ここで重要となる考え方に分散表現と分布仮説がある。
分散表現と分布仮説
「単語の意味」を的確に捉えたベクトル表現を、自然言語処理の分野では分散表現と呼ぶ。 単語をベクトルで表す研究は数多く行われてきたが、重要な手法のほとんどが、ある一つのアイデアに基づいている。 それは 「単語の意味は、周囲の単語によって形成される」 というものである。
これを分布仮説と呼ぶ。
例えば。you say goodbye and i say hello .
という文字列には語彙が全部で7つある(ピリオドを含めて)。
それぞれの単語について、コンテキスト(その単語の周囲の単語)に含まれる単語の頻度を数えると、
you
という単語が[0, 1, 0, 0, 0, 0, 0]というベクトルで表現できることが分かる。(you
の周囲の単語はsay
のみであり、say
にのみコンテキストの目印として共起した回数の1
を設定している。)
- | you | say | goodbye | and | i | hello | . |
---|---|---|---|---|---|---|---|
you | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
また、say
については、[1, 0, 1, 0, 1, 1, 0]というベクトルで表現することができる。
- | you | say | goodbye | and | i | hello | . |
---|---|---|---|---|---|---|---|
say | 1 | 0 | 1 | 0 | 1 | 1 | 0 |
上記のように、各単語毎に行列として表現したものを 共起行列 という。
単語をベクトルで表すことができたら、ベクトル間の類似度で各単語の類似性を測ることができる。
この類似度の計算にはコサイン類似度を使用することができる。
カウントベース手法の問題点
高頻度単語問題
ここでは、2つの単語が共起した回数を表現していましたが、これは高頻度単語に目を向けるとあまりよくないことがわかる。
例えば、あるコーパスにおいてthe
とcar
の共起を考えてみると、〜〜 the car 〜〜
というフレーズは多くみられる一方で、〜〜 drive car 〜〜
というフレーズは、前者に比べて少ない可能性がある。
car
とdrive
という単語には強い関連性があるにも関わらず、the
とdrive
を比較したときにthe
の方がcar
との関連性が高いと認識されてしまう可能性がある。
この問題を解決するために、生の相互情報量(PPMI:Positive PMI) が使われる。
PMI行列に関しては下記記事が詳しい。
共起行列をPPMI行列に変換することで、より良い指標の行列(単語ベクトル)が作成できる。
大規模コーパス問題
PPMI行列に変換し、良い単語ベクトルを取得できたところで、例えば語彙数を100万とした大規模なコーパスを扱う場合などには、カウントベース手法では100万×100万の巨大な行列を生成する必要がある。
また、このPPMI行列は、多くの要素が0で構成されているため(PPMI行列へ変換する前の行列自体が、[0, 1, 0, 0, 0, 0, 0]というものだったため)、ベクトルのほとんどの要素が重要ではないことを意味している。
このように、ノイズに弱く頑健性に乏しいという欠点がある場合には、ベクトルの次元削減などが有効である。
ベクトルの次元削減とは、重要な情報をできるだけ残してベクトルの次元数を削減することである。 直感的なイメージだと、身長と体重の2次元データを、体格という1つの次元とし、身長と体重という次元は削除する、といったとことだろうか。(データの分布をみて重要な軸を見つける)
次元削減の行う方法は主成分分析や特異値分解などいくつかある。
しかし、前述したような巨大な行列に対して、次元削減を行うことは現実的ではない。(計算リソース、計算時間の観点から)
カウントベースの手法では、周囲の単語の頻度によって単語ベクトルを表現してきた。具体的には、単語の共起行列を作成しその行列に対して次元削減を行うことで、密なベクトル(単語の分散表現)を獲得した。
このカウントベース手法はコーパス全体の統計データ(共起行列やPPMI行列)を利用して、1回の処理(次元削減など)で単語の分散表現を取得してきたが、これから説明する推論ベース手法では、例えばニューラルネットワークは一度に少量(ミニバッチ)の学習サンプルを見ながら、重みを繰り返し更新していく。 このように、コーパス全体の統計データから分散表現を取得するのではなく、推論ベースでミニバッチごとに学習するほうが効率的である。
推論ベースの手法(word2vec)
推論ベース手法では、「推論」することが主な作業である。
you 【?】 goodbye and I say hello .
の【?】にどのような単語が出現するのか推測するのが、推論ベースの手法である。
推論ベースの手法では単語をone-hot表現に変換して、そのベクトルを入力としてニューラルネットワークで処理を行う。 ニューラルネットワークでは、コンテキスト情報を入力として受け取り、出現しうるであろう各単語の出現する確率を出力する。
その仕組みの中で正しい推測ができるように、コーパスを使ってモデルの学習を行う。そして、その学習の結果として単語の分散表現を得られるというのが推論ベースの手法となる。(推測するという目標があり、その副産物として単語の分散表現を取得できる)
この推論ベースの手法(word2vec)に関して、詳しくみていく。
word2vec
word2vecは推論ベースの手法であり、シンプルな2層のニューラルネットワークで構成される。
word2vecで使用されるニューラルネットワークのモデルにCBOWとskip-gramというものがある。
CBOWモデルは、コンテキストからターゲットとなる単語の確率を出力する予想するモデルであり、skip-gramモデルはターゲットから周囲の単語(コンテキスト)を推測するモデルである。
CBOW(continuous bag-of-words)モデル
コンテキストからターゲットを推測することを目的としたニューラルネットワークの名称である。(「ターゲット」は中央の単語、「コンテキスト」はその周囲の単語)
このCBOWモデルで、できるだけ正確な推測ができるように訓練することで、単語の分散表現を取得することができる。
下記に、CBOWモデルの概略を図示する。
入力層から中間層への変換は、全結合層(重みW
)によって行われる。この重みWこそがそれぞれの単語の分散表現となる。
また、中間層にあるニューロンは、各入力層の全結合による変化後の値が「平均」されたものになる。
重みと分散表現
word2vecで使用されるネットワークには2つの重みがある。
上図でも記載したように、入力側の全結合層の重み(W_in)と出力側の全結合層の重み(W_out)の2種類である。
この重みには、どちらも各単語の分散表現に対応した値(ベクトル)が格納されているが、最終的に利用する(取得する)単語の分散表現は、入力側の重み(W_in)を利用するのがポピュラーである。
skip-gramモデル
skip-gramは、CBOWで扱うコンテキストとターゲットを逆転させたモデルである。
下記に、skip-gramモデルの概略を図示する。
CBOWとskip-gramの比較
CBOWモデルとskip-gramモデルを比較した際、単語の分散表現の精度の点においては多くの場合skip-gramモデルの方がよい結果が得られることが多い。
とくに、コーパスが大規模になるにつれて、低頻出の単語や類推問題の性能の点において、skip-gramモデルの方が良い結果が得られる傾向にある。
学習速度の点では、CBOWモデルの方がskip-gramモデルよりも高速になる。これは、skip-gramモデルの場合はコンテキストの数だけ損失を求めるため、その計算コストが大きくなることに原因がある。
word2vecの高速化
高速化の手法として、
Embeddingレイヤの実装
Negative Sampling手法の導入
があげられる。
最後に
後編ではRNN、LSTMについてまとめようと思っています。