はじめに
本シリーズでは,確率的プログラミング言語Pyroを用いて統計モデリングを行う方法について,いくつかの例題を交えながら紹介していきます.
例題には,書籍「実践Data Scienceシリーズ RとStanではじめるベイズ統計モデリングによるデータ分析入門」(KS情報科学専門書)に登場する例題を採用します.この本では題名の通りRとStanを用いてベイズモデリングを行っていますが,本シリーズでは同じ例題をPyroを用いて解いていきたいと思います.コーディングを通じて統計モデリングへの理解を深めるとともに,実データにもPyroを用いた柔軟なモデリングを適用できるようになることを目的として執筆します.統計モデリングそのものについての詳しい解説は書籍や他の記事に譲り,本記事では実装をメインに書きます.
読者としては.以下に当てはまるような人を想定しています.
- Pythonの基本的な使い方がわかる人
- ベイズ統計モデリングの基本を理解している人
- 柔軟かつスケーラブルな統計モデリングを行いたい人
- Pytorchユーザ
本記事はそのシリーズの第1回として,Pyroの概要および次回以降のモデリングを実装していく上での基本的なメソッドを説明していきます.
Pyroとは
Pyro はUber AI Labsが開発したPythonで書かれた確率的プログラミング言語の一つです. バックエンドにはPytorchを採用しており,もちろんGPUを利用できます.公式サイトに書いてあることを意訳すると,Pyroを使う利点は以下の通りです.
- 汎用性: あらゆる計算可能な確率分布を表現できる.
- スケーラビリイティ: (並列計算を用いることで)大きなデータセットにも対応可能.
- 最小限: コードの複雑性を可能な限り落としているので挙動を把握しやすい(?)
- 柔軟性: 処理の自動化もできるし,カスタムもできる.
特に,GPUを利用可能なフレームワークの特長として,大きなデータセットに対しても実用的な時間で計算できるという利点(=スケーラビリティー)は注目すべきポイントです.他にGPUを利用できる確率的プログラミング言語にはEdward2などがありますが,PytorchユーザにはPyroの方が使いやすいでしょう.
Pyroのインストール
公式リファレンスにある通り,pipを用いて以下のコマンドでインストールできます.
pip install pyro-ppl
Pyroの基本メソッド
Pyroには統計モデリングを実装するための根幹となるメソッドが用意されていますが,その中で最も基本的なpyro.sample
およびpyro.plate
について本稿で紹介します.これらは,確率分布からのサンプリングを容易に記述できるメソッドです.
1. 確率分布に従うサンプリングpyro.sample
統計モデリングのフレームワークとして欠かせないのが,確率分布に従うサンプリングです. Pyroでは多くの確率分布(正規分布,二項分布,ポアソン分布,...)が用意されており,
pyro.sample(<識別名>, <確率分布>)
という記述により指定した確率分布から標本を抽出することができます.
以下のコードは,標準正規分布から10万個のi.i.dなサンプルを抽出し,確認のために抽出した標本の分布を可視化するものです.
import matplotlib.pyplot as plt
import pyro
import pyro.distributions as dist # distにはPyroで利用できる確率分布が実装されている
# for文でサンプリングを実行
samples = []
for _ in range(100000):
# 標準正規分布から1つのサンプルを抽出
a_sample = pyro.sample("a_sample", dist.Normal(0, 1)) # 標準正規分布より
samples.append(a_sample)
# 可視化
plt.hist(samples, bins=50)
plt.title("標準正規分布からの標本分布(n=10万)", fontsize=16)
適切に標準正規分布からサンプリングされていることが確認できます.
これでも良いのですが,Pyroではよりシンプルな書き方により同様の標本を得ることができます.
2. ベクトルとして取得することを宣言pyro.plate
統計モデリングを行うにあたっては特定の確率分布から多数の独立なサンプルを抽出することは非常に頻繁に行われます.1
のようにfor文で記述すると記述・処理の両面において非効率です.
そこで便利なのが,pyro.plate
です.
pyro.plate(<コンテクスト名>, <サンプルサイズ>)
によって宣言されたコンテクスト内でpyro.sampleによるサンプリングを行うと,ベクトルとしてサンプルを得られます.以下はその実装です.
# pyro.plateを用いてベクトルとして取得する場合
with pyro.plate("plate", size=100000):
samples = pyro.sample("samples", dist.Normal(0, 1))
plt.hist(samples, bins=50)
plt.title("標準正規分布からサンプリングした標本分布(n=10万)", fontsize=16)
結果は上図と同様になるはずです.
pyro.sample
,pyro.plate
を用いることにより,確率分布からサンプリングを行うことができるようになりました.統計モデリングを行うためには他にも不可欠な機能がありますが,それらは次回以降に実例を交えながら随時説明してまいります.
まとめ
本稿では,主に以下の2つの点についての紹介を行いました.
- Pyroの概要や利点
- 確率分布からサンプリングを行う
pyro.sample
,pyro.plate
冒頭でも述べた通り,次回からは書籍「実践Data Scienceシリーズ RとStanではじめるベイズ統計モデリングによるデータ分析入門」(KS情報科学専門書)に準拠し,書籍で紹介されている例題をPyroで再現する形で進めていきます.
次回は第3部第2章「単回帰モデル」を扱います.