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

以下の本を読みます。

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

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

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

単語分散表現とは、単語間の関係が反映された単語の数値ベクトル表現を得ることでしたね。

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

今回は5.2節の word2vec からか。word2vec には CBOW と Skip-gram というアーキテクチャ?があって、前者では文脈語から中心語を予測して、後者では中心語から文脈語を予測する…あのさ、

  • word2vec 自体は何を指すの? 「CBOW と Skip-gram があります」じゃ説明になってなくない?
  • 文脈語と中心語って何?
  • なんか単語から単語を「予測する」って言ってるけどさ、いまやりたいのは単語を数値ベクトルにすることだよね? なんで予測始めちゃったの??

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

CBOW と Skip-gram の具体的な手順を追ってみれば自ずとわかるでしょう。本でも英語の童話の文を例に挙げられていますが、ここでは以下の文章で考えてみます。機関車トーマス (汽車のえほん 2) | ウィルバート・オードリー, レジナルド・ドールビー, 桑原 三郎, 清水 周裕 |本 | 通販 | Amazon の最初の文章ですね。

「タンク式機関車のトーマスは大きな駅ではたらいていました」

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

なんでトーマス!?

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

プロデューサーさんがはまっているので。上の日本語文を形態素解析すると以下のようになると思います。実際にやっていないので脳内 tokenizer ですが。 11個の単語がありますので、1~11のIDを付けておきます。

タンク式機関車12トーマス34大きな567はたらい89いまし1011

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

なんか1個目の単語から聞き慣れないんだけど。タンク式機関車って何?

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

タンク式というんだから水を貯めるタンクが専用の炭水車ではなく本体に積載されている機関車に決まってるでしょう。物語中では最重要キャラクターのトーマスとパーシーがこのタンク式なんです。

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

そっか…。

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

ここである単語とその周辺の数単語を中心語と文脈語とよぶことにします。例えば、「トーマス」に着目してこれを中心語として、ここから2単語以内にある単語を文脈語とするとします。

タンク式機関車12トーマス34大きな567はたらい89いまし1011
先に Skip-gram の方の手順から追いかけます。Skip-gram では中心語から文脈語を予測します。正確には、以下のようなモデルを学習します。
  • 「中心語:トーマス、文脈語:タンク式機関車」という入力 → OK(1)
  • 「中心語:トーマス、文脈語:駅」という入力 → NG(0)
「タンク式機関車」は「トーマス」から2単語以内にあるので OK だが、「駅」は「トーマス」から2単語以内にはないので NG ということです。予測器というより判定器といった方がしっくりきますね。結果的に予測はしているんですが。そして、この判定器は以下のようにつくることにします。
  1. 中心語を中心語用の Embedding 層で数値ベクトルにする。
  2. 文脈語を文脈語用の Embedding 層で数値ベクトルにする。
  3. 1. と 2. の内積をとる。
  4. 3. に出力の次元数が1の Dense 層をかぶせ、sigmoid で活性化して最終的な判定とする。
    言い換えるとこの層では、中心語と文脈語の内積という1次元の説明変数をつかって「本当に中心語と文脈語のペアでありうるか?」の分離境界をロジスティック回帰するんですね。

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

はいはい質問! Embedding 層って何? 説明がないよね?

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

調べると、例えば全11単語を5次元に埋め込むとしたら Embedding 層は11×5次元の行列であるようですね。何のことはない、各単語がどのような数値ベクトルになるかをそのまま重みとして保持する(ように学習する)層なんですね。まあそれで、中心語側の Embedding 層による数値ベクトル化が、今回得たい単語分散表現に他なりません。

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

あっ、そこを最終的につかうんだ! 予測したいわけじゃないのに予測してたのは、後から Embedding 層を取り出すためだったのか。…でもさ、そもそもなんでそんな予測しようって思ったんだ? なんか天から降ってきた感じしない?

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

そうですね…頭を真っ白にして、「目の前にあるコーパス内の全単語を、単語間の何らかの距離を反映するようにN次元空間に埋め込んでください」と言われたらどうすればいいか考えてみましょう。但し、そのコーパス以外に何の辞書も知識もないとします。その制約下である単語とある単語が近くにあるかどうかの基準は、「登場頻度が似ているか」「同じ文章内に登場しやすいか」「文章内で隣り合って登場しやすいか」「文章内で登場する位置が序盤か中盤か終盤かが似ているか」など色々考えられます。文章内での登場位置に踏み込んだルールであって最も基本的なのはやはり「文章内で隣り合って登場しやすいか」なのではないでしょうか。そしておそらく「隣同士」としてしまうと単語間が近いとみなす基準があまりに狭いので「M単語以内」の方がいいと思います。であれば、「ある単語とある単語がM単語以内に登場しやすいか」を考えることになります。Skip-gram で「中心語」と「文脈語」を別々に Embedding するのはおそらく単語間の距離が非対称だからでしょう。どの単語からみても近い単語というのはありそうですが、それで対称性をもつ距離を入れたらあらゆる単語が近くに集まってしまいそうですよね。…のように考えれば、Skip-gram 分類器を学習しようとするのは素朴な発想なのではないでしょうか。

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

長っ! じゃあ Skip-gram は無理がない発想なんだとして、もう1つの CBOW ってのはどうなの?

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

CBOW は Skip-gram とは逆に文脈語から中心語を予測するということですが、入出力はこうですね。出力されるのは、入力された文脈語群の中心語はどれかという確率分布です。以下の入力だと、「トーマス」のところで大きい確率であってほしいですね。

  • 「文脈語群:タンク式機関車、の、は、大きな」という入力 → 全ての単語上の確率分布
このモデルは以下のようにつくることにします。
  • 各文脈語を共通の Embedding 層で数値ベクトルにする。
  • 全文脈語の平均ベクトルを出す。
  • それを出力の次元が語彙数の Dense(softmax で活性化)で中心語の予測分布にする。
こうやって学習したときの Embedding 層が求める単語分散表現です。ネットワーク構造は Skip-gram のときと多少異なりますが、要は文脈語への Embedding の方を利用しようということですね。

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

…Skip-gram のときの「内積をとる」もそうだったんだけど、こっちの CBOW の「平均をとる」もかなり決め打ちの操作っぽいような? せっかくニューラルネットつかってるのにさ。

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

そうすることで単語空間がユークリッド空間っぽくなるんじゃないですか(適当)。

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

じゃ Skip-gram と CBOW はどっちをつかえばいいの?

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

140ページに、Skip-gram の方は低頻度語の予測に優れ、CBOW の方は高速とあります。確かに CBOW は Embedding 層が1つしかないので学習が速そうですね。ただ予測器の入力が「文脈語群」なので、低頻度語が混ざった入力の場合、低頻度語以外の寄与で正解を当ててしまい、低頻度語の表現が正しく得られないのかもしれません。Skip-gram は、各単語を「ある単語が周囲に登場しそうか」で特徴づけますから、低頻度語であっても表現の学習が疎かにはならなさそうです。

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

なるほど。これで Skip-gram と CBOW は終わって…147ページの真ん中らへんの「類似した単語がひとかたまりになります」ってどういうこと?

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

例えば…「[ X ] はバンドに欠かせない弦楽器である」という文章の [ X ] には「ギター」も「ベース」も入りますよね。なのでありうる文章をじゅうぶん含んだコーパスで学習すれば Skip-gram や CBOW で「ギター」や「ベース」は近くなるはずです。次に「High×Joker の[ X ] 担当は[ Y ] である」という文章を考えると、[ X ] に応じて[ Y ] には「秋山隼人」「榊夏来」が入るはずですが、「ギター」と「ベース」がほとんど近いならば先ほどと同様の原理で「秋山隼人」と「榊夏来」も近くなるはずです。ということは、「秋山隼人→ギター」「榊夏来→ベース」という2つのベクトルはほとんど似ているはずなんです。このベクトルはさしずめメンバーと担当楽器を結ぶベクトルですね。

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

次の 5.2.4 節はどんな話?

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

現実に単語分散表現を学習するときには Keras より gensim などが便利でしょうという話ですね。

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

Keras の本なのに!?

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

gensim にはある単語に類似度が高い上位の単語を出せる関数や、単語間の類似度を出せる関数が備わっているようですね。

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

この類似度って具体的に何を計算しているんだろう?

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

実際に使ってみて数値表現から検算してみるとよさそうですね。


2018-10-07 追記
f:id:cookie-box:20180305231302p:plain:w60

5.3節は GloVe か。なんか word2vec とは総じて何なのかわからないまま GloVe に入っちゃったんだけど…。GloVe では「文脈」というものを考えるのか。LSA の特異値やトピックモデルのトピックのようなものなのかな…いや違うな。むしろ LSA やトピックモデルでいう文書に相当するのがここでの文脈(通常は単語列)なのか。単語文脈共起行列をさらに単語特徴行列と特徴文脈行列の積に分解するみたいだし。だから、特異値やトピックに相当するのはむしろ「特徴」か。じゃあ GloVe は、文脈は特徴の(重み付き)組合せでてきていて、特徴は生成する単語分布をもつと考えているのかな。でどうやって行列を分解するのかというと…ランダムな値から出発して誤差(再構築誤差)を減少させるように SGD で学習するのか。この誤差の定義がわかんないから全然わかんないな。

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

論文を参照するように書いてありますからね。

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

まあいいや。153ページの図で単語特徴行列がグレーに塗られているから、これが求める単語分散表現そのものなんだな。152ページと153ページで繰り返し出てくる「word2vec は予測ベースで GloVe はカウントベース」ってどういうことなんだろ?

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

153ページの最下部からは、前者は個別データから学習が始まり後者は全体データの単語共起統計量から学習が始まるというように書いてありますね。word2vec の Skip-gram はある別の単語がある単語の文脈語であるかどうかを個別に学習させますが、GloVe はある単語の文脈のヒストグラムを再現するように一気に特徴を学んでいるようには見えますね。Skip-gram でもバッチサイズが大きければ一気に学習する感じにはなると思うのですが。最初から単語共起統計量をターゲットにする方が精度よく特徴を学べるのかもしれません。154ページに GloVe の方が一般に精度がよいとありますから。ただ並列化しないと計算が遅いのが欠点ということなのでしょうか。この本ではあまり詳細に書いていないのでわかりませんね。

(次回があれば)つづく