HELLO CYBERNETICS

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

ガウシアンプロセスを使ってみたい人への最低限の知識

 

 

follow us in feedly

はじめに

下記の記事の通り、非常に良いガウス過程の日本語書籍が出版されました。その気になればガウス過程を誰でも勉強できるようになったという素晴らしい状態です。

www.hellocybernetics.tech

今回は勉強フェーズは上記の書籍に完全に任せるとして、使うという立場でガウス過程を見ていきましょう。

ガウス過程の構成要素

ガウス過程は一般線形モデル $y = {\bf w \cdot \phi(x)}$ に対してカーネル法とパラメータ $\bf w$ に事前分布を設けて周辺化消去を駆使した高度なモデルになっています。ガウス過程を利用する場合には、パラメータの周辺化消去は数式上で実施されているため特に意識することはありません。 $\bf w$ が式から消えた後は、データ $\bf x$ によって $y$ がカーネル関数を介して表現される形式となります。

より正確には、$\bf x$ とカーネル関数 $k({\bf x', x})$ によって定められる分布 $p(f \mid k({\bf x', x}))$ によって関数 $f$ が生成され、その関数 $f$ によって $y _ {new} = f({\bf x} _ {new}) + \epsilon$ と言った具合に新しい ${\bf x} _ {new}$ に対する $y _ {new}$ が生成されます。

そうすると、ガウス過程を利用する場合において、利用者が着目しなければいけないのは、カーネル関数 $k$ と最後に出てきたばらつき $\epsilon$ の表現ということになります。

パラメータの周辺化消去

パラメータの周辺化消去とは、下記の式で表される操作になります。

$$ \begin{align} \mathbb E _ {w\sim p(w)} [y]& = \mathbb E _ {w\sim p(w)} [{\bf w \cdot \phi(x)}] \\ & = \int _ {\bf w} {\bf w\cdot \phi(x)} p({\bf w})d{\bf w} \end{align} $$

これはいわば、とあるモデル ${\bf w ^{1}\cdot \phi(x)}$ を1つ考え、更に別のモデル ${\bf w ^{2} \cdot \phi(x)}$ を考え…みたいなことをした時に、考えうるすべてのモデルを混ぜて使いたいということです。その混ぜ方は、${\bf w ^{k}\cdot \phi(x)}$ に対して $p(\bf w ^{k})$ の係数を付与して、

$$ \sum _ {\bf k} {\bf w ^k\cdot \phi(x)} p({\bf w ^k}) $$

という線形結合したモデルを使うということになります。 $\bf w$ は連続値のはずなので無数にいろんな数値を取ることができます。なので上記の和が積分の形になるという仕組みです。

このとき、 $p(\bf w)$ を平均ベクトル $\bf 0$ で、共分散行列 $\bf I$ (単位行列)としたものを選びます(他の分布じゃダメなの?と思われるでしょう。ダメじゃありません。モデルを考えるという上では他の選択肢もあります。ただガウス分布は非常に性質の良い分布なので、こうするとうまく解析的に計算ができてしまうという都合があります)。

当然積分計算をしたあとには、 $\bf w$ は消えてしまっているので、実を言うとガウス分布ではこれ以降 $\bf w$ というパラメータは明示的に現れることはなくなります。

カーネル関数

さて、そうするとモデルとして残っているのは $\phi ({\bf x})$ という基底関数だけになります。この基底関数が入力 $\bf x$ と出力 $y$ の関係を決定づけるものになりそうです。 ここでカーネルトリックが登場します。カーネルトリックを使うと、基底関数 $\phi$ というものが表面上なくなってしまいます。では、一体、モデルを表す構成要素はどこへいってしまったのでしょうか。

その正体がカーネル関数 $k({\bf x, x'})$ になります。具体的には

$$ k({\bf x, x'}) =\bf \phi (x)\cdot \phi(x') $$

という関係にあります。回帰の式を丁寧に追っていくと、実は $\phi$ という関数が単体で出てくることはなく、いつでも $\bf \phi (x)\cdot \phi(x')$ という形でしか現れなくなります。ならばこれを1つの関数と思って扱ってしまおうということです(本当は、このような形でしか現れないようなモデルに対してカーネルトリックが適用できると言ったほうが正しい)。

ここまで来ると、ガウス過程のモデリングというのは、極端に単純化すると、カーネル関数 $k$ の設計を行うということになります。ただし、基底関数 $\phi$ が単体で現れることはなくとも、カーネル $k$ を考えた時にはそれに対応する何らかの基底関数 $\phi$ を利用したことに結果的になっていなければなりません。カーネル関数をデタラメに作って、実はそんな変換はそもそも成り立ちませんということになってしまっては意味がないのです。なのでカーネル関数として資格を持つためには、いくつかの条件を満たしている必要があります(それは調べればすぐ出てくるので割愛)。

カーネル関数の資格を持つものとしてRBFカーネルだとか多項式カーネルだとか、いろいろありますが、一度カーネル関数の資格を持つ関数を見つけたらば、それらのカーネル関数を足したり引いたり掛けたりしたものもカーネル関数になるという性質を利用し、新たなカーネル関数を作り出すことができます。これは想像以上に柔軟な仕組みを得られたことになります。要するに、平凡に一般線形モデル

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

を考えたらば、ついつい適当な $\phi$ を1つだけ選んでしまいがちですが、いろんな基底関数をごっちゃごちゃに混ぜて使えるということなのです。あら素敵…!(いや、別に一般線形モデルでもその気になれば何でも作れるので、これは本質的な差異ではないのだが、少し手軽な気はする)。

ちなみにRBFカーネルは、基底関数として、いわゆるガウス分布から確率分布としての資格を奪った(すなわち積分して $1$ にならなくても別に良いような関数) $$\displaystyle \exp\left(-\frac {({x - x'}) ^2}{s} \right)$$ を選択していることになるのだが、別にこれは「ガウス過程」の「ガウス」とは無関係です。多項式カーネルを使おうと線形カーネルを使おうと、ガウス過程はガウス過程であり、カーネルはあくまで基底関数を置き換える役割を担っているということに注意してください。

ガウス過程に「ガウス」の名が使われるのは下記の事情です。

ガウス過程

データが $D = \{({\bf x} _ 1, y _ 1), \cdots, ({\bf x} _ n, y _ n), \cdots, ({\bf x} _ N, y _ N) \}$ とあるとしましょう。 ここで、何らかの関数 $f$ によって $y _ n = f({\bf x} _ n)$ という関係があり、

$$ (y_1, \cdots, y_n, \cdots, y_N) = (f({\bf x} _ 1),\cdots, f({\bf x} _ n), cdots, f({\bf x} _ N)) $$

という出力データを並べた多次元ベクトルが$N$次元ガウス分布に従うとき、先ほど天下り的に登場した $f$ がガウス過程に従うと言います。このとき平均 $\bf \mu$ で共分散 $\bf K$ として

$$ f \sim {\mathcal GP} \bf (\mu, K) $$

と表現します。もしも適当な $f$ で変換してみた $y$ のデータ点たちが多変量ガウス分布に従わないのならば、それは $f$ がガウス過程に従っていないということです(ここで、ガウス過程というのは、 $f$ に対して規定されているということ)。 すなわち「ガウス過程を利用する」ということを言い換えるならば、「出力データを並べたベクトル $(y_1, \cdots, y_n, \cdots, y_N)$ が多変量ガウス分布に従っていると仮定する」ということになります。

そしてそれは、出力データ点 $N$ 個を並べたベクトルそれ自体があたかも多次元ガウス分布から出現した1つのサンプル点の如く扱うということです。さらに一歩踏み込むのならば、データ点を無限個、稠密に準備したときには、出力データ $y$ をひたすら並べたベクトルは、関数 $f$ それ自体の形状を描くはずであり、関数 $f$ を1つのデータ点とするような多次元ガウス分布を扱っているということになります(それをガウス過程と呼んでいる)。

もともとガウス過程が $f$ に対して規定されていることから出発すれば、 $f$ とは本来無限個あるであろう $y_n$ たちを並べて出来上がるベクトルであり、その中からインデックスの順序は保ったまま任意に選び出した 有限の$N$ 個のデータを取り出してベクトルを作りだした場合に、そのベクトルが $N$次元ガウス分布に従っていれば $f$ はガウス過程なのだと言えます。そしてこの立場から「ガウス過程を使う」ということを考えると、ガウス過程に従っているであろう $f$ を仮定したならば、収集できうる有限個の $y$ もまた多次元ガウス分布で表されるということであり、あとはその多次元ガウス分布の表現を獲得すればいいということになります。

そして、その多次元ガウス分布の表現が先ほどみた「カーネル $k({\bf x, x'})$」 によって規定されてしまうのです。具体的には共分散行列 $\bf K$ の $(i, j)$ 成分を $k({\bf x} _ i, {\bf x} _ j)$ として決まってしまいます。 平均 $\bf \mu$ の方はというと、 $\bf 0$ としまって構いません。というより $0$ となってしまうようにデータを平行移動しておけばよいのです。多次元ガウス分布に従うという過程をしている限り、この変換は極めて容易です。

ガウス過程回帰

ここでガウス過程回帰という話題に入ります。 $\bf x$ と $y$ の間には$f$ という関数による関係があるとしましょう。ここで $f$ はどんなものなのかわからないが、ガウス過程で表現できるような関数であると考えれば、

$$ f \sim {\mathcal GP} \bf ({\bf 0, K}({\bf x} _ i, {\bf x} _ j )) $$

と表せてしまいます。先ほど実は、適当な嘘をついてしまいました。 $y$ を無限個並べたものが $f$ を形作ってくれるという話のことです。 $y$ は観測データであり、いつでもノイズ $\epsilon$ が混入していることを想定しなければなりません。無邪気に $y$ を並べても本来の $f$ に比べてガタついているかもしれない、ということです。それを表現すべく

$$ y = f({\bf x}) $$

が理想であることに対し

$$ y = f({\bf x}) + \epsilon $$

が観測の実体であると考えます。すなわち、厳密には $y$ と $f({\bf x})$ は一致せず、その差分としてデータ点毎に毎回何らかの $epsilon$ が混入しているということです。 ではこのノイズ $\epsilon$ はどのように表現してやると良いのでしょうか。ここはもはや普通の回帰同様、 $\epsilon$ がガウス分布に従っていると考えてしまいましょう。

すなわち $y$ は理想的な状態からガウスノイズの分だけばらつく生成モデルを考えます。実はそのような分布は $f$ がガウス分布であることもあり、非常に簡単な形に持っていくことができ、生成モデルをガウス過程の共分散行列やデータ点だけから解析的に求めることできてしまいます。つまり、カーネル関数を定めてしまえば、通常の意味での学習は、直ちに終了するということです。そして新しいデータ点 $\bf x'$ に対する $y'$ の予測分布も解析的に求まります。

というわけでカーネルの設計が重要なのですが、カーネル自体にパラメータを持たせて(というか通常はハイパーパラメータと呼ばれる者達である)を学習してしまうことができ、ガウス過程の学習と言った場合には、カーネルを構成するハイパーパラメータをデータによって推定することを指すのでしばしば注意が必要です。

ガウス過程分類

一般化線形モデルを勉強していれば、「ちょっと待ってくれ!観測のバラつきの表現はガウス分布でなくてもよくないか?」と自然と思えます。これが冒頭で「ガウス過程を利用する場合において、利用者が着目しなければいけないのは、カーネル関数 $k$ と最後に出てきたばらつき $\epsilon$ の表現ということになります。」と述べた理由です。ガウス過程に従う関数 $f$ はカーネルの設計によってモデル化され、ばらつき $\epsilon$ の表現が実施する推定の問題を規定することになります。

ハイパーパラメータの推定を適当なライブラリで実施する立場から端的に述べれば、損失関数となる負の対数尤度関数をどのように選ぶか(結局はバラつきのモデルをどうするかということ)によって指定することが多いはずです。

最後に

余力があれば何かコードを書こうと思ったが、そういう場合にはたいてい余力はないのである…。

詳しい理論面はやはり

www.hellocybernetics.tech

を参考にして欲しいです。 コードは、numpyでいろんな人が書いていたり、あるいはGpyTorchやGpyなどの優れたPythonライブラリも多数あるので、そちらが参考になると思います。