作って遊ぶ機械学習。

~基礎的な確率モデルから最新の機械学習技術まで~

データに欠損がある場合の教師あり学習

おはようございます.

今回は教師あり学習モデルを題材に,入力データが欠損している場合のベイズ流の対処法を解説します.ベイズモデルというと,たいていの場合は事前分布の設定の仕方云々だとか,過学習を抑制できるだとかに議論が注目されがちですが,個人的には,パラメータや潜在変数を推論することとまったく同じ枠組みで欠損値も同時に推論できることが,実用上非常に便利なベイズの特性だと思っています.

 

データの欠損部分の取扱い

データに欠損部分が存在することはよくあります.センサーデータを解析する際は,ネットワークの状況やデバイスの不具合によってデータの一部が欠けた状態で上がってくることがあります.スマホから複数種類のデータを集めるといった状況を考えてみると,例えば加速度センサーの値は継続的に取得できたとしていても,GPSの位置情報はほとんど上がってこないといった場合もあるかと思います.また,何かしらのユーザーのアンケートデータを利用した予測を行う場合は,収集したアンケートに未記入項目が出てしまうのはごく自然でしょう.

ナイーブな対処方法としては次の2つ考えられます.1つめとしては,あるデータの一部が欠損している場合は,そのデータごと解析の対称から外してしまうことです.しかし,これは貴重なデータを使わずに捨ててしまっていることになるので,よほどデータ量が潤沢にない限りは非常にもったいないやり方になります.また,継続的に観測される時系列データなどを取り扱う場合には,そもそもうかつにデータを削除することすらできません.2つめの対処法としては,予測アルゴリズムを適用する前に,前処理として線形補間や平均値の当てはめなどを行って欠損を埋めてしまうことです.しかし,こちらの方法も問題があり,前処理で欠損を埋めてしまうと,後段の予測アルゴリズムは受け取ったデータの中の実際に観測された部分と補間された部分の違いが区別できないため,誤った推定結果を出してしまうことになります*1

ベイズの枠組みで確率的な推論を行えば,データを使った予測と欠損値の補間を同時に行うことができます.補間値に対する不確実性も見積もることもできるため,誤った補間による予測性能の劣化や過学習も基本的には起きません.

 

ベイズロジスティック回帰

さて,ここではベイズロジスティック回帰を例にいわゆる「教師あり学習」のモデルをおさらいしたいと思います*2.ロジスティック回帰は,多次元の実数値入力データを2値に分類するようなモデルです.入力データ(説明変数)をX,出力データ(目的変数)をY,さらにパラメータをwとすれば,N個のデータに対する同時分布は次のようにモデル化されます*3

f:id:sammy-suyama:20170830214813p:plain

ただし,式(1)のそれぞれの分布は次のようになっています.

f:id:sammy-suyama:20170830214830p:plain

式(2)のσはシグモイド関数で,中身の実数値を0から1までの間に押し込める役割を担っています.式(3)ではwの事前分布にガウス分布を仮定しています.

このモデルから,下記のパラメータの事後分布に関する特性(平均や分散など)を得ることが,ベイズロジスティック回帰における「学習」にあたります.

f:id:sammy-suyama:20170830214850p:plain

式(4)の事後分布はロジスティック回帰の場合では解析可能な表現形式が得られません.ですので,変分ベイズによって何かしらのシンプルな分布で近似をするか,MCMCを使って大量のサンプルを取得することによって平均や分散などを調べる必要があります.

 

入力データに欠損値がある場合

ここからが本題です.今回は入力データXの一部を,パラメータwと同じようなやり方で推論する必要があるので,次のようにXに対しても事前分布を置いてあげる必要があります*4

f:id:sammy-suyama:20170830215000p:plain

また,ここでは,入力データセットXの任意の部分が欠損しているような状況を考えることにします.あるn番めのデータx_nは,要素の一部が欠損していてもいいですし,まるごと全部無くなっている状態でもOKです.データセットをX={Xo,Xm}のように,観測部分Xoと欠損部分Xmに分解して書けば,求めたい事後分布は次のようになります.

f:id:sammy-suyama:20170830215059p:plain

あとは欠損値がなかった場合と同じように,何かしらの近似推論手法を使って式(7)の事後分布の特性を調べてやればOKです.

 

実験

さて,簡単な2次元のトイデータを使って欠損値補間付きベイズロジスティック回帰の動作を確認してみます.ここでは入力データの次元数をD=2,データ数をN=30とします.また,入力データはそれぞれの要素が50%の割合で欠損しています.今回はスケールの小さい簡単な問題ですので,MCMCの1つであるMetropolis-Hastings法を使用して学習しています.

2クラス分類を行うと,次のような「平均確率の等高線」を描くことができます.

f:id:sammy-suyama:20170830023317p:plain

(左図)すべての次元がそろっている場合のデータのみを使った予測結果になります.今回の場合はN=10個のみを使用し,残り20個は捨ててしまった上で学習しています.

(中央図)今回の欠損値補間の方法を用いて,欠損値(×印)を補間推定しながら予測を行った結果です.

(右図)欠損が一切なかった場合の予測結果で,いわば今回の「正解」の予測分布になります.

結果から分かるように,左図では欠損のあるデータを捨ててしまっているので,右図の正解とはほど遠い予測結果になってしまっています.中央図ではx印の点が欠損値を持つデータの推定位置(平均)を表しており,薄い棒はサンプルから計算された推定位置の偏差を表しています.青・赤それぞれのクラスがなんとなくまとまるように配置されている様子が分かりますね.中央図と右図はかなり近い形状の等高線(予測確率)になっており,欠損のあるデータをうまく利活用した方が,データが完全に観測された場合の予測に近づいている様子がわかります

 

まとめ

さて,今回の話を簡単にまとめてみます.

1,データは使えるだけ使った方が良い.

データを捨てるのはもったいないですアルゴリズムの実装コストや計算コストなどともよく相談する必要がありますが,なるべくなら余計な前処理などせず,上手に単一のモデルから推論できた方が望ましいでしょう.ただし,データの欠損値補間をもっと真剣にやるのであれば,今回のような教師ありモデルを使わずに,生成モデルによってしっかりXをモデル化した方が良いかもしれません.

2,ベイズの枠組みでは,欠損値もパラメータと同様に確率推論を行う.

推定したい値はすべて確率変数として扱う」のがベイズの基本です.したがって,教師あり学習を普通に使うときは存在を意識する必要はありませんでしたが,入力の欠損値を推論したい場合は今回のように事前分布を明示的に導入することになります.また,欠損値を確率推論できるようにしておけば,前処理や例外処理をあれこれ実装する手間もなくなります.今回のアルゴリズムであれば,極端な場合入力Xがすべて欠損だったとしても「うまく予測できませんでした」という予測結果が返ってくるだけで,バグになることはありません*5

3,欠損値の補間を行っても過学習はしない.

ベイズにはそもそも「過学習」という概念すらないので,これはかなりナンセンスな言い方ではあります.仮に,ベイズの代わりに最尤推定を用いて欠損値を推定した場合,尤度を向上させるために際限なく「都合の良い」Xmを求めてしまいます.これは推定というよりも「データの捏造」に近いため,当然ながら新規データに対する汎化性能は期待できません.

 

今回の実験を行ったソースコード(Julia実装)は下記にあります.(logistic_regression_intrp.jl)

MLBlog/src at master · sammy-suyama/MLBlog · GitHub

 

今回の記事がよくわからん!という方には,次のような入門書もあります.

books.rakuten.co.jp

*1:僕の経験上最悪のデータは,欠損部分がすでに0で埋められているというものでした.どこが欠損していたかの情報もなかったため,観測値として本当に0なのか,欠損のため0なのか,まったく検討がつきませんでした.

*2:ちなみに,個人的には「教師あり」だとか「教師なし」だとかっていう区別はあんまり本質的ではないと思っています.

*3:ちなみに,個人的には「説明変数」だとか「目的変数」だとかっていう区別はあんまり本質的ではないと思っています. 

*4:欠損値がない場合でもXに事前分布を置いても構いませんが,Xがすべて完全に与えられている状況では,結果としてXの事前分布はwの事後分布やyの予測には一切の影響を与えないことが分かります(グラフィカルモデルの記事を参照ください).

*5:より正確に言うと,事前分布の情報のみを使った大雑把な予測を出力してくれます.

変分ベイズを使って変化点検知をしてみる

おつかれさまです.今回は簡単なメッセージ受信数のデータを使って,変分ベイズによる変化点検知をやってみたいと思います.なお,今回使うデータやモデルは下記のPyMCの入門書を参考にしています*1.

Pythonで体験するベイズ推論-PyMCによるMCMC入門-キャメロン-デビッドソン-ピロン

この本では推論にMCMCを使っていますが,今回はモデルはそのまま流用し,同じことを実現する変分ベイズによる近似推論を導いてみます. 一般的には変分ベイズの方が計算が高速なので,MCMCの性能に満足できない場合などは変分ベイズは良い代替手法になり得ます.また,今回紹介する例は,過去に紹介した混合モデルを使った例よりも比較的シンプルですので,変分ベイズの入門題材にはちょうど良いんじゃないかと思っています.

MCMCによる変化点検知

・メッセージ受信データ

PyMC本では次のような「ある期間で受信したメール数」を題材にMCMCを解説しています.

f:id:sammy-suyama:20170819131110p:plain

データをよーく見てみると,非常に微妙ではありますが,経過日数の後半の方で受信メッセージ数が少し多くなっているような傾向が見えます.この変化点をベイズモデリングによって見つけるのが目標です.

・モデル

n日目のメッセージ受信数Cnはカウントデータなので,次のようなポアソン分布を使ってモデル化するのが良いでしょう.

f:id:sammy-suyama:20170819164730p:plain:w180

ここで,λはポアソン分布の平均パラメータです.また,次のようにある{\tau}日目を境にこの平均パラメータが変化することを仮定します.

f:id:sammy-suyama:20170819164811p:plain:w220

それぞれのパラメータλ1およびλ2はポアソン分布の共役事前分布であるガンマ分布を使ってモデル化します*2

f:id:sammy-suyama:20170819164827p:plain:w200

PyMC本ではデータの平均値を使って超パラメータを設定していますが,あんまりおすすめしません. 僕は適当にa,bの値を設定した後にモデルからデータをサンプルしてみて,なんとなくスケール観が合ってそうな値(a=2.0, b=0.1)に設定しておきました.

最後に,変化点は次のように全部でN日の中から等確率で選ばれると仮定します.

f:id:sammy-suyama:20170819180159p:plain:w200

MCMCによる推論

詳しくは本やJupyter Notebookの内容を参考にしてほしいのですが,モデル(model)をPyMCで構築した後に次のようなコードを書くと事後分布からのサンプルが得られます.

iters = 40000
burn = 10000
mcmc = pm.MCMC(model)
mcmc.sample(iters, burn)

mcmc.sampleを叩いたあと,数秒待つと,各変数のサンプルが取り出せます.

lambda_1_samples = mcmc.trace("lambda_1")[:]
lambda_2_samples = mcmc.trace("lambda_2")[:]
tau_samples = mcmc.trace("tau")[:]

得られたサンプルを元に各種期待値を計算すると,次のようになりました. f:id:sammy-suyama:20170819140519p:plain 上図ではサンプルから計算される各日のλの期待値をプロットしています.下図では,各日におけるτの近似事後確率を示しています. 確かに,45日目あたりを境に,メッセージ受信数の傾向が微増していることが示唆されていますね.ちなみに,iters=5000より小さい値を設定すると,あんまり綺麗な分布は得られませんでした.

変分ベイズによる変化点検知

・変分ベイズ(平均場近似版)の概要

平均場近似による変分ベイズの導出方法を簡単におさらいしましょう.データXを観測したあとの潜在変数(パラメータ含む)Z1,Z2の事後分布を次のように近似するとします.

f:id:sammy-suyama:20170819164956p:plain:w300

Z1,Z2の事後分布を同時分布として表現することは諦め,よりシンプルな独立の分布qで近似しようというのがアイデアです.近似分布qを真の分布に「似せる」ために,次のようなKLダイバージェンスをqに関して最小化します.

f:id:sammy-suyama:20170819175656p:plain:w320

詳しくはこちらの記事に書いてありますが,結果としては次のような式を繰り返し計算すればKLダイバージェンスが徐々に小さくなっていくことになります.

f:id:sammy-suyama:20170819192537p:plain:w440

今回はこの結果をそのまま使って,変分ベイズアルゴリズムを導出します.

・更新アルゴリズムの導出

さて,先ほどのメッセージ受信数の変化モデルから,変分ベイズを導いてみることにしましょう.次のように,少しだけモデルを計算しやすく書き直してみます.

f:id:sammy-suyama:20170819175915p:plain:w800

ここで,δ()は中身が真の場合は1を返し,そうでない場合は0を返すような関数です.τの値によってデータがサンプルされる分布が切り替わるイメージですね.

次に,このモデルの事後分布の分解を次のように仮定します.

f:id:sammy-suyama:20170819170354p:plain:w350

ここまで決めてしまえば,あとは機械的に計算をするだけです.λ1の近似事後分布は,

f:id:sammy-suyama:20170819170437p:plain:w550

となるので,

f:id:sammy-suyama:20170819170547p:plain:w270

f:id:sammy-suyama:20170819170654p:plain:w350

とガンマ分布で表現出来ます.λ2もまったく同様に,

f:id:sammy-suyama:20170819170720p:plain:w270

f:id:sammy-suyama:20170819170741p:plain:w350

となります. 次にτの近似事後分布は,

f:id:sammy-suyama:20170819170917p:plain:w520

となるので,次のような離散分布になります.

f:id:sammy-suyama:20170819170949p:plain:w470

また,近似事後分布がガンマ分布と離散分布(カテゴリ分布)であることがわかったので,途中計算に必要な期待値も次のように求められます.

f:id:sammy-suyama:20170819181549p:plain:w320

・動かしてみる

さて,先ほどのアルゴリズムを使って事後分布を推定した結果は次のようになります, f:id:sammy-suyama:20170819194208p:plain PyMCで十分なサンプル数で実行した場合とほとんど同じ結果になりましたね.ただ,変分ベイズの場合はこの近似分布を得るまでにMAXITER=5程度でほぼ完全に収束し,計算時間も一瞬でした.

せっかくなので,適当に作ったトイデータで同じように推論してみます. f:id:sammy-suyama:20170819194246p:plain 上図からわかるように,変化点がはっきり見えているようなデータなので,下図ではアルゴリズムも確率ほぼ1.0という強い自信を持って変化日が50日目だと言っていますね.

データを作り直してもう1回やってみましょう. f:id:sammy-suyama:20170819194505p:plain このデータはちょっと意地悪だったかもしれません.データからはまったく変化点を見ることが出来ません. 下図の結果では「どこかが変化日だったのかわかりません」と言っています.なかなか良い答えです.無理くりどこかを予測結果として出されるより,よっぽど紳士的ですね*3

Juliaで実装したソースコードは下記に置いてあります.(change_point.jl)

MLBlog/src at master · sammy-suyama/MLBlog · GitHub

ということで,本日は以上です.

*1:英語になっちゃいますが,本の内容とほぼ同じJupyter Notebookがあります. https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers

*2:PyMC本では指数分布を使っていますが,ガンマ分布でa=1とおけば指数分布に一致します.

*3:今回のモデルは,「変化点は確実に1つあるんだけど,どこかわからない」という前提のもとで推論をする話になっています.最後の結果は「変化点はありませんでした」とは違うことに注意してください.

ベイズ学習の勉強に参考になる資料

おつかれさまです.今回はタイトルの通り,ベイズ学習を勉強する上で参考になる教科書やウェブの資料,論文等を紹介したいと思います.

 

ベイズ学習は確率推論に基づいた機械学習アルゴリズムの構築論です.ベイズ学習を使えば,あらゆる形式のデータに対して,未観測値の予測や隠れた構造を発見するための統一的なアプローチをとることができるため,特に現代の機械学習アルゴリズムを深く理解し使いこなすためには必須の方法論になっています.


1, ベイズ学習の位置づけ

まず,データサイエンスにおける他の方法論と,ベイズ学習の位置づけを簡単に俯瞰したいと思います.

 

僕の知る限り,ベイズ学習は1990年代ごろから登場してきた機械学習の方法論で,既存の学習アルゴリズム確率モデルによって構築し,学習や予測の計算をすべて確率推論(条件付き分布と周辺分布の計算)で解決してしまおうという試みによってはじまりました.これにより,従来の学習アルゴリズムの問題点だった過学習,次元の呪いなどをうまく解決できる(あるいは,問題ですらなかった)ことがわかりました.また,既存の手法がベイズ学習の極めて特別な場合であるとして再定義出来ることが多く,k-means,サポートベクターマシンニューラルネットワーク,主成分分析などなど,数え上げればキリがないですが,これらはすべて確率モデルとして再構築でき,従来の学習方法のほとんどは対応する確率モデルに対する特別な近似推論であることが示せます.

 

ちなみに,最近では深層学習の各種の問題点(大量のデータを必要とする,過学習する,不確実性をハンドル出来ない,ニセのデータに騙される)などをベイズ学習の手法でエレガントに解決する方法が提案され始めているほか,深層学習の各種の計算テクニック(ドロップアウトなど)も実はベイズ学習の近似推論計算であったりすることが発見されています.また,次の動画が参考になりますが,深層学習はベイジアンの目からは「高次元データの多層構造による表現を学習する方法」とされており,グラフィカルモデル*1で表現可能なモデルの一つであるという認識になっています.

www.youtube.com

 

さて,すべての未知の値の予測を確率計算のみで行ってしまおうというのがいわゆるベイズ主義とされていますが*2,その反対は頻度主義と呼ばれています.したがって,データ解析の分野を俯瞰すれば,「頻度主義 or ベイズ主義」×「統計学 or 機械学習」の組み合わせでおおよそコミュニティが分類できるようです.統計学機械学習の違いは微妙ですが,機械学習の場合は画像や音声などを含めたより複雑な構造のデータを解析対象にする傾向があり,それに伴ってコンピュータを使った効率的な計算の実行に焦点が置かれているようです.頻度主義,ベイズ主義の違いをここでは深入りして説明することはしませんが,興味のある方は下記の動画が参考になると思います.

www.youtube.com

 

次にベイズ学習に関連する資料をいくつか挙げていきますが,参考書(PRMLとか)によってはベイズ主義と頻度主義がごちゃごちゃに混ざっている場合があるので,内容を理解するためには十分注意した方が良いでしょう.

 

2, ベイズ学習を勉強するためのお勧め資料

前置きが長くなってしまいましたが,ここでは主にベイズ学習(ベイズ主義機械学習)を勉強する際に参考になる資料を紹介します.

 

PRML

Pattern Recognition and Machine Learning | Christopher Bishop | Springer

Chris Bishopによるベイズ学習の決定版の教科書です.とはいえ,機械学習全体をある程度俯瞰するためにも作られたためか,ベイズではない手法も半分くらい混じっています.次に挙げる章が特に重要です.

  • 1,2章の確率計算に関する基本
  • 3,4章の回帰・識別の基本
  • 8章のグラフィカルモデル
  • 9章の混合モデル
  • 10,11章の近似推論・サンプリング手法

10章の変分推論が理解できれば,12,13章の各種潜在変数モデルを参考にするよりも,後述のBealの博士論文の方が良いと思います.また,ガウス過程(カーネル)の話もRasmussenのテキストの方が詳しいです.

 

・BDA

Home page for the book, "Bayesian Data Analysis"

Andrew Gelmanらによるベイズ統計の定番書籍です.統計学の本ですが,各種の確率分布の使い方が解説されているのはもちろん,後半の章では次のような機械学習に深く関連する話題がたくさんあります.

  • 12章のMCMC,13章の確率分布の近似
  • 21章のガウス過程,23章のディリクレ過程

  • etc...

 

・Machine Learning: A Probabilistic Perspective

Machine Learning | The MIT Press

Kevin Murphyによる,現在出版されている中でも最も網羅的な機械学習の解説書です.ページ数が1000を越えているので,これを使って勉強しようっていう人はあんまりいないと思います.リファレンス的に使うのが良く,僕も崩壊型ギブスサンプリングの解説記事を書くときとかはこの本を参考にしました.

 

・BRML

David Barber : Brml - Home Page browse

Bayesian Reasoning and Machine Learningの略です.なぜかウェブでフルバージョンのPDFがダウンロード出来ます.

 

・GPML

Gaussian Processes for Machine Learning: Book webpage

Carl Edward Rasmussenらによるガウス過程の解説書です.

 

The Matrix Cookbook

The Matrix Cookbook

ベイズとは直接関係ないですが,行列の展開や微分計算などの便利な公式がたくさん載っています.

 

・Variational Algorithms for Approximate Bayesian Inference

Matthew J. Beal - Thesis: Matthew J. Beal, Variational Algorithms for Approximate Bayesian Inference

隠れマルコフモデル等に対する変分推論の解説記事として良くまとまっています. 

 

・Introduction to Probabilistic Topic Models

http://menome.com/wp/wp-content/uploads/2014/12/Blei2011.pdf

トピックモデルのみの短い解説記事ですが,実際の課題に対してどのように確率モデルを構築・拡張するのか簡単に俯瞰できる内容になっています.

 

・Nonparametric Bayes Tutorial

http://stat.columbia.edu/~porbanz/npb-tutorial.html

ベイジアンノンパラメトリクスに関する解説記事・論文が網羅されています.

 

・Probabilistic Modelling and Bayesian Inference

http://mlss.tuebingen.mpg.de/2013/2013/Ghahramani_slides1.pdf

ベイズ学習の解説スライドで,基本的な思想や利点などが説明されています.

 

まとめ

以上の教科書や解説記事は,それぞれの分野のパイオニアたちが執筆した極めて品質の高い資料であるため,アルゴリズムを開発したり調べ物をする際にはとても参考になると思います.他にも秀逸な記事がありましたらご提案いただけたらと思います.

ただし,ここまで色々挙げといてあれですが,最も大事なことはここで挙げた教科書等を100%完璧に理解してやろうなどと思わないことです.正直なところ,僕も紹介した参考文献の10%~20%くらいしかちゃんと読んでいない気がします.最も効率的なやり方は,業務や研究活動で実際に直面している課題に合わせて,基礎内容の勉強,応用事例の調査,実装と動作の確認をバランス良く繰り返していくことです.そのような実務的なプロセスを通すことによって,アルゴリズム開発者の抱える多くの「がしたい!」にとことん応えてくれるベイズ学習の包容力に気づかされることになると思います.

日本語で書かれた参考文献がほしい!という方には,次のような入門書もあります.

books.rakuten.co.jp

*1:参考:グラフィカルモデルによる確率モデル設計の基本 - 作って遊ぶ機械学習。

*2:単純にベイズの定理を使うことが「ベイズ主義」ではないので注意してください.例えばナイーブベイズとかベイジアンネットワークは,ベイズ主義的な方法で扱われないことが多いようです.

実践!ベイズ学習

今回は、実問題を解くためのベイズ学習による機械学習アルゴリズムの構築方法に関してざっくり俯瞰してみたいと思います。ここで解説するフローは僕が実問題にアプローチする際に意識しているものですが、おそらくこれはベイズ学習のみならず、広く一般的な統計モデリング機械学習の問題解決にも適用できると思います。

 

 <アルゴリズムの開発フロー>

f:id:sammy-suyama:20161219140751p:plainあまりファンシーな図でなくて申し訳ないですが、これから1つ1つの項目と各々の遷移に関して説明していきます。

 

1、データ・課題の整理をする

まず、機械学習を使って解きたい問題や実現したいサービスを定義してみます。データはあるんだけど何をして良いかわからない、という場合もあるかもしれませんが、そういうときでもとりあえず何かしらの目標を仮置きしてみるのが良いかと思います。基本的に機械学習でできることは「見えない情報の予測」であると考えればアイデアが発想しやすいかもしれません。未来の株価の予測、画像や音声の判別、欠損データの補間、異常値の特定など、これらはすべて未知の事象に対する予測問題として定義することができます。*1

課題が決まれば、次第に必要なデータは明らかになってきます。例えば、明日の東京都全体の電力需要を予測したいのであれば、過去の需要データに加え、その日の天気や曜日の情報(平日or休日)なども予測に役に立つでしょうし、その日に起こる予定のイベントとかも考慮しておいた方が良いかもしれません。この辺りはデータの収集コストと相談する必要もあるかと思います。また、データそのものの収集に伴って、データに関する周辺的な知識(よく知られた法則、物理的な制約など)も色々仕入れておけば、後のモデル構築の段階に役立てられる可能性が高いです。
また、集めたデータの形式や粒度がバラバラだったりする場合はこの時点で揃えておくのが良いかもしれません。ただし、欠損値の補間や異常値の除去、データサイズの補正などのいわゆる「前処理」をここで行ってしまうと、後段のアルゴリズムに対する情報欠損に繋がる可能性があります。手間とコストを十分に考慮する必要がありますが、理想的には、これらの処理はモデルと推論(2および3)で行う方が良いです。

 

2、モデルを構築する

f:id:sammy-suyama:20161219202632p:plain

ここでは確率モデルP(X, Θ)の構築を行います(XがデータでΘが学習したいパラメータ)。基本的なアプローチとしては、「今手元にあるデータXは一体どういうプロセスを経て生成されたのか?*2」ということを念頭に置き、基本的な確率分布を組み合わせてモデルを構築します。

持っているデータの種類によってもモデル構築の仕方が大きく変わってきます。例えばラベルデータを十分に持っているのであれば、既存の教師ありの識別モデル(線形回帰、ロジスティック回帰、ガウス過程など)をそのまま使うのでも良いかもしれません。*3

最も大事なことは、この段階でデータをよく観察し、普遍的な性質や特徴を整理することです。そのような知見をどれだけモデルに組み込むことが出来るかが、未知の値を予測するにあたって非常に重要になってきます。ちなみに、生データに対して何かしらの特徴量抽出を行うやり方も手軽ですが、このような段階を踏んだ情報処理の過程にしてしまうと、その都度情報欠損が起きてしまう可能性があることに注意してください。これを防ぐには、特徴量抽出のプロセスも確率モデルとして組み込むのが理想的です。

さらに、確率モデルを構築した後に必ずやってほしいことは、モデルP(X, Θ)から仮想的にデータXをサンプル(シミュレート)してみることです。このサンプルが、我々が実データを学習させる前に持っている「仮説」を具体的に表していることになります。例えば、データXとして成人男性の身長を仮定しているのに、モデルからサンプルしてみた値が0 cm近辺にへばりついたちっさい値しか出てこないとかいう場合は、明らかにモデル自体か事前分布の設定等が誤っています。モデルからのサンプルが実際に発生し得るデータをちゃんとカバーできそうかどうか、次の推論導出に進む前にチェックしておくのが大事です(「作ったモデルでもっと遊んでね」と僕は表現します)。

 

3、事後分布を計算する(推論を実行する)

前ステップで構築したモデルをもとに、事後分布P(Θ|X)を評価します。

伝統的な確率推論に対して、機械学習機械学習たらしめているのはおそらく取り扱う確率モデルの複雑さにあると思います。多くの問題では事後分布が解析的に得られず、推論アルゴリズムを導いてコンピュータ上で実行することになります。具体的にはMCMCや変分近似などの近似推論アルゴリズムを導出してPython等の適当な言語で実装するほか、モデルがそれほど複雑でないのであればStanなどのツールを使って自動的に推論してもらうという手もあります。
また、多くの機械学習の課題では、ただパラメータの事後分布を計算するだけを目標とするということはあまりないでしょう。例えば未来の値X*を予測したい場合は、学習された事後分布を使って予測分布P(X*|X)=ΣP(X*, Θ|X)を評価することになると思います。あるいは、クラスタリングなどの「観測することのできない潜在的な値を推定する」問題では、潜在変数モデルP(X,Z,Θ)に対する潜在変数の事後分布P(Z|X)を計算することになります。

ところで、このステップでは多くのバグに苦しむことになります。手で導出した推論アルゴリズムがきちんと動作しているか確認する方法はいくつかあり、一番のオススメとしては、いきなり実データに挑戦せずに、学習前のモデルから仮想的にサンプルしたデータを改めて訓練データとして使って推論させてみることです。このようにすればデータに対するモデルは100%正しいことが保証されるので、推論アルゴリズムの導出式や実装のバグのチェックのみに集中することできます。また他には、例えば変分ベイズ法などの特定の方法では、変分下限と呼ばれる値を評価することにより(ある程度は)動作の正当性を確認できます。

モデル構築および近似推論に関する関連記事は例えば次のようなものがあります。

グラフィカルモデルによる確率モデル設計の基本 - 作って遊ぶ機械学習。

ベイズ混合モデルにおける近似推論① ~変分近似~ - 作って遊ぶ機械学習。 

 

4、結果の評価を行う

f:id:sammy-suyama:20161219201611p:plain

作ったアルゴリズムが所望の動作を実現しているか、あるいは改良がうまくいっているかを評価します。モデル自体を評価するような指標(周辺尤度、BICAICなど)もありますが、基本的には今解いている課題に即した評価手法を使うのが自然かと思います。例えば連続値の予測であれば二乗誤差で評価するのが(ベストかどうかはともかく)簡単ですし、低頻度のイベントを検知するような課題であればF値を使うのが良いかもしれません。ただし、結果の1%や2%を競うような数値評価至上主義*4に陥らないように注意してください。また、見落としがちではありますが、実際のところ機械学習を使ったサービスなどでは視覚的に結果の良し悪しを確認したり、自分でサービスを使ってみて感触を確かめる、というのも重要な評価手段の1つになります。

それに伴って、アルゴリズムの計算効率(メモリ量や計算速度など)も合わせて評価するのが重要です。というのも、最適化やサンプリングに基づく多くの機械学習アルゴリズムは、時間をかければかけるほど最終的な性能が高くなるものが多く、計算コストを無視した推定精度のみの評価はほとんどの場合では不十分になるためです。

また、機械学習の課題で訓練データとテストデータを分けて評価するのは必須だと思われます(クロスバリデーションなど)。これは過学習をしていないかチェックするための超基本手段なのですが、意外にちゃんとやっていない人が多くてびっくりです。ちなみに「ベイズ学習はそもそも過学習をしないので、データを分けなくても評価できる」という主張もありますが、現実的に多くの場合では近似アルゴリズムを推論に使うことになるので、オーバーフィットもアンダーフィットも起こり得ます。なるべく本番環境に近い状態で評価するためには、やはりテストデータに対する課題依存の評価指標を設定するのが無難かと思います。

確率モデルを使った機械学習アルゴリズムでは、得られた事後分布から仮想的にデータをサンプルしてみるのも学習がうまくいったか直観的にチェックするポイントになります。例えば、顔画像Xを学習する問題を考えてみましょう。事前分布P(Θ)をもとにP(X|Θ)からデータをサンプルしてみると初めはぐちゃぐちゃなノイズしか出てこなかったのが、学習された事後分布P(Θ|X)をもとにサンプルした場合は「顔っぽい」データがちゃんと生成できるようになっているはずです。これがうまくいかない場合は、モデルの表現能力に問題があるか、訓練データ数が少ないか、あるいは推論アルゴリズムの性能が十分でない可能性があります。

 

よく起こる遷移

・推論導出からモデルの構築(3→2)

2で構築したモデルが奇怪すぎて推論アルゴリズムがうまく導けない場合があります。
それでも無理やり追加の近似などを仮定してアルゴリズムをひねり出すこともできますが、多くの場合は性能がよくなりません。モデルの構築と推論の導出は分けられたプロセスとして認識すべきですが、実際は相互に行き来しながら一番良い組み合わせを探していくことになります。

・性能評価から推論の再導出(4→3)

アルゴリズムの導出はうまくいっているはずなのに、実データに対して思うような性能が出ない場合は、推論アルゴリズムを再検討してみる必要があります。具体的には、必要メモリ数があまりにも多すぎた場合などは、学習アルゴリズムをオンライン化(Stochastic Gradient Descentなど)してデータを小分けに出来るようにするなどが考えられます。他にも、例えばMCMCが遅すぎる場合は変分近似を使ってみる方が良いかもしれません。

・性能評価からモデルの構築(4→2)
実験結果を眺めることにより、「うまくモデル化できていない特徴」というのが見えてくる場合があります。この場合は2に戻って、新しい特徴をモデルに組み込むことが必要になってきます。例えば、データに明らかに時間的依存性があることがわかった場合は、モデルをマルコフモデルにするなどの手段が考えられます。

逆に、作ったモデルが複雑すぎるために推論アルゴリズムの性能が出ていない可能性もあります。こういう場合は、ちょっと悔しいですが、モデルから余計な要素を切り落としてシンプル化するのもアリなんじゃないかと思います。

・性能評価から課題の設定(4→1)
評価結果が思わしくない場合は、データの量や質に関する問題に着目するか、あるいは課題自体を検討しなおしてみるのが良いかもしれません。実際、4の段階にまで入ると、データに関する知識やアルゴリズムの計算コストなども最初の頃よりだいぶ頭に入ってきているはずなので、実運用に基づいた課題の再設定などは積極的に検討すべきなのではないかと思います。

 

- - -

以上、思いつくままにバァーッと書いてしまいましたが、少しでもベイズ学習あるいは確率モデルによる機械学習構築を検討される際に参考になればと思います。

 

 

*1:他にもデータの圧縮、ノイズの除去なども確率モデルの得意とするところです。

*2:いやいや、深層学習とか認識系の課題であれば「データがどういうプロセスを経て認識されたのか」の方が正しいでしょ、とおっしゃる方もいるかもしれません。その場合は、人間が与えるラベルデータが「どのような認識的な処理過程を経て生成されたのか」をモデル化する、と考えれば、文中の言い方でも悪くない気がします。

*3:ところで「教師あり」というのはつまり、「予測したい値と同質と思われるデータを学習用に持っている」とした場合の機械学習の実装方法だと解釈できます。つまり、解きたい実課題自体が教師ありだとか教師なしだとか言うのはナンセンスで、アルゴリズムを開発する人間がその課題をどう捉えるかに依る、というのが正しいと思います。

*4:定量評価というものは、実現したい目標を理解しやすく数値に要約したもの、あるいは仮置きしたものに過ぎません。よっぽど単純な問題でない限り、絶対的な数値評価指標などというものは存在しないと思った方が良いです。

ベイズ混合モデルにおける近似推論③ ~崩壊型ギブスサンプリング~

 さて、今回は混合モデルに対する効率的な学習アルゴリズムとして、崩壊型ギブスサンプリング(Collapsed Gibbs Sampling)*1を紹介します。ベースとなるアイデア自体はギブスサンプリングそのものなのですが、標準的な方法と比べて種々の計算テクニックが必要になってくるのと、実際に推論精度が向上することが多いのでここで紹介したいと思います。 

また、今回の実験で使用したソースコードGithubにおいてあります。

GitHub - sammy-suyama/MLBlog: source codes used in MLBlog

 

[必要な知識]

下記をさらっとだけ確認しておくといいです。

 

1、崩壊型ギブスサンプリングのアイデア

基本的なアイデアとしては、対象の確率モデル(同時分布)から一部の確率変数をあらかじめ周辺化除去(marginalise out)しておき、より数の少ない確率変数をサンプルすることによってサンプリングの効率性を高めようとするものです*2

ここでは、崩壊型ギブスサンプリングの位置付けを明確するために、いくつかの異なるギブスサンプリングの手法を比較紹介します。

ある確率分布{p(z_1, z_2, z_3)}があり、この分布から{z_1},{z_2},{z_3}をすべて同時にサンプルするのが不可能であるとしましょう。この様な問題に対して、一般的なギブスサンプリングは次のように確率変数を1つ1つ別々にサンプリングするという作戦を取ります。

f:id:sammy-suyama:20160729175801p:plain

これは「直接同時にサンプルするのが難しいのであれば、他の値を固定したより簡易な条件付き分布から順次サンプルすればいい」というアイデアなのでしたね。

次に、ブロッキングギブスサンプリング(blocking Gibbs sampling)というのもあり、この場合はいくつかの変数をまとめてサンプリングします。

f:id:sammy-suyama:20160813140837p:plain

「すべて同時にサンプルするのは難しいが、{z_1},{z_2}の同時分布なら簡単に計算できる」というような場合ではこちらを使った方が断然性能が良いです。

さて、本題の崩壊型ギブスサンプリングでは上記2つの手法とは異なる作戦を取ります。この手法では、モデル中のいくつかの変数を周辺化除去することによって、より少ない数の変数だけをサンプルします。(Collapsed spaceでサンプルする、と呼ぶようです。)

f:id:sammy-suyama:20160813142357p:plain

f:id:sammy-suyama:20160813142409p:plain

最初の{z_3}に対する積分除去が解析的に出来ることと、それによって得られた同時分布{p(z_1,z_2)}からの交互サンプリングが簡単に行えることが適用できる条件です。単純なギブスサンプリングと比べて、そもそもサンプルする変数の種類が少ないので、より速く目的の分布からのサンプリングが得られることが期待できます。

一般的にはブロッキングギブスサンプリングや崩壊型ギブスサンプリングの方が、単純なギブスサンプリングより性能が良い傾向にあります。しかし単純ギブスサンプリグの方が1回あたりの計算が軽いので、問題によってはより早く所望の結果が得られる場合があります。実用上では、まず最初の2つの手法を検討してみて、それでも精度がイマイチだった場合には崩壊型ギブスサンプリングを試してみるのがオススメです。*3

 

2、混合モデルからパラメータを周辺化除去

まずは標準的な混合モデルを考えてみましょう。ここでは{x}{N}個の観測データの集合、{z}が各データに対する隠れ変数の集合、{\theta}{x}の分布を制御するパラメータ、{\pi}が隠れ変数の分布に対するパラメータです。f:id:sammy-suyama:20160813144049p:plain

{p(\theta)p(\pi)}がパラメータに対する事前分布です。一般的に混合モデルでは、{p(z)}はカテゴリカル分布を使います。{p(x|\theta, z)}{x}の発生をモデル化するための確率分布であり、今回は例としてポアソン分布を使いますが、用途次第ではガウス分布でも多項分布でも構いません。

さて、この式に対するグラフィカルモデルを次の様に表現してみることにします。

f:id:sammy-suyama:20160813151130p:plain

混合モデルに対する崩壊型ギブスサンプリングでは、パラメータをモデルからあらかじめ周辺化除去するのが一般的なやり方です。

f:id:sammy-suyama:20160813144102p:plain

こんな感じに積分除去すると、対応するグラフィカルモデルは次のようになります。一応これをここでは周辺化モデルって呼ぶことにします。

f:id:sammy-suyama:20160813151148p:plain

当然、積分除去された{\theta}{\pi}はもはや周辺化モデルには現れません。しかし、そのおかげでモデルが簡単になったかというとそうでもないようですね。隠れ変数{z}は元のモデルでは({\pi}が与えられたとき)独立性を保っていたもの、{\pi}積分除去された途端にすべての隠れ変数が依存関係を持つようになってしまいました。同様に、{x}{\theta}積分除去されたために、すべてのデータ点がお互いに依存するようになってしまいました*4 。このようなモデルから{z}をサンプリングする計算式を導くのが目標になります。

 

3、周辺化モデルからのサンプリング

さて、周辺化モデルは非常にタイトな変数依存関係を持ってしまってしまっているので、{z}を一度に同時にサンプルすることはできません。しかし{z_1}{z_2},・・・、{z_N}のように、1つずつサンプルすることが可能である場合があります。ある{z_n}を、{z_n}以外のサンプル{ z_{\backslash n} = \{ z_1, ..., z_{n-1}, z_{n+1}, ..., z_N \} }がすでに与えられた状態でサンプルできないか考えてみることにします。この条件付き分布は次のように計算することが出来ます。

f:id:sammy-suyama:20161103130033p:plain

1行目では、ただ単にベイズの定理の分母を無視したもので事後分布を書き直しただけです。2行目ではそれをバラバラに展開しました。真ん中の項は{x_n}を除いたグラフィカルモデルを考えれば、独立性から、

f:id:sammy-suyama:20161103164208p:plain

であることが示せるため、結果今サンプルしたい{z_n}とは無関係になるので3行目では除去されています。

さて、出来上がった最後の式をよく見てみると、目的の確率分布が{p(x_n |x_{\backslash n}, z_n, z_{\backslash n})}{p(z_n | z_{\backslash n})}の2つの分布に分解されることがわかりますね。これらの確率分布はどういう意味を持っているのでしょうか。

まず始めに{p(z_n | z_{\backslash n})}ですが、次のような{z_n}に関するある種の予測分布であると解釈することができます。

f:id:sammy-suyama:20161103130333p:plain

まず、すでにサンプルされていると仮定している{z_{\backslash n}}を観測データかのように扱うことで、{\pi}のある種の事後分布のようなもの{p(\pi|z_{\backslash n})}が計算できます。この事後分布は、次の様にベイズの定理を使って簡単に計算することができます。

f:id:sammy-suyama:20161103130508p:plain

今回は{p(z_{\backslash n}|\pi)}はカテゴリカル分布で、{p(\pi)}はディリクレ分布です。したがって、次のようなディリクレ分布事後分布が求まります。

f:id:sammy-suyama:20161103130630p:plain

さて、この{\pi}に関する事後分布を使って予測分布を計算してみることにします。結局、有限シンボルの離散分布であることがわかるので、結果はカテゴリカル分布として表現することができます。

f:id:sammy-suyama:20161103212604p:plain

同様にして、残る{p(x_n |x_{\backslash n}, z_n, z_{\backslash n})}の項も次の様に{x_n}に関する({z_n}の条件付き)予測分布になることがわかります。

f:id:sammy-suyama:20161103131603p:plain

次のセクションで解説しますが、ポアソン・ガンマモデルではこの積分は解析的に実行できます。*5

ところで{x_n}は実際にはデータとして与えられているので、より正確に言うとこの項は予測尤度とでも言った方が正しいかもしれません。肝心な点は、具体的な{z_n}を与えることによってこの尤度が評価できるという点です。{z_n}に対する{K}種類の実現値1つ1つに対して式{p(x_n |x_{\backslash n}, z_n, z_{\backslash n})p(z_n | z_{\backslash n})}を評価し、正規化してあげれば、{z_n}をサンプルするための離散分布が計算できることになります。

 

4、ポアソン・ガンマモデルにおけるベイズ推論

さて、ここまでで崩壊型ギブスサンプリングの説明はほぼ終わりなのですが、残された課題は次の条件付き予測尤度の計算ですね。

f:id:sammy-suyama:20161103131603p:plain

先ほどと同様、手順としてはまず右側の事後分布{p(\theta|x_{\backslash n},z_{\backslash n})}を計算し、その後で尤度関数{p(x_n | \theta, z_n)}と掛け合わせてから{\theta}積分除去します。

まず事後分布の計算からやってみましょう。今回は{D}次元のポアソン・ガンマモデルを仮定しているので{\theta}ポアソン分布のパラメータ{\lambda}になります。こちらもベイズの定理を使うと、

f:id:sammy-suyama:20161103134221p:plain

として計算をすることができ、事後分布は当然ガンマ分布になります。

f:id:sammy-suyama:20161103134239p:plain

さて、この事後分布を使って予測分布を計算してみましょう。幸い事後分布がガンマ分布のままなので、このまま解析的にパラメータ{\lambda}積分除去することができ、得られる分布は次のような負の二項分布(Negative Binomial Distribution)になります。

f:id:sammy-suyama:20161103213242p:plain

ここでは、負の二項分布の定義として次のような表現を使いました。

f:id:sammy-suyama:20161103135740p:plain

混合モデルにおいて崩壊型ギブスサンプリングが適用できる条件としては、観測モデルの事後分布と予測分布がともに解析的に実行できることです。今回のようなポアソン・ガンマモデル以外でも、共役の関係にある分布を選べばこれは必ず実行できます。  

 

5、動作確認実験

さて、今回導いたポアソン混合モデルにおける崩壊型ギブスサンプリングアルゴリズムをJuliaで実装し、動作確認をしてみます。ソースコードGithubにあります。

観測データ数N=1000、次元数D=2、クラスタ数K=8として混合モデルを学習させてみました。次の図は100回までのサンプル結果をアニメーションにしています。 

f:id:sammy-suyama:20161028181950g:plain

左下の方のクラスタはかなり密集していますが、なんとかうまく分離できているように見えますね。右図でサンプル回数が50回を超えてもまだパタパタしている箇所がありますが、それらのデータ点はクラスの所属が「あいまい」であることを示しています。

 

さて、せっかくですので前回導出した標準的なギブスサンプリングと簡単な性能比較をしてみます。下の図は横軸をサンプル回数、縦軸を最後のサンプルに対する尤度にしてグラフを描いたものです*6。GS(ギブスサンプリング)、Collapsed(崩壊型ギブスサンプリング)ともに5回ずつ実験しています。

f:id:sammy-suyama:20161028121122p:plain

傾向として、崩壊型ギブスサンプリングの方が少ない繰り返し回数で、より高い尤度に達しているようですね。最終的な到達点も崩壊型ギブスサンプリングの方が高い傾向があります。

ちなみに計算時間で比較すると、100回のサンプリングでギブスサンプリングが平均7.03秒、崩壊型ギブスサンプリングが平均7.15秒と、あまり差がないようです。 一般的には、崩壊型ギブスサンプリングにおける予測尤度の計算が遅くなる可能性がありますが、今回の場合は特にボトルネックにはなっていないようです。

 

6、まとめ

さて、今回はベイズポアソン混合モデルを題材にして、崩壊型ギブスサンプリングのアルゴリズムを導いてみました。今回の簡易実験が示す通り、標準的なギブスサンプリングアルゴリズムよりも性能が高くなる傾向があるようです。オススメとしては、まず標準のギブスサンプリングを導いてみて、その性能で満足いかないようであれば崩壊型ギブスサンプリングを導出してみるのが良いかと思います。ただし、解析的にパラメータを積分除去するためには、今回のポアソン分布とガンマ分布の例のように、観測モデルが共役の関係性を持っている必要があります。

同様のアイデアは時系列モデルである隠れマルコフモデル(Hidden Markov Model, HMM)、トピックモデルにおけるLatent Dirichlet Allocation(LDA)に適用されているほか、中華料理店過程(Chinese Restaurant Process, CRPインド料理店過程(Indian Buffet Process, IBP)などのベイジアンノンパラメトリクスの手法にも応用されています。

 

*1:参考: Machine Learning: A Probabilistic Perspective by Kevin Murphy | The MIT Press

*2:このことから、崩壊型ギブスサンプリングは周辺化ギブスサンプリングとも呼ばれることもあるようです。

*3:ただし、モデルによっては解析的にうまくアルゴリズムを導けない場合や、解析的な周辺化のために積分近似を行う場合もあります。

*4:これは一般的には{\int \prod_{n} p(x_n|\theta)p(\theta)d \theta \neq \prod_{n} \int p(x_n|\theta)p(\theta)d \theta}であるためです。

*5:他にもガウス・ウィシャートモデルのように、共役関係が成り立っていれば解析計算できます。

*6:尤度で性能を比較するのはあまり望ましくないですが、今回は完全に同じモデルからアルゴリズムを導いているので、尤度でもほぼ「良いクラス割り当て」を反映しているとしてしまってもいいんじゃないかと思います。

機械学習の4つのアプローチ

おつかれさまです。今日はちょっと趣を変えて、近年のいわゆる「機械学習」という技術のアプローチをカジュアルに少しカテゴリ分けしたいと思います。

といっても、自分はアカデミックの研究者ではなく大量の論文を読み漁るということもほとんどしないので、理論的なバックグラウンドに基づいたソリッドなカテゴリ分けはできません。ここで紹介するのはあくまで、実用上の機械学習技術者から見た視点で「こんな傾向があるかなぁ」くらいの気持ちで書いたものです。 

 

<代表的な4つのアプローチ>

1、最適化(目的関数ベース)

まず始めは最適化手法をベースにした機械学習アルゴリズムです。たぶん一番例が多いんじゃないでしょうか。

ここでは、ある解きたい課題を目的関数によって定式化し、適切な最適化手法を使って解きます。伝統的な線形回帰や線形識別はもちろん、主成分分析(PCA)や非負行列因子分解(NMF)なんかもこの枠組みで解かれることが多く、ほとんどの場合で誤差関数を定義してそれを最小化するというアプローチを取ります。他にはサポートベクターマシンSVM)なんかもマージン最大化という基準にしたがって最適化を行いますね。

この種のアルゴリズムの利点としては、比較的自由に目的関数をデザインして解くことができる点が挙げられると思います。

欠点としては、ある種の複雑な課題に対してはそもそもどうやって目的関数を設定していいかわからない場合があることと、最適化に基づいているので簡単にデータに対してオーバーフィットしてしまうことです。また、予測が「どれだけ確からしいのか」といった情報を上手く扱えないことが多いです。

 

2、深層学習

最近流行っているあれです。一番シンプルな例は(伝統的な)ニューラルネットワークなどで、アイデアとしては、データの表現を多層構造を使って学習することにより、データの次元間にまたがった共通の特徴を高レベルの層でシェアして汎化性能を高めようというものです。画像や音声の認識タスクで性能を発揮するようです。

利点としては、概念が比較的わかりやすいこと、ある特定の課題に対して顕著な性能を発揮していることです。

欠点としては、基本的にものすごい量のデータと計算コストを使用しなければならないことと、アルゴリズムのチューニングが厄介なことです。あと、だいたい単純な誤差関数の最小化とかを基準にするので上の方法と同様オーバーフィットしやすいです。あとは、現状あまり理論面が洗練されていないのも課題です。

 

3、機械学習ライブラリ

これもカテゴリに入れていいのか謎ですが、実際の現場ではよく使われています。Scikit-learn*1などの機械学習ライブラリを駆使して問題を解くという、あらゆる場面で比較的にスピーディーに試せる方法です。

基本的なアプローチとしては、入力データをよく眺めて、特徴量抽出や次元削減などを行い、その結果を識別器にかけるというものです。

利点としては、ややこしい数学の知識などがなくてもプログラミングさえ少しできれば誰でも始められることです。機械学習の入門として、あるいはクイックプロトタイピングとしてお勧めかもしれません。あとは、わりと洗練されたライブラリが世に出回っているので、自分でいろいろアルゴリズムを開発してバグに悩まされるという心配もあまりありません。

欠点としては、解けるタスクが非常に限られていることです。問題自体をデザインすることがほとんどできないので、最大性能もほかのアプローチと比べて限界があります。


4、ベイズ学習

すべての問題を「ベイズの定理のなるべく精緻な実行」 として解くアプローチです。

基本的には、データの発生プロセスを確率分布を使って物理的・論理的に記述し、近似推論アルゴリズムを使って事後分布を計算するという流れです。上に具体的に挙げたような各アルゴリズムの多くがベイズ化できるほか、ベイジアンノンパラメトリクスと呼ばれる、ガウス過程やディリクレ混合過程などといったベイズ手法ならではのモデルもあります。

このアプローチの利点としては、基本的にはオーバーフィットをしないため*2、少量・多次元のデータでも性能が出やすいことです。 また、確率分布を組み合わせてモデルを自由にデザインできるので、幅広い課題に対してアルゴリズムを与えることができます。

欠点としては、アルゴリズムの導出に多少の数学力を要することと、厳密な計算には非常に計算コストがかかることです。

 

 

 <ベイズ学習の汎用性>

で、自分は完全なベイズ派なので、最後に今一度ベイズ学習の汎用性と、他の3手法との関係性について触れたいと思います。

 

1、ベイズ学習と最適化

ベイズ学習でも最適化手法をサブルーチンとして使うことは良くあります。というのも、ある種の最適化問題は、ベイズ学習で必要となる積分の近似と等価になるからなんですね。

例えば最尤推定(最小二乗法を使った誤差関数の最小化)なんかも、実はベイズの近似推論に対して極端な仮定を置くことで導かれます*3。主成分分析、非負行列因子分解もベイズ化できるほか、サポートベクターマシンガウス過程の関係性も指摘されています*4

 

2、ベイズ学習と深層学習

ベイズ学習は汎用的なデータ解析の枠組みであるので、もちろん深層学習の多様なモデルをベイズ学習として再定式化することができます。代表的には、ガウス過程を使ったディープなモデル*5があるほか、変分ベイズを使ったオートエンコーダの実装*6もあります。あとは畳み込みニューラルネットワーク(CNN)をベイズの枠組みで焼き直して変分近似で解くといった手法とかもあります*7

 

3、ベイズ学習とライブラリ

ベイズ学習の1つの欠点は、近似推論手法の開発に非常に数学力と手間がかかることです。この手間を省いてくれるものとして、種々の統計確率言語があります。代表的なものにはStan*8があり、モデルの記述さえすればあとは勝手に近似推論アルゴリズムを実行してくれます。残念ながら、複雑なモデルに対する推論性能は現在のところあまりよろしくないようです。

他にはベイズの枠組みで作られたアルゴリズムがそのままライブラリ化されている場合ももちろんあります。最近人気なのはベイズ的最適化(Bayesian Optimization)で、深層学習のチューニングなんかに使われているようです。

 

- - -

さて、ちょっとした落書きのような記事になってしまいましたが、少しでもたくさんある機械学習技術のアプローチとその関係性がクリアになっていただければ幸いです。

*1:Scikit-learn: http://scikit-learn.org/stable/

*2:PRMLとかではオーバーフィットしないと言い切ってますが、実際の多くの場面では近似アルゴリズムを使うので、近似性能が悪ければオーバーフィットもアンダーフィットも起こり得ます。

*3:最尤推定、MAP推定、ベイズ推論 - 作って遊ぶ機械学習。

*4:Gaussian Process for Machine Learning: http://www.gaussianprocess.org/gpml/

*5:Deep Gaussian Process: http://www.jmlr.org/proceedings/papers/v31/damianou13a.pdf

*6:Auto enoding variational Bayes: https://arxiv.org/abs/1312.6114

*7:Bayesian CNN: https://arxiv.org/abs/1506.02158

*8:Stan: http://mc-stan.org/

ベイズ混合モデルにおける近似推論② ~ギブスサンプリング~

さて、今回はMCMCの代表的な手法であるギブスサンプリングを使って、混合モデルによるクラスタリングを行いたいと思います。今回も前回の変分近似の記事と同様、ポアソン混合分布を具体的なモデル例として使っていきます。

 

[必要な知識]

下記をさらっとだけ確認しておくといいです。

 

・ギブスサンプリング

さて、ギブスサンプリングでは、サンプルを取りたい同時分布{p(z_1,z_2,z_3)}に対して、下記のような繰り返し手続きを用いて変数{z_1,z_2,z_3}を順にサンプリングします。

f:id:sammy-suyama:20160729175801p:plain

他の変数を既にサンプリングされた値で固定し、残りを確率分布からサンプルする、というのを繰り替えしていきます。それぞれの確率分布が、注目している変数をサンプリングするのに十分なほど簡単になっているのがギブスサンプリングが適用できる条件です。証明は今回省きますが、このような手続きで得られたサンプルは、数が十分に多ければ真の分布から得られたものとみなすことができます。

ギブスサンプリングは変分近似と比べ、細かい積分計算(期待値計算)を必要としない分だけいくらか変分近似より楽に導出できるかと思います。また、サンプリング手法が元々積分計算を近似するために開発されたという経緯もあり、変分近似と比べて若干適用できるモデルの範囲が広いです。変分近似とギブスサンプリングの簡単な比較はこちらの記事をご参照ください。

 

ポアソン混合モデルに対するギブスサンプリング

さて、前回と同様、お題としてポアソン混合モデルを使用します。利便上もう一度確率モデルを書いておくことにします。 

f:id:sammy-suyama:20160706122448p:plain

{x}{z}はそれぞれ観測データと隠れ変数の集合で、{\lambda}{\pi}はパラメータです。

それぞれのパーツは具体的に次の様に設定します。

f:id:sammy-suyama:20160706122512p:plain

f:id:sammy-suyama:20160706122531p:plain

f:id:sammy-suyama:20160706123807p:plain

f:id:sammy-suyama:20160706122606p:plain

早速このモデルの事後分布({x}が観測された後の残りの確率変数の分布)の推定にギブスサンプリングを適用してみましょう。今回はパラメータ{\{\lambda, \pi \}}と隠れ変数{z}を別々に分けることによって、十分容易にサンプリングが出来る確率分布が得られることを示します。

f:id:sammy-suyama:20160729184242p:plain

f:id:sammy-suyama:20160729184710p:plain

まずパラメータである{\lambda}{\pi}のサンプルから見てましょう。すべての隠れ変数{z}がすでにサンプルされたある値で固定された状態になっているので、パラメータの分布はちょこちょこっと計算すると次のようなガンマ分布とディリクレ分布の独立した積になることがわかります(表記を簡単にするためインデックス{i}は取り除きます)。

f:id:sammy-suyama:20160729185837p:plain

ガンマ分布に関しては、さらにそれぞれのクラスタ{k})と次元({d})ごとに独立にサンプルすればOKだということがわかりますね。実装上では、お使いのプログラミング言語のライブラリでガンマ分布とディリクレ分布からそれぞれ値をサンプルすればOKです。

さて、パラメータがサンプルされたので、今度は隠れ変数{z}をサンプリングしてみることにします。{\lambda}{\pi}が一旦サンプルされた値で固定されると、次の様に{z}はそれぞれデータ点ごとに独立にサンプリングできることがわかります。

f:id:sammy-suyama:20160729190112p:plain

このようにしてすべての{z_n}をサンプルし終えたら、また{\lambda}{\pi}のサンプリングに戻ります。

 

・簡単な実験

さて、導出したポアソン混合モデルのギブスサンプリングを使って、簡単なトイデータのクラスタリングをしてみましょう。可視化のためデータの次元{D}は2に固定し、データ数は300とします。サンプリングのイタレーションは50回とします。

次の結果はクラスタ{K=2}とし、多少クラスタ間のオーバーラップがあるデータから隠れ変数をサンプリングしてプロットしてみたものです。

f:id:sammy-suyama:20160730013101p:plainf:id:sammy-suyama:20160730012717g:plain

左の図が正解のクラスタリングで、右図はサンプリングのプロセスをアニメにしています。右図を見ると、サンプリング数が増えていっても2つのクラスタのちょうど中間くらいにあるデータに対する割り当てはずっと安定しません。サンプリング法では、このような事後確率の不確実性がそのままサンプルされる値のバラツキ加減によって表現されるわけですね。 

 

次はクラスタ{K=6}のデータを分離してみた結果です。

f:id:sammy-suyama:20160730012556p:plain f:id:sammy-suyama:20160730012834g:plain

サンプリングの途中で誤ったクラスタ分けに一度収束しかけていますが、30回目くらいでなんとか運良く脱出し、最終的には正しい結果が得られたようですね。ギブスサンプリングはじっくり待てば理論的には真の事後分布からのサンプルを得ることが出来るのですが*1、実際には局所的に尤度の高い位置にひっかかってしまい抜け出せなくなってしまう場合も多いです。

 

・まとめ

ということで、今回はポアソン混合分布に対するギブスサンプリングを導出し、簡単な実験をやってみました。ガウス混合分布と比べてパラメータ数も1つ少なく行列計算も必要ないので、実際に手で計算してみてアルゴリズムを導出してみることをオススメします。変分近似と比べてもいくぶんか導出は楽ですね*2

次回は1つ発展として崩壊型ギブスサンプリング(Collapsed Gibbs sampling)を紹介する予定です。

*1:真の事後分布が得られることと、想定している正解のクラスタリング結果が得られることとは同値ではないので注意してください。

*2:前回の変分近似の記事と結果の式を比べてみると、期待値計算を除いてほとんど同じになっていると思います。実を言うと、前回の記事のtexをそのままコピーして今回の記事の式を作っています。