HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学、量子計算などをテーマに扱っていきます

機械学習で予測モデルを作る際の概要のオレオレまとめ

 

 

follow us in feedly

https://cdn.blog.st-hatena.com/images/theme/og-image-1500.png

はじめに

機械学習のモデルには数多くのものが存在します。 例えばサポートベクターマシンやニューラルネットワーク、ロジスティック回帰モデルなど、初学者にとってどれが何のために生み出され、 そしてどのような時に有効なのかを把握することは難しいように思います。

 

そこで今回はある特定のモデルについて細かく見るのではなく、機械学習のモデルが何を表し何を達成しようとしているのかの概観を与え、 それぞれのモデルがどういう時に使えそうなのかの感覚を身につける手がかりのようなものを書いてみたいと思います。

(最初、一般化線形モデルからベイズまでそれなりにしっかり書こうと思ったのですが、死ぬほど長引きそうだし、長引かないような上手い説明の仕方は私のレベルではできなかったため、 なんか本当に概要だけの記事になりました。)

機械学習のモデル

機械学習で達成したいこと(の多く)は、手持ちのデータDから今後、将来的に得られるデータに対する予測あるいは知見を得たいというものです。 そこでDに基づいた何らかの予測モデルを構築することが所謂学習となります。 しかし、どのようなモデルを仮定するかに応じて、得られる予測モデルは変わってきます。

 

ここでは、ザックリと予測モデルがどのようなものかを見てみましょう。 今回は題材として教師あり学習を考えていきます。

教師あり学習

手持ちのデータが D= \{ (x_1,y_1), (x_2,y_2), ..., (x_N,y_N) \}で表されるとしましょう。 今xの値に応じてyが適切に予測できるような状況を想定(あるいは期待)します。すなわち、

$$ y = f(x) $$

のように、$x$を入れたら$y$を出力するような関数$f$が作れるであろうと考えるわけです。

 

このとき、N個の「入力データ$x$と出力データ$y$の組」が手に入っているという状況で、上手い関数$f$を作り、 今後得られる$x_{new}$に対して正しい$y_{new}$を出力してくれればうれしいということです。

 

xが仮に身長、体重、体脂肪率、筋肉量などの身体的データを格納したベクトルであり、yが性別(男or女)が格納されたスカラーだと思えば、 これは2クラス分類器を作ることに相当し、$y$が年収のような連続的な数値だとすれば多入力一出力の回帰を考えることになります。

 

このとき、これから作りたい関数$f$が上手く動作する保証はどこにもないことに注意してください。 身体的データから性別が分かるのか、あるいは年収が予測できるのかなんてのは、理論的に保証されることではありません。 予測できるとしたらどのような$f$が考えられるのか、しか言えません。

 

機械学習における予測モデルの基本的な作り方

予測モデルfの考え方

さて、予測モデル$f$をデータ$D$から求めるためにはある程度の仮定が必要です。 例えば、$x$と$y$は正比例の関係(あるいは線形の関係)にあると考えれば、

$$y=f(x)=w\cdot x$$

であろうなどと仮定できます。

 

このときには私達が求めたいのは$w$というパラメータになり、これが求まれば予測モデル$f$が決定できるというわけです。 もちろん、実際には$x$と$y$の関係が仮定した形式になっているかの保証などどこにもありません。 もしかしたら今回のようなあまりにも単純すぎる仮定では、全くデータの関係を表すことはできないかもしれません。

 

そこでもうちょっと$f$に表現力を与えたいときがあります。その方法の1つが、$x$をあれこれ加工して$\phi(x)$としてから、

$$y=f(x) = w\cdot \phi(x)$$

の関係で表そうというものです。$\phi(x)$の決め方はいろいろありますが、上手く選ぶことができれば、$f$に表現力を持たせることができそうです。

 

$\phi(x)$の決め方

私達は予測に役立つような$f(x)$を作ろうとしています。 そのために$\phi (x)$というデータの加工を行えば表現力が高まります。というのがここまでの流れです。 しかしここで一つの疑問が生まれます。 $f$を求めることが$\phi$を上手く選ぶことに変わっただけで、なんというか前に進んでいないような気がするのです。

 

それでもこの考え方は多くの場面で役に立つでしょう。 私達は、非線形性などを含むある種の複雑な関係性は$\phi$の方に表現させておいて、 一方で線形の関係性は$w$の方で表現しようという、問題の分解ができたのです。 ここまでの考え方で生データ$x$を何とか加工することで、 最終的には予測したい$y$と線形の形に持っていくことが目標になりました。

 

つまり、実際に学習で求めなければいけないのは$w$だけであり、比較的簡単ということです。 $\phi(x)$がどれだけ複雑な形をしていようが、$\phi(x)$を一度固定して、$z=\phi(x)$なる新しい変数だと思ってしまえば

$$ y=f(x)=w\cdot \phi (x) = w \cdot z $$

に過ぎなく、とっても簡単な線形回帰(線形分類)の問題として捉えられるのです。 そうであれば、既に存在する既存の学習手法を使い回すことが可能です(特に、計算機がまだ発達していない頃は、既存の比較的計算の軽い手法が使えることは重要でした)。

 

最初は予測をするための関数$f$を作りましょうと言う途方も無く抽象的な話から、少しは具体的なことに踏み込めるようになった気がします。 さて、ここで$\phi$の方をどのように考えていくのか、その大まかな考え方を紹介します。

 

特徴量エンジニアリング

さて、予測モデル$f$を作っていく上で最も基本的なアプローチを紹介します。 それは生データ$x$に対して様々な事前知識を活用した加工を施すということです。 いわゆる特徴量エンジニアリングと呼ばれるものです。

$$z=\phi(x)$$

という加工(特徴量エンジニアリング)を行い、 $z$に対して線形回帰や線形分類を行うという方針です(特徴量エンジニアリングがそのまま$\phi$の役割をする)。

 

問題は自分たちの知恵を絞っても非常に上手い特徴量エンジニアリングは難しいという点です。

大体、確実と分かっている処理があるのならば、その処理を施さないという選択肢は殆ど無いので、 今回のようにまるで特徴量エンジニアリングや前処理がモデルの一部$\phi$であるかのような話し方はしません。

 

モデル選択

非常に上手い特徴量エンジニアリングが見つからないとしましょう(大抵そうである)。 つまり、おいしい$\phi$が私達にはわからないのです。

それならば「何個か$\phi$を準備しておいて、$f(x)$を作ってみて、一番良かった$\phi$を使えば良いんじゃないですか?」ということが考えられます。 つまり以下のように例えば3つのモデルを作ってみて

$$ y=f_1(x)=w_1\cdot \phi_1 (x) $$

$$ y=f_2(x)=w_2\cdot \phi_2 (x) $$

$$ y=f_3(x)=w_3\cdot \phi_3 (x) $$

何らかの方法でそれぞれの$w_i \cdot \phi_i$を比較し(例えば交差検証など)、 モデル選択を行うという方針が取れます。

もちろん、生データ$x$に対してこれはやっておいたほうが良いという処理が分かっているのであれば、 特徴量エンジニアリングと組み合わせることも可能です。それはつまり、$z = g(x)$なる加工を施しておいて(そしてこの加工は優れていると仮定して)、

$$ y=f_1(z)=w_1\cdot \phi_1 (z) $$

$$ y=f_2(z)=w_2\cdot \phi_2 (z) $$

$$ y=f_3(z)=w_3\cdot \phi_3 (z) $$

と幾つかのモデルを準備することに相当します。

 

多くの場合はこの形式が取られるのではないでしょうか。 既に知っている確実な知識を特徴量エンジニアリング、あるいは前処理でしっかり反映しておいて、 確実とは言えない怪しい部分を、「仮定」という形で$w\cdot \phi$に託すのです。

 

$\phi$が自由すぎるとモデルは簡単に過学習してしまいます。 かと言って単純すぎると、モデルの残る部分は$w$だけになってしまい、 コイツは線形分離や線形回帰しかできないので心もとない学習結果が得られるでしょう。

 

なかなか有望な$\phi$を選ぶのは難しそうです。

 

ニューラルネットワーク

そこで「$\phi$を学習の中で一緒に求めてしまえばいいんじゃないですか?」という考えも重要でしょう。 つまり、$\phi$の方にも何らかの仮定を入れてパラメータ化して、そのパラメータを一緒に求めてしまえばいいということです。 具体的に言えば、ニューラルネットワークはこの部分に該当するのではないかなと思います。

 

例えば出力が1つで、中間層が2つのニューラルネットワークは以下のような形をしています。

$$ y=f(x)=w\cdot \sigma(W_2\sigma(W_1x)) $$

一番最後の$w$が出力層の重みだと思えば、それまでの層は$\phi$を表すための層だと見ることができます。 「深層学習が特徴量を自分で獲得する」などと言われるのはこのような面を見ているのだと思われます。

 

ただ、一番最初に述べたとおり、実際にデータがこのように表せるかの保証など誰もしてくれないので、 上手い特徴量を選べている保証だって誰もしてくれません。ましてやニューラルネットワークがそうしてくれる保証もありません。 ただ、特徴量を持ってきていると見なす形をあれこれ考えることはできるということです。

 

もちろんココでも、特徴量エンジニアリングやモデル選択の概念が消えることはありません。 確実と分かっている前処理は当然行うべきですし、 何らかの仮定を設けたニューラルネットワークを複数準備して、モデル選択を行うというのが通常の手法です。

 

ここで何らかの仮定とは、ニューラルネットワークの構造や学習の条件などのハイパーパラメータを選ぶことに相当します。

そういう意味では、ニューラルネットワークを使おうが何をしようが、特徴量エンジニアリングや$\phi$の選択に関して私達は解放されたわけではありません。 深層学習では、ニューラルネットワークの構造であったり、学習の条件であったりなどに置き換わっているだけです。

 

ただ、何となくニューラルネットワークの構造を考えるというのは、抽象的な$\phi$なるものを考えるよりは幾分かとっつきやすいとは言えるでしょう。

 

複数の予測モデルの活用

アンサンブル

さて、予測モデルを幾つか作って比べてみたり、特徴量エンジニアリングをしてみたり、ニューラルネットワークを設計・学習したりと、やることがいっぱいあります。 これら全ては、ある一つの予測モデルを上手く作るための作業であり、ある1つの予測モデルが完成した時、道中で得られたそれ以外の予測モデルが全て捨て去られてしまうことになります。

 

なんて勿体無いのでしょう。そこで、複数のモデルを組み合わせて1つの予測モデルにするという考え方があります。 方法はいろいろあるのですが、形式的には予測モデル$f_i$があるときに、最終的な予測モデル$f$は

$$ f = g(f_1, f_2, ...) $$

などと、複数の予測モデルを統合する関数$g$で与えられるでしょう。

 

これがモデルのアンサンブルです。ここでそれぞれの予測モデル$f_i$はそれぞれ異なる予測を与えるでしょう。 しかしそれらの予測を上手く組み合わせて1つの予測に統合する方法を与えれば、 ある1つのモデルを使うよりもっと良い結果が得られる可能性があります。ナンバーワンだけではなく、数多くの意見を取り入れましょうということです。

 

するとこの手の手法では、どのように複数の予測の意見を統合するか(つまり$g$をどのように作る)が問題になります。

 

 

アンサンブル学習は、単にいろいろな機械学習モデルを混ぜましょうという話ではなく、更に発展的な1つの分野とも言えるでしょう。

 

それは、モデルを学習させるときにまで遡って見ると分かります。 例えば、ある予測モデルAにはある観点の予測にのみ特化させて、 別の予測モデルBには、別の観点の予測にのみ特化させて学習させるのです。 すると、問題の観点に応じて、どの予測モデルの意見を尊重するかを調整するという方法を考えることができます。 ある種の分業ですね。いろんな分野のスペシャリストを育て上げ、問題に応じてそれぞれの意見を集約するということです。

 

あるいは、順番に予測モデルを学習をさせていくことを考え、 前の予測モデルが苦手とする問題を補うように順次予測モデルを学習させていくという方法を考えることもできます。

 

ベイズ予測分布

「複数のモデルを活用する」という考え方に、ベイズ予測分布を使うこともできます。

 

まず複数の予測モデル$f_i(x)$を作った際に、全ての予測分布を上手く統合するというのが今回の方針です。 統合の仕方を単純に線型結合で表すことにしましょう。すなわち、

$$ y = p_1f_1(x) + p_2f_2(x) + \cdots = \sum_i p_if_i(x) $$

と、重み付け$p_i$によって複数の予測モデルの意見を統合し、ひとつの出力$y$を得るということです。

  

ここで予測モデルの1つ1つは$f(x) = w\cdot x$などとなっているかもしれませんし、$f(x)=w \cdot \phi(x)$となっているかもしれません。 はたまたニューラルネットワークの形になっているかもしれません。それは好きなように選ぶこととし、$f(x, w)$と表しておきましょう。

 

すると予測モデル$f_i$のアンサンブルを行うというのは、言わば、いろんな$w$で作られる$f(x, w)$を利用するということです。

$$ y = p(w_1)f_1(x,w_1) + p(w_2)f_2(x,w_2) + \cdots = \sum_i p(w_i)f_i(x,w_i) $$

ここで重み付け$p_i$を$p(w_i)$と書き直しました。 なぜならモデル$f_i$に応じた$p_i$を決めることが目的でしたが、モデル$f_i$が$w_i$によって表されるようにしたので、 $p_i$は$w_i$に応じて決まればいいからです。

 

さてここで、考えうる全ての$w_i$を無限個準備することにしましょう。すると和が積分となり、式は以下のようになります。

$$ y = \int_w p(w)f(x,w)dw $$

無限個の$w$を準備したならば、予測モデルを無限個準備したも同然です。 ここで無限個の予測モデルを上手く統合する方法が得られれば素晴らしいでしょう。

 

それを可能にするのがベイズ予測(分布)です。 今回のように$x$に対して$y$を予測するような場合の概要だけ述べることにすると、(理想的な)ベイズ予測分布とは以下の式で表されます。

$$ p(y | x) = \int_w p(w)p(y|x,w)dw $$

ここで$p(w)$は$w$がどれだけ上手いパラメータになっているかの重みを確率で表したものです。

どうやらベイズ予測分布では、全ての$w$の関しての重み$p(w)$の和が$1$になっているということのようです。

  

$p(y | x, w)$は、パラメータ$w$と$x$が決まった時に$y$という値が出てくる確率を表しています。 この部分が1つ1つの予測器に相当するようです。

 

まとめれば、1つ1つの予測モデル$p(y|x,w)$を$p(w)$という重み付けで統合しているのがベイズ予測分布というわけです。 急に関数が確率分布になってギョッとするかもしれませんが、ベイズ予測分布がやろうとしていることは所謂アンサンブルのようなものだというわけです。

  

  

さてここで問題なのは、じゃあ$p(w)$をどうやって決めるんですか?というところでしょう。 実は$p(w)$なる上手い重み付けなど最初から知っているわけではありません。 そこで、手持ちのデータ$D$からこれを決めてしまいたいということになります。

$D$に基づいた$w$の重みは

$p(w|D)$

で表されます。

  

通常の機械学習では上手いモデル$f$あるいは上手い$w$を1つ求めることが目的でした。

しかし、ベイズ学習では最初からアンサンブルすることを目標にしているので、$w$を1つ求めるのではなく、 データ$D$に基づいて、上手いパラメータ$w$の重み付け$p(w|D)$を求めるということになります。 コイツを求めるのが所謂ベイズ学習、ベイズ推定、ベイズ推論になります。

 

データに基づく上手い重み付けを$p(w|D)$としたら、現実的に利用する予測分布は

$$ p(y | x) = \int_w p(w|D)p(y|x,w)dw $$

という形式で表されます。また、ベイズ予測では、値が得られるのではなく値の確率が得られます。$y$がこの値である確率は◎◎ですと言ってくれるようになります。

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

  

多くのモデルのアンサンブルによって出力を行うので、やけに自信満々な過学習した$f_i(x,w)$がいい加減な予測を行うということはなくなります。 代わりに多くのモデルの意見を採用した、「そのような値と成る確率」を出力し、 その確率が低ければ予測モデルが自身をあまり持っていないと見ることができます。

  

ただし、ベイズ予測分布を使ってもモデルの正しさを保証してくれるというわけではありません。 要するに、明らかに正しいことに関しても、「私は自信がありません」と言ったりする場合もあるのです。

  

それは統合される前の予測モデル1つ1つは$p(y|x,w)$という形をしているわけですが、 これは$w$をパラメータとする確率分布であり、この形状に関しては仮定を設けなければならないからです。

  

この仮定が間違えていれば、それらを統合して得られる予測分布も重み付けの仕方も変になってしまうわけです。

  

ほとんど分布に仮定を設けない、ノンパラメトリックな確率分布を使うという方法もあるようですが、私の知識の範囲を逸脱するのでこの辺で。

s0sem0y.hatenablog.com