機械と学習する

統計解析、機械学習について学習したことをまとめていきます

【読後メモ】データ解析のための統計モデリング入門(その3)

  • 改めて「データ解析のための統計モデリング入門」を読みました(一部飛ばしたけど)。本記事は読後のメモです。
  • 全3回の連載で、今回が第3回目です。GLMのベイズモデル化(第9章)と階層ベイズモデル(第10章)についてまとめます。
  • 第2回第1回も合わせてご覧いただけたらと思います


【目次】

はじめに

「データ解析のための統計モデリング入門」を読んだので、 どのようなことが書かれているのかといったメモを残しておきます。

この書籍では、統計モデリングとして「一般化線形モデル」に着目し、その基礎と発展について書かれています。 よくある統計学の入門書では、確率の基礎や確率分布の紹介が多くの紙面を割いていることがあります。 しかし本書では、一般化線形モデルに焦点を絞ることで、確率・統計の基礎についてはあまり触れられてはいません。 これだけ書くと難しいように感じるかもしれませんが、逆に焦点を絞ることで本書を通して一貫した話題になっており、 一般化線形モデルについて理解しやすいのではないかと思います。 また、例題をベースにしているのも理解が進みやすいポイントかなと思います。

本書籍の読後メモは全3回でまとめる予定です。

本記事は第3回です。 第3回では、第9章 GLMのベイズモデル化と第10章 階層ベイズモデルについてまとめていきます。

【トップに戻る】


第1回 : learning-with-machine.hatenablog.com

第2回: learning-with-machine.hatenablog.com

第3回 : 本記事


第9章 GLMのベイズモデル化と事後分布の推定

第8章ではMCMCアルゴリズムを軸に、ベイズモデリングという考えの触りを学習しました。 第9章では、第3章で学習したGLM(一般化線形モデル)のベイズ化を扱っています。 ベイズ化/ベイズモデリングについては、なぜこれが必要なのかなど説明が本書籍ではあまり触れられていないように感じます*1が、 この辺りについては私が書いた以下の記事などをご覧いただけると何かわかるかもしれません。

chocolate-ball.hatenablog.com

ざっくりと私の考えを述べると次のようになります。 第7章までで扱ってきた最尤法ではパラメータを一つの推定値として求めるのに対し、 ベイズ推定では事後分布という形でパラメータを推定します。 最尤法は一点で予測するためにデータが少ない場合に極端な値を推定することがあります(過適合)。 これに対してベイズ推定では、データが少ない場合には曖昧さを分布の広がりで表現できるということに違いがあると考えています*2

ということで、第7章までで扱ってきた最尤法によるパラメータ推定をベイズで行うとどのようになるのかを見ていきます。 なお、ベイズでのパラメータ推定には第8章で扱ったMCMCアルゴリズムを使用します。 第8章では、種子の生存個数を二項分布としてその生存確率という単一のパラメータ推定問題を例として MCMCアルゴリズムが解説されていましたが、この章では複数のパラメータを推定する問題を扱います。

例題の設定

第4章で扱った植物の種子数のモデルが本章で扱う例題とされています(ポアソン回帰)。

個体iの種子数y_iは、パラメータ\lambda_iポアソン分布に従うと仮定します。 ポアソン分布のパラメータ\lambda_iは、個体サイズx_iを特徴量として予測されると仮定します。 これらを表現すると以下のようなモデルになります。

{ \displaystyle
y_i \sim Poi(\lambda_i) \\
\lambda_i = \exp(\beta_1 + \beta_2 x_i)
}

ここで、線形予測子のパラメータ\beta_1, \beta_2が予測対象のパラメータで、 これらをベイズモデリングにより推定していきます。 なお第3章では、Rのglmライブラリを使って最尤推定しました。

GLMのベイズモデル化

上記のモデルをベイズモデル化します。 ベイズの定理より、事後分布は以下の式で得られます。

{ \displaystyle
p(\beta_1, \beta_2 | D) \propto p(D | \beta_1, \beta_2) p(\beta_1, \beta_2)
}

右辺第1項は尤度関数であり、パラメータ\beta_1, \beta_2がある値の時のデータDの同時確率です。 第2項はパラメータ\beta_1, \beta_2の事前分布であり、本書籍では、\beta_1, \beta_2は 独立と仮定しています(p(\beta_1, \beta_2)=p(\beta_1) p(\beta_2))。

最尤法では尤度関数だけを扱ってきましたが、ベイズ推定では事前分布を設定します。 この事前分布がパラメータの範囲を定めるため、正則化をしているとみなせます(PRML 第1章)。 次節から、尤度関数と事前分布を具体的に設定し、パラメータを実際に推定してみます。

尤度関数

尤度関数は、パラメータ\beta_1, \beta_2がある値の時のデータDの同時確率です。 ここで、データDはi.i.d.(独立同分布)を仮定するので、尤度関数は以下の式となります。

{ \displaystyle
L(\beta_1, \beta_2 | D) = \prod_i p(y_i | \beta_1, \beta_2, x_i)
}

ここで、データDはD=\{y_1, y_2, \cdots, y_n\}であり、x_iは植物iの個体サイズです。

事前分布

事前分布については、第8章で述べている通り、 データがない時のパラメータの分布を表します。 分析者の信念やドメイン知識に基づいて事前分布を設定することもありますが、 本書籍では「無情報事前分布」を使うとしています。

無情報事前分布ですが、今回の推定対象であるパラメータ\beta_1, \beta_2は、 値の範囲が[-\inf, \inf ]であるため、 一律に特定の値をとるようにしてしまうと正規化して1になりません(発散する)。 そのため、このような定義域のパラメータの無情報事前分布として、分散が大きな平たい正規分布を利用することが多いです。

事後分布の推定

上記の通り事前分布に平べったい正規分布を利用するとして、具体的に事後分布を推定していきます。 実際の計算は、8章で述べられているMCMCアルゴリズムを利用します。

本書籍では、R言語とWinBUGSを利用したコードが紹介されています。 WinBUGS(他にもStan)とは、モデルとデータを定義することでMCMCサンプリングを実施してくれるソフトウェアのことで、 Probabilistic Programming Language(確率プログラミング言語、PPL)と呼ばれています。 WinBUGSやStanは、R言語とのインターフェースが用意されており、R界隈ではよく利用されていると思います。

しかし、私はRはあまり使っていないのでPythonを利用したいと思います。 Pythonに於けるPPLは、 PyMC3、TFP(Tensorflow Probability)、pyroなどが有名なところです(PyStanというものもありますが、私は詳しくありません)。 以下のコード例はpymc3を利用したコードになります。

モデルの定義はセル番号5番で行なっています。 ポアソン回帰なので、モデルとしては以下の通りです。

{ \displaystyle
y \sim Poi(\lambda_i) \\
\log(\lambda_i) = \beta_1 + \beta_2 x_i
}

\lambda_iは対数リンク関数で線形予測しているのですが、 コード上では左辺の対数を右辺にて指数の形で表現しています。

パラメータ\beta_1, \beta_2の事前分布は、 ともにN(0, 10)という正規分布としています*3

以上のモデルを図で表現すると以下のようになります。

f:id:hippy-hikky:20190409001951p:plain
種子数予測のためのモデル(Kruschkeのダイアグラム)

パラメータの予測結果は、以下のように事後分布で予測されています。

f:id:hippy-hikky:20190408235613p:plain
MCMCサンプリングの結果。上段が\beta_1、下段が\beta_2であり、左列がヒストグラムKDE)、右列がサンプル系列。

この結果から、事後分布の平均として、(\beta_1=1.29, \beta_2=0.08)という推定結果を得ることができました。 これは、第3章の最尤法での結果とほぼ一致します。

次に、事後分布からサンプルしたパラメータを利用して、回帰直線を描いてみます。

f:id:hippy-hikky:20190409000036p:plain
推定した回帰直線。青点はデータ。オレンジ線が事後分布からサンプルした回帰直線で、青線は事後分布の期待値。

このようにして、GLMをベイズ化してパラメータが予測できました。

【トップに戻る】

第10章 階層ベイズモデル -GLMMのベイズモデル化-

第9章ではGLM(ポアソン回帰)をベイズモデル化しました。 続いて、第10章ではGLMMをベイズ化します。 GLMM(一般化線形混合モデル)については、 当シリーズの第2回で触れていますので 詳しくはこちらをご参照いただけたらと思います。

なおGLMMの最尤推定については、RのglmmMLパッケージなどがあるようですが、 ちょっと調べたところPythonにはぴったりなパッケージが無さそうです。 そのため、Pythonを使ってGLMMを解くためには、 ここで紹介するように階層ベイズモデルにしてMCMCアルゴリズムで推定するのが簡単ではないかなと思います。

例題の設定

第7章で扱った個体差のある種子の生存確率のモデリングが例題とされています。 「各個体で8個の種子をサンプルし、その中で何個の種子が生存していたか」という問題のため、 普通に考えると二項分布でモデリングするでしょう。 しかし、個体差があるため、下図の通り過分散なデータになっています。

f:id:hippy-hikky:20190409215822p:plain
例題データのヒストグラム。各個体8個の種子をサンプルし、生存していた種子の個数についてのヒストグラム

第7章では、過分散が個体差によるものとして、GLMMを使ってモデリングしてきました。 これを階層ベイズモデルとしてモデリングしてみます。

階層ベイズモデル

8,9章で扱ったベイズモデルでは、求めたいパラメータに事前分布を設定しました。 階層ベイズモデルとは、事前分布を構成するパラメータもデータから推定するためにさらに事前分布(階層事前分布と呼ぶ)を設定します。 この階層モデル(階層事前分布)の意味を例題に従ってみていきます。

まず本データである個体iの生存種子数y_iは第7章と同様に以下の二項分布に従うと考えます。

{ \displaystyle
y_i \sim \binom{8}{y_i}q^{y_i}_{i}(1-q_i)^{8-y_i}
}

ここで、二項分布のパラメータである生存確率q_iですが、 全ての個体で同じ生存確率という単純な二項分布で表現すると上記の通り個体差があるためモデルの精度は悪化します(過分散)。 そこで、q_iは以下で示すように、個体差r_iを持つとしてみます(第7章)。

{ \displaystyle
logit(q_i) = \beta+r_i
}

\betaは全個体に共通のパラメータです。 個体差が少ない均質な植物群であれば、個体差rは小さく、単純な二項分布モデルと同じものとして表現できます。 第7章では、個体差r_i積分消去して期待値を計算していましたが、 階層ベイズモデリングではこのr_iにも事前分布を設定して、推定します。

まず、r_iN(0, s^{2})正規分布に従うものとします(第7章)。 ここに出てくるsは、個体毎のばらつきの大きさを規定するパラメータです。 sが小さければ、植物群は全体的に均質(r_iは0に近いものばかり)であると見れるし、 sが大きければ、植物群のばらつきが大きいと言えます。 このように、推定対象のパラメータr_iの全体の動きを規定するための(上位階層の)パラメータを仮定して、 一緒に推定するモデルが階層ベイズモデルです。

なお、個体差r_iの事前分布のように、事前分布の事前分布を階層事前分布と呼び、 階層事前分布のパラメータ(ばらつきの大きさs)をハイパーパラメータと呼びます。

階層ベイズモデルの推定

では、上記のモデルを使って、具体的にパラメータの推定をしてみます。 先の9章での実験の通り、PyMC3を利用して計算してみます。 jupyter notebookを添付しますので、ご参照ください。

モデルの定義はセル番号5で行なっています。 先に示した通り、種子数は二項分布に従うとし、 そのパラメータである生存確率p_iを共通パラメータ\betaと個体差r_iで表現しています。

\betaの事前分布は平たい正規分布としています。 個体差r_iの事前分布はN(0, s^{2})正規分布です。 そして、sの事前分布として一様分布を設定しています。

以上のモデルを図で表現すると以下のようになります。

f:id:hippy-hikky:20190410002523p:plain
生存種子数のモデル(Kruschkeのダイアグラム)

個体差r_i全体を統括するハイパーパラメータを、個体に関係なく共通のパラメータsとして定義します。 これは先に記したように、植物群の個体差がどの程度あるのかを規定するパラメータです。

各パラメータの事後分布は以下の通りに推定されました。

f:id:hippy-hikky:20190410002721p:plain
MCMCサンプリングの結果。上段が個体差の大きさを示すパラメータs、中段が各個体のr_i、下段が共通のパラメータ\beta。左列がヒストグラムKDE)、右列がサンプル系列。

\betasの事後分布を見てみると、書籍内の事後分布と概ね同じような値であることがわかります。 この結果(事後分布)を利用して、生存種子数のシミュレーションをした結果を以下に示します。

f:id:hippy-hikky:20190410003142p:plain
生存種子数のシミュレーション結果。青線が元のデータ。オレンジが推定値。

推定した事後分布を利用して100個体それぞれから10セットサンプルし、平均値をプロットしています。 推定値がデータとよく合っているであろうことがわかります。

ベイズモデルで使う事前分布

本書籍ではここまで、「事前分布」についてはあまり深く説明されてきませんでした。 本記事では、事前分布とはデータが無い時のパラメータに対する信念を表現するものだと書きましたが、 この信念が大きく間違っていると推定に悪影響が現れます。 極端な例では、事前分布で確率を0とした値の範囲には事後分布が現れません*4。 このような極端な例ではなくても、事前分布がずれていると、合理的な事後分布を推定するためにたくさんのデータが必要になってしまいます。

本書籍では、このように事前分布の選択はベイズモデリングにおいて重要であるため、 主観的な事前分布は使う必要がないと述べてられています。 基本的には無情報事前分布を使えば良いと書かれています。 しかし、上記の種子の生存確率の個体差のような問題の場合、 個体差r_iの事前分布に無情報事前分布を利用するということは、各個体のそれぞれを独立に推定していることになるため、 統計モデリングとしては望ましくありません。 そのため、このような場合には階層事前分布を設定することモデルとしては好ましいでしょう(と書籍内に記載されています)。

階層事前分布を使用するべきなのか無情報事前分布を使用するべきなのかについては、 本書籍で「パラメータがデータのどの範囲を説明するのかに依存する」と主張されています。 同じようなパラメータが少数で大域的に影響するパラメータ(上記の\betaのようなパラメータ)には無情報事前分布を使い、 同じようなパラメータが多数で局所的に影響するパラメータ(上記の個体差r_i)には階層事前分布を利用するべきとされています。 局所的なパラメータは、独立に推定してしまうと、データに過適合してしまう恐れがありますから、 階層事前分布で正則化することは尤もなやり方でしょう。

なお私は、主観的な事前分布も場合によっては使うべきだと考えています。 データが少ない場合で、且つ、問題に対しての深い知識/常識的な知識がある場合には、 積極的にパラメータの範囲を拘束するべきと考えています。 データの範囲を拘束することで、データが少なくてもリーズナブルな事後分布を得られる場合があるためです*5

【トップに戻る】

まとめ

以上本記事では、「データ分析のための統計モデリング」の9,10章をまとめてきました。

第9章では、一般化線形モデル(GLM)をベイズモデリングとして書き直しました。 第4章の最尤法での計算結果と異なり、ベイズモデリングの結果(パラメータの推定結果)は事後分布で与えられるのでした。

第10章では、一般化線形混合モデル(GLMM)をベイズモデル化しました。 GLMMをベイズモデル化すると、階層ベイズモデルと呼ばれるモデルになります。 具体的には、種子の個体差を含めたモデルを構築してみました。

また、事前分布の選択として、主観的事前分布、無情報事前分布、階層事前分布のどれを選択すべきかについて、一つの基準が示されました。 本書籍では、無情報事前分布、階層事前分布をパラメータが説明する範囲に応じて使い分ければ良いとされています。

【トップに戻る】

終わりに

ここまで3回にわたって「データ解析のための統計モデリング入門」の読後メモを記してきました。 本書は、GLMに対象を絞っており、例題をベースにしているのでとても読みやすいと思います。

GLMは実務で多く利用されていると思いますが、RやPythonのライブラリを単純に叩けば一応の答えは返ってきます*6。 しかし、内部を知らないで使うことで、モデル(確率分布)の選択が問題に適していないといったケースもあると想像します(実際目にしてきました)。

データ分析を行う上では、本書籍の範囲は一応知っておくことが最低限必要なのかなと思います。

【トップに戻る】

参考文献

パターン認識と機械学習 上

パターン認識と機械学習 上

ベイズモデルと最尤法の違いが詳しく説明されていたりと非常に参考になります。 ちょっと難しいですが。

Pythonによるベイズ統計モデリング: PyMCでのデータ分析実践ガイド

Pythonによるベイズ統計モデリング: PyMCでのデータ分析実践ガイド

PythonのPPLであるPyMC3について、事例をベースにした書籍。 PyMCでモデリングをする際に参考になります。

*1:本書籍でもベイズについて詳しくは別に紹介している書籍を読んでとなっています。本書籍の趣旨からしてあまりここを深く掘り下げる必要は無いのでしょう。

*2:PRMLの第1章では、ベイズ推定は事前分布を用いることで正則化しているとみなせると記載されています。こっちの方がわかりやすいですね。

*3:分散はもう少し大きくてもよかったかも

*4:事後分布は尤度と事前分布の積に比例するので

*5:データが多ければ無情報事前分布を積極的に使うべきですし、ドメイン知識が潤沢でない場合にも無情報事前分布を使うべきです

*6:ロジスティック回帰などは「GLM」と意識せずに使われているケースもあるでしょう