直感 Deep Learning: 5章メモ(単語分散表現)(その1)

以下の本を読みます。

直感 Deep Learning ―Python×Kerasでアイデアを形にするレシピ直感 Deep Learning ―Python×Kerasでアイデアを形にするレシピ
Antonio Gulli Sujit Pal 大串 正矢

オライリージャパン 2018-08-11
売り上げランキング : 1992

Amazonで詳しく見る
by G-Tools
キャラクターの原作とは関係ありません。本読みメモですがよく脱線します。誤りがありましたらご指摘いただけますと幸いです。
次回:まだ
f:id:cookie-box:20180305231302p:plain:w60

ジュン、これプロデューサーが買ってきた本なんだけど、5章を読むの手伝ってくれない?

f:id:cookie-box:20180305232608p:plain:w60

「直感 Deep Learning」? プロデューサーさんは深層学習の本なんてもう何冊も持ってるでしょう? しかもなんで5章?

f:id:cookie-box:20180305231302p:plain:w60

これ先月出た本で、評判がいいから買ったらしいんだけど、5章以外はもう知ってる話も結構ある感じだったから、まず5章から読みたいんだって。プロデューサーは自然言語処理の勉強したことないからって。

f:id:cookie-box:20180305232608p:plain:w60

じゃあ自然言語処理の本買えばいいだろ。

f:id:cookie-box:20180305231302p:plain:w60

それで、5章(137ページ~)の「単語分散表現」なんだけど、このタイトルからもう割と意味わかんないんだけど、2段落目まで読むと「単語分散表現」っていうのは「テキスト中の単語を数値ベクトルに変換する方法のひとつ」らしいんだ。でも分散表現って何かの説明がないのに「最も基本的な分散表現の手法である」って one-hot エンコーディングが引き合いに出てきて、one-hot エンコーディングには問題点があってとかなっててよくわかんない! いまの目的は何なの!?

f:id:cookie-box:20180305232608p:plain:w60

…ハヤトは、one-hot エンコーディングは理解しているんですか?

f:id:cookie-box:20180305231302p:plain:w60

それはこの本の10ページに書いてあって、6行しかないから読むのすぐだったよ。10個の手書き数字をそれぞれ以下のように表現するのが one-hot エンコーディングなんだろ?
  x手書き数字の"0" = (1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  x手書き数字の"1" = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
  x手書き数字の"2" = (0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
  \cdots
でも、そもそもなんで one-hot エンコーディングするんだろ? 「どの数字か」って情報はせっかく1次元だったのになんで10次元にしちゃったのって感じなんだけど。

f:id:cookie-box:20180305232608p:plain:w60

常に正解が確実にわかるのであれば確かに「どの数字か」という情報は1次元ですね。0~9のいずれかの整数などで表現できます。しかし今は正解に絶対の自信があるわけではありません。例えば数字の1にも数字の7にも見える字を書く人はたまにいますね。1らしいが7らしくもある。そんなときに出力が1次元だったらどうするんです? 1と7の間を取って4を返すわけにもいかないでしょう? 出力が10次元あれば、2番目と8番目の要素を 0.5 にすることでこの状況が表現できます。このように出力を柔軟に10次元とするなら、目指すべき正解も10次元にしておくべきですね。

f:id:cookie-box:20180305231302p:plain:w60

じゃあ、one-hot エンコーディングは、絶対の自信がないときの出力が目指すべき正解になるような表現ってこと…? そういうときに用いるのが分散表現なの?

f:id:cookie-box:20180305232608p:plain:w60

いえ、分散表現の正確な語義は知りませんが、少なくとも狭義には違うと思います。

f:id:cookie-box:20180305231302p:plain:w60

違うの!?

f:id:cookie-box:20180305232608p:plain:w60

おそらく137ページ3段落目の「最も基本的な分散表現」の「分散表現」は「データを数値ベクトルとして表現すること」程度の意味合いと思いますが、一般的に分散表現(distributed representation)といったとき、 局所表現(local representation)と対になる概念としてそういわれていることが多いようにみえます。one-hot エンコーディングはむしろ局所表現ですから、分散表現ではないと思います。以下などを参照させていただきました。

しかし、分散表現の英語 distributed representation は「分布表現」とも読めます。デルタ関数も特殊な確率分布だというような気持ちなら、局所表現も分散表現の特殊なケースといえるのかもしれません。であれば、one-hot エンコーディングも分散表現ですが。

f:id:cookie-box:20180305231302p:plain:w60

ごめんよくわかんない。

f:id:cookie-box:20180305232608p:plain:w60

そうですね、例えば…ハヤトは「ハヤトである」という特徴をもっていますね?

f:id:cookie-box:20180305231302p:plain:w60

え? いやまあ俺は俺だけど…特徴っていうかトートロジーだなそれは。

f:id:cookie-box:20180305232608p:plain:w60

はい、トートロジーです。何であれ、僕たち軽音部5人をそのように特徴付けるなら、僕たちはそれぞれ以下のような5次元の特徴ベクトルで表現できます。
  x隼人 = (1, 0, 0, 0, 0)
  x = (0, 1, 0, 0, 0)
  x夏来 = (0, 0, 1, 0, 0)
  x四季 = (0, 0, 0, 1, 0)
  x春名 = (0, 0, 0, 0, 1)

f:id:cookie-box:20180305231302p:plain:w60

できるって言われても…これ、one-hot エンコーディング

f:id:cookie-box:20180305232608p:plain:w60

ええ。そして、この one-hot エンコーディングは「分散」していないですね。

f:id:cookie-box:20180305231302p:plain:w60

何が?

f:id:cookie-box:20180305232608p:plain:w60

例えば、僕たち5人を先のような5次元ベクトルで表現して、「任意の2人を入力してその2人の仲のよさを出力するニューラルネットワーク」を学習するとします。

f:id:cookie-box:20180305231302p:plain:w60

なんでだよ、俺たちはみんな仲いいだろ! 不仲がいるみたいな感じやめろ! ちゃんとバンド内で仲良くして!?

f:id:cookie-box:20180305232608p:plain:w60

物の喩えです。しかし、先の表現では意味のある学習などできません。いえ、訓練データを暗記することはできるでしょう。しかし、訓練データを暗記することしかできません。なぜなら、ニューラルネットワークはハヤトについて「ハヤトである」以上の情報を知り得ませんので。そして当然、未知の新しいメンバーが入力された場合にも対応できません。そこで、表現を変えてみます。
  x隼人 = (1, 1, 1)
  x = (0, 0, 1)
  x夏来 = (1, 0, 1)
  x四季 = (0, 1, 1)
  x春名 = (0, 0, 0)

f:id:cookie-box:20180305231302p:plain:w60

何これ、3次元になった?

f:id:cookie-box:20180305232608p:plain:w60

ベクトルの1番目の要素は「担当が弦楽器である」、2番目の要素は「上にきょうだいがいる」、3番目の要素は「留年せず進級している」としてみました。

f:id:cookie-box:20180305231302p:plain:w60

3番目の要素が個人を特定しにかかってるな。

f:id:cookie-box:20180305232608p:plain:w60

こちらが(おそらく狭義の)分散表現です。ハヤトの特徴を「ハヤトである」から「弦楽器担当で、上にきょうだいがいて、留年していない」に「分散」したんです。こうすると、ニューラルネットワークは単なる暗記以上の学習をできる見込みがあります。例えば、「弦楽器担当の人と、上にきょうだいがいない人は特に仲がいいようだ」という情報が抽出できるかもしれません。そして、新メンバーにも対応できる可能性があります。このエンコーディングは未知のメンバーにも適用できますから。もちろん、これは例示的なヒューリスティックエンコーディングなので、実際の分散表現は未知データに対応できるとは限りません。というか、おそらく標準的な単語分散表現では対応できないですね。例えばこの章で紹介されている word2vec や GloVe では、膨大な数の文章(学習用コーパス)を与えて、そこに含まれる膨大な単語を教師なしで所与の次元数にエンコーディングします。なので、得られた表現の各次元にヒューリスティックな意味はありませんから、訓練に用いた文章に含まれていなかった単語のベクトル表現を知ることはできませんね。

f:id:cookie-box:20180305231302p:plain:w60

…なあジュン、この3次元の表現だと、俺とハルナは真逆ってこと?

f:id:cookie-box:20180305232608p:plain:w60

「弦楽器かどうか」「上にきょうだいがいるか」「留年していないか」のみが意味をもつ世界では最も遠くに配置されるというだけです。モデルの学習の上でこれらのみが意味をもつのでは足りないなら、4番目の要素、5番目の要素…をベクトルに追加するべきですね。もっとも、先にも言及したように、少なくともテキスト中の単語の分散表現では、ベクトルの要素の意味を人間的に与えて単語間の距離を決めるのではなく、逆に単語間の距離の手がかりの方を与えて「単語間の距離を適切に表すように空間内に単語を配置するやり方を何らかのアルゴリズムで学習する」と言った方が正しいです。また、いまの例示ではベクトルの各要素が  \{0,1\} のどちらかの値しかとっていませんが、もちろん実際には(計算機の範囲で)自由に実数値をとって構いません。

f:id:cookie-box:20180305231302p:plain:w60

「単語間の距離」って?

f:id:cookie-box:20180305232608p:plain:w60

どんなコーパスを用いて、どんな関係をもつ単語どうしが近いと定義するかによりますが、例えば「ギター」と「ベース」という単語は「近い」んじゃないか、と考えられます。同じ楽器ですし、「ギター」と「カレー」よりは「ギター」と「ベース」の方が近そうでしょう?

f:id:cookie-box:20180305231302p:plain:w60

…でもさ、ハルナの中では「ドラム」と「ドーナツ」が近いかもしれないじゃん。どっちも好きな物?みたいな感じで。

f:id:cookie-box:20180305232608p:plain:w60

そうですね、「春名さんのこれまでの発言」のようなコーパスを使って単語分散表現を学習したら本当にそうなるかもしれません。それはそれでいいです。単語分散表現は用いたコーパスによりますから。

f:id:cookie-box:20180305231302p:plain:w60

ふーん…あ、あとさ、単語って同じ単語でも違う意味があったりするじゃん。例えば、「翼」っていったら、うちの事務所の翼さんかもしれないし、765プロの翼さんかもしれないし、普通に鳥とかの翼の意味かもしれないし。

f:id:cookie-box:20180305232608p:plain:w60

いきなり単語分散表現の弱点を突くのはやめてください。

f:id:cookie-box:20180305231302p:plain:w60

ごめん…。

f:id:cookie-box:20180305232608p:plain:w60

整理しますね。

  • one-hot エンコーディング データを数値ベクトルにする手法であって、現れるデータが N 種類なら one-hot な N 次元のベクトルにするだけというもの。
    • なので、エンコーディングする対象のデータ集合さえあればベクトル表現が得られる。
    • ベクトルの各次元の意味は、「i 種類目のデータである」でしかない。
    • このエンコーディングをする目的は、多クラス分類問題においてモデルが出力すべきお手本をつくるためといった向きが大きい(はず)。
  • 分散表現: データを数値ベクトルにする手法であって、データ間の距離(類似性)を考慮した上でベクトル化する=空間内に配置するもの(具体的なアルゴリズムは色々ある)。
    • なので、エンコーディングする対象のデータ集合だけでなく、データ間の距離を示唆する情報も必要である(現実の場面では、エンコーディングする対象の単語たちが文章セットとして与えられるのでこれが達成される=例えば、文章の中で5単語以内の距離に出てくる頻度が多い単語どうしは距離が近いと定義するなど)。
    • ふつうベクトルの各次元にはヒューリスティックな意味はない(アルゴリズムによる)。
    • このエンコーディングをする目的は、データ(多くの場合、単語)を「その意味上の距離を保ったまま」モデルが扱える数値ベクトルにするためである(はず)。そうして得られた数値ベクトル表現は機械学習モデルの入力にも出力にもなりうるが、入力になることが多いと思われる。例えば以下のような使用シナリオが考えられる。
      • 文章セット全体から、登場する各単語を適当な分散表現手法で数値ベクトルにする。
      • 「各文章(=数値ベクトル列)→ その文章がポジティブかネガティブか」のようなRNNを教師あり学習する。
僕たちが機械学習で扱うデータの中で、「画像」や「音声」などは(何らかのセンサーを通して)直ちに実数の多次元配列です。しかし文章は違います。もちろん各文字に文字コードなどはあるでしょうが、文字コードの羅列は単語の意味を反映しません。それを無視した学習は(できなくはないですが)有効ではないでしょう。単語の意味を考慮した数値表現を得ることが必要です。それがいまの目的ですね。

f:id:cookie-box:20180305231302p:plain:w60

目的はわかったよ。それで、137ページの下の方に、単語分散表現以前の単語のベクトル化手法みたいなのが出てきて、「これらの手法は文章中の単語に着目しており、単語それ自体の意味を捉えようとする単語分散表現とは異なる手法になります」「単語分散表現は、文章を前提としそれを文脈とする従来の(中略)手法とは異なり、単語自体を文脈として使用します」ってあるんだけど、この辺も抽象的でよくわかんなくない? 単語を文脈として使用って何?

f:id:cookie-box:20180305232608p:plain:w60

本のタイトルが「直感」だから深く考えなくても。きちんと捉えたいなら、列挙されている単語分散表現以前の手法を追うべきでしょう。リンクも書いてありますし、調べてみましょう。

  • TF-IDF: 各単語を「全文書中でその単語が頻度ベースで占める割合」と「全文書中でその単語が出てくる文書の割合の逆数の対数」の積であるスカラーで表現する手法のようですね。
  • 潜在意味解析(LSA): (i,j) 成分が単語 i の文書 j における出現頻度であるような行列を特異値分解して、特異値が大きい方から k 個までに対応する左特異ベクトルと右特異ベクトルだけ残すという操作をして先の行列のランクを  k に落として、i 番目の単語を「k 本の左特異ベクトルの i 番目の要素をつなげたベクトル」、j 番目の文書を「k 本の右特異ベクトルの j 番目の要素をつなげたベクトル」にエンコードするようです。もっとも、そのような数値ベクトル表現を得て、単語や文書をクラスタリングすることが目的のようですが。
  • トピックモデル: 「トピック」という隠れ変数を考えるようですね。各文書はいくつかのトピックの重ね合わせを生成して、各トピックは単語分布を生成すると仮定して、「各文書のトピックの混合比」と「各トピックの単語分布」を推定するようです。なので、各単語について得られる数値表現は「各トピックでどれだけの出現確率をもつか」のようなベクトルになりますね。トピックを軸に各単語や各文書を解析するようです。具体的なアルゴリズムは色々ありうるようですが。Wikipedia にあまり具体的なことが書いていなかったので2つ目のページも参考にしました。LSA において、各右特異ベクトルが確率的に生成された各文書がそのトピックをどれだけ強くもっているかのベクトル、各特異値がトピック、各左特異ベクトルが確率的に生成されたトピック毎の単語分布、になるようにやり直そうとするとトピックモデルになりますね。Wikipedia のアニメーションは、これはトピックを見出す1つの方法といった感じなのですかね。
ただこれらが単語分散表現に比して何を欠いているのかというのは結局単語分散表現の方も追わないとわかりませんね。ただ word2vec と GloVe を流し読みした範囲ですぐわかるのは、上の従来の手法は「この単語とこの単語は文書内で隣り合って出現することが多い」という情報を使っていませんね(LSA やトピックモデルでは「同じ文書に現れやすい」というレベルでは考慮していますが)。…言い換えに近くなってしまいますが、137~138ページの「単語それ自体の意味を捉える」「単語自体を文脈として使用する」とは、「コーパス内での出現頻度以上の単語間の関係を織り込んだ単語空間を構成する」ということと考えます。TF-IDF は単語の数値表現ですが出現頻度に寄りすぎですし、LSAとトピックモデルは特異値やトピックを通した相関は表現しているんですが、結局各文書における出現頻度に基づくクラスタリングのようなものなので、文書の構造などには立ち入れないと思います。

f:id:cookie-box:20180305231302p:plain:w60

ジュンごめん、あのさ、まだ5章の序文なんだけど…。

f:id:cookie-box:20180305232608p:plain:w60

いいじゃないですか、気付きがあったなら全部回収しておけば。それに、5.1節はもういいでしょう。単語間の関係を保った数値ベクトル表現がほしいって話だし。5.2節も word2vec の具体的なアルゴリズムの解説なので、適当なコーパスで実際にやってみればいいですよ。その後も GloVe の紹介と実用場面での分散表現の得方で、1つ目は完全に自前で分散表現を学習する、2つ目は学習済みの重みで初期化した上で学習する(ファインチューニング)、3つ目は学習済みの重みをそのまま利用するやり方ですね。

f:id:cookie-box:20180305231302p:plain:w60

かなり内容あるじゃん! あと、word2vec を試してみるのに使えるデータってある? 本では1つの文章しか出てきてないっぽいし。

f:id:cookie-box:20180305232608p:plain:w60

ハヤトのソロ曲の歌詞とかでいいじゃないですか。

f:id:cookie-box:20180305231302p:plain:w60

なんで!?

(次回があれば)つづく