はじめに
Pythonによるベイズモデルの実装をきちんと学ぼうと思い,森賀新・木田悠歩・須山敦志 著 「Pythonではじめるベイズ機械学習入門」を読むことにした。
本記事は,第3章「回帰モデル」のうちガウス過程回帰(ガウス尤度)に関する読書メモである。
- 本書の紹介ページ
3.6 ガウス過程回帰モデル:ガウス尤度
本節では,ノンパラメトリック回帰モデルと呼ばれる非常に柔軟な回帰モデルであるガウス過程回帰(Gaussian Process Regression Model)について説明している。
3.6.1. モデル概要
ガウス過程(Gaussian Process)の定義は以下の通りである。
ある確率変数の集合をとする。任意の自然数に対して,を関数としてから選んだ個の確率変数がガウス分布に従うとき,をガウス過程と呼び,はガウス過程に従うという。
つまりガウス過程は,関数からなるベクトルを出力するシステムとみなすことができる。
カーネル関数
ガウス過程の直感的な性質として,「入力が近ければ出力も近くなる」というものがある。この近さを表現するために,カーネル関数を用いる。
カーネル関数は,入力との距離を表現するものである。代表的なものとしてRBFカーネル(Radial Basis Function Kernel; 動径基底関数)がある。
先述の通りガウス過程は,平均関数とカーネル関数によって,生成される関数の性質が決まる。データの平均値を0に正規化しておくことで,平均関数はゼロベクトルと仮定できるので,ガウス過程の性質はカーネル関数によって特徴づけられることになる。
具体的な入力値の集合を用意すると,これらの入力値を用いて,次のような共分散行列
を計算すると,ガウス過程は
のように次元の多次元ガウス分布できる。または,から次元ベクトルをサンプリングしたものとして表現できる。
なお,本書の参考文献( ベイズ深層学習 | 書籍情報 | 株式会社 講談社サイエンティフィク )によると,入力ベクトルの集合から2つの要素を取り出してカーネル関数の値を算出し行列にしたものを,特にと表現している。
すなわち(1)式においては,である。
カーネル関数の組合せ
など,近さの関係性ごとに様々なカーネルが存在する。
また,2種類のカーネル関数の和や積もまたカーネル関数になるので,新たなカーネル関数を設計することもできる。
データにもとづき,複数のカーネル関数の候補から適切なカーネル関数を選択するには,対数周辺尤度(log marginal likelihood)の比較を行なう。
入力と,これに対応する出力の組合せが個存在し,およびと表すと,周辺対数尤度は,
となる。
ハイパーパラメータも選択する必要があるが,データに対する過剰適合を防ぐために,ハイパーパラメータに対しても事前分布を設定し,ハイパーパラメータの事後分布を同時に推論することで,過剰適合を抑制できる。
推論
ガウス過程回帰では,新たなデータに対する予測分布の出力が可能である。
すなわち,学習データを用いて学習を行なった後に,新規の入力値が得られたときの予測値の予測分布を算出することができる。
問題設定を簡単にするために,入力値は1次元でで,これに対応する予測値はとする。
ガウス過程回帰の学習を行なうと,のように表現できる。
予測分布を算出するにはが従う分布を求めればよいのだが,これを求めるためにという次元のベクトルを導入する。また,およびから算出される行列をとすると,ガウス分布の性質よりもまたガウス分布に従い,
となる。すなわち,
となる。ただし,
である。
ここで,ガウス分布の条件付き分布の公式を用いる。ガウス分布に従うベクトルが,
のように分割されているとすると,条件付分布は,
であるので,この式を用いるとガウス過程分布の予測分布は以下のようになる。
予測の入力が複数ある場合でも考え方は同じで,結果は本書のP130の通りとなる。
尤度関数
各関数の出力に対して独立なノイズが付与されることによって,データが観測されていると仮定する。今回は観測分布としてガウス分布を仮定する。
このとき,次のような尤度関数を定義していることになる。
3.6.2 実装
サンプルコードを動かしながら,挙動を確認した。
github.com
データの準備
データは下図に示すような人工データを用いる。
GPyTorchの特徴
ガウス過程の最大の問題点は,予測分布の計算においてサイズの行列の逆行列計算が含まれることである。これにより計算量のオーダーがになる。
GPyTorchでは,blackbox matrix-matrix multiplication (BBMM)推論を用いることで,計算量を実質的にに減らしている。
モデルの定義
ガウス過程回帰のモデルは,以下の様に実装される。
- サンプルコード
# ガウス過程回帰モデルの実装 class ExactGPModel(gpytorch.models.ExactGP): def __init__(self, train_x, train_y, likelihood): super(ExactGPModel, self).__init__(train_x, train_y, likelihood) # 平均関数 self.mean_module = gpytorch.means.ConstantMean() # カーネル関数 self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel()) # ガウス過程の生成過程 def forward(self, x): mean_x = self.mean_module(x) covar_x = self.covar_module(x) return gpytorch.distributions.MultivariateNormal(mean_x, covar_x) # 尤度にガウス分布を設定 likelihood = gpytorch.likelihoods.GaussianLikelihood() # モデルのインスタンス化 model = ExactGPModel(x_data, y_data, likelihood)
まずモデルの構造として,mean_moduleとcovar_moduleを設定している。
サンプルコードではRBFカーネルを用いているが,これ以外のカーネル関数を用いる場合はcovar_moduleの定義を変更すればよい。
カーネル関数に含まれるハイパーパラメータは,勾配法によって求める。損失関数は負の周辺対数尤度である。学習ステップごとの損失関数の推移は下図のようになる。
学習の後,予測分布を算出する。予測の入力は,-1から1までを50等分した値であり,予測結果は下図のようになる。
学習データが少ない領域の分散は大きくなり,予測の不確実性が高くなっていることが分かる。
まとめと感想
ノンパラメトリック回帰の1つである,ガウス過程回帰モデルについて学んだ。
本書は理論と実装の両方を紹介している良い本なのだが,紙面の関係でどうしても理論部分の説明を他書に譲る必要が出てくる。ただ,参考文献もきちんと書いてくれているので,行間はガウス過程と機械学習 | 書籍情報 | 株式会社 講談社サイエンティフィクやベイズ深層学習 | 書籍情報 | 株式会社 講談社サイエンティフィクで補うことができた。
ガウス過程は,定義がとっつきにくかったが,いくらか具体例を紹介していただけると理解できた。特に予測分布は,多変量正規分布の条件付き分布のよい復習になった。
機械学習に初めて触れた2000年代前半は,カーネル法やSVMが最盛期であり,当時からカーネル行列の逆行列計算やその近似計算については議論になっていた。アルゴリズムや実装の面で工夫がされてきているので,しっかり実践していきたい。
本記事を最後まで読んでくださり,どうもありがとうございました。