NumPyro:各分布に関してまとめ
連載している記事の1つです。以前までの記事を読んでいる前提で書いているので、必要であればNumPyroの記事一覧から各記事を参考にしてください。
はじめに
ベイズを扱う際に避けて通れないのが、数多くある確率分布です。今回はこれまで扱ってきた分布をまとめていきます。
分布
分布の形状を可視化するための準備を行います。
from jax import random
from jax import numpy as jnp
import numpyro.distributions as dist
import seaborn as sns
import matplotlib.pyplot as plt
def plot_dist(list_dist, num_sample=10000, kde=True):
plt.figure(figsize=(5, 4))
for i, dist in enumerate(list_dist):
samples = dist.sample(random.PRNGKey(0), (num_sample,))
sns.histplot(samples, kde=kde, stat="density", label=str(i))
plt.xlabel("X")
plt.legend()
参考
- https://en.wikipedia.org/wiki/Probability_distribution
- StanとRでベイズ統計モデリング
- https://mc-stan.org/docs/functions-reference/discrete-distributions.html#discrete-distributions
連続確率分布
連続型一様分布
NumPyroでの実装
d = [dist.Uniform(low=0, high=10)]
plot_dist(d)
Probability density function(PDF)
support
parameters
平均
分散
使用例
無情報事前分布として使用されます。Stanでは事前分布を指定しない限り、とりうる値の範囲内で一様な一様分布が設定されます。NumPyroでは何かしらの事前分布を指定する必要があるので、極端に広いパラメータを指定しておけば同じような結果になります。
ベータ分布
NumPyroでの実装
# concentration1:alpha
# concentration0:beta
list_dist = [
dist.Beta(concentration1=0.5, concentration0=0.5),
dist.Beta(concentration1=5, concentration0=1.0),
dist.Beta(concentration1=2, concentration0=2),
dist.Beta(concentration1=1, concentration0=1),
]
plot_dist(list_dist, kde=True)
Probability density function(PDF)
support
parameters
平均
分散
使用例
その他
事前分布として何も情報を持たせたくない場合は、\alpha=\beta=1とすることで0~1の範囲の一様分布と同じになる。
ベータ分布は平均値μ(0<μ<1)と2つの形状パラメータの和ν=α+β>0で再パラメータ化することができ、平均値が重要な統計量の場合に有効。
ディリクレ分布
NumPyroでの実装
# 三角ダイアグラムはサボりました。。。
samples = dist.Dirichlet(concentration=jnp.ones(2)).sample(random.PRNGKey(0), (100,))
plt.scatter(samples[:, 0], samples[:, 1])
Probability density function(PDF)
support
parameters
平均
分散
使用例
ベータ分布の多変量版。カテゴリカル分布や多項分布のパラメータ
その他
指数分布
NumPyroでの実装
list_dist = [
dist.Exponential(rate=0.5),
dist.Exponential(rate=1.0),
dist.Exponential(rate=1.5),
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
機械が故障するまでの時間などイベントが起こるまでの時間を表す際に使用される。また時間だけでなく、DNA鎖の突然変異の間の距離など、あるイベントが単位長さあたり一定の確率で発生する状況をモデル化する際にも使用される。また、スケールなど正の実数のパラメータを生成する分布として使用される。
その他
無記憶性を持つ唯一の連続型の確率分布で、各時間単位でイベントが起こる確率が等しいとしているモデル。そのため、12-13時の昼休憩時と13-14時の間では電話がかかってくる確率が異なるので、13-14時だけに限定してモデル化する際にはよく表現できる。
また、あるイベントが起こる時間や長さが複数の独立した作業の連続と考えられるプロセスの場合は、Erlang分布(独立した複数の指数分布変数の和の分布)に従う。
ガンマ分布
NumPyroでの実装
list_dist = [
dist.Gamma(concentration=1, rate=1),
dist.Gamma(concentration=1, rate=3),
dist.Gamma(concentration=3, rate=1),
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
待ち時間をモデル化する際に使用される。また、正の実数値を取るので正のパラメータを生成する際に使用される。
その他
1次元正規分布
NumPyroでの実装
list_dist = [
dist.Normal(loc=0, scale=1),
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
多くのデータに当てはめることができる。モデリングする際も階層モデルで個人差やグループ差を考慮する際に使用される。
その他
裾野が短く外れ値に弱いのでコーシー分布やStudentのt分布が代わりに使用される。正規分布に従うxに対して新しい確率変数
多次元正規分布
NumPyroでの実装
samples = dist.MultivariateNormal(loc=jnp.zeros(2), covariance_matrix=jnp.eye(2)).sample(random.PRNGKey(0), (1000,))
plt.scatter(samples[:, 0], samples[:, 1])
Probability density function(PDF)
support
parameters
平均
分散
使用例
相関がある2つの変数の分布をモデル化する際に使用する。ガウス過程を扱う際にも使用される。
その他
コーシー分布
NumPyroでの実装
list_dist = [
dist.Cauchy(0, 1),
]
plot_dist(list_dist, kde=True)
Probability density function(PDF)
support
parameters
平均
分散
使用例
かなり裾が長い分布なので稀に大きな値を生成するため、外れ値を含むモデルや変化点の検出に使用される。他にも年間最大1日降雨量や河川流出量などの極端な事象に適用されます。
その他
独立な2つの正規分布Normal(0, 1)の比率はCauchy(0, 1)に従う。コーシー分布は、自由度1のスチューデントのt分布と一致する。
Studentのt分布
NumPyroでの実装
list_dist = [
dist.StudentT(df=2, loc=0, scale=1),
dist.StudentT(df=4, loc=0, scale=1),
dist.StudentT(df=100, loc=0, scale=1),
]
plot_dist(list_dist, kde=True)
plt.xlim([-5, 5])
Probability density function(PDF)
support
parameters
平均
分散
使用例
外れ値を含むモデルに使用される。
その他
自由度1のスチューデントのt分布はコーシー分布と一致する。自由度∞のスチューデントのt分布は正規分布と一致する。そのため自由度
また、自由度はスチューデントのt分布の尖度を制御しスケールパラメータと相関がある。そのため、尤度は複数の局所最大値を持つことがあるため、自由度をかなり低い値(3~9, または5)に固定した上で他のパラメータを推定することがしばしば必要になる。
ラプラス分布
NumPyroでの実装
list_dist = [
dist.Laplace(loc=0, scale=1),
dist.Laplace(loc=0, scale=2),
]
plot_dist(list_dist, kde=True)
Probability density function(PDF)
support
parameters
平均
分散
使用例
その他
2つの指数分布をつなぎ合わせたものと考えることができるため、二重指数分布と呼ばれることもある。指数分布と同様に裾が長い。
NumPyroではラプラス分布に似た形状であるがどこでも微分可能なdist.SoftLaplace
が実装されている。微分可能なためHMCやラプラス近似に適しています。また、2つの異なる指数分布をつなぎ合わせた分布として非対称ラプラス分布もある。
ワイブル分布
NumPyroでの実装
list_dist = [
dist.Weibull(scale=1, concentration=1),
dist.Weibull(scale=1, concentration=1.5),
dist.Weibull(scale=1, concentration=5),
]
plot_dist(list_dist, kde=True)
Probability density function(PDF)
support
parameters
平均
分散
使用例
k=1の時は指数分布とk=2の時はレイリー分布を表している。Xが故障までの時間とした時に、kの値に応じて初期不良、ランダムな外的要因による故障、摩耗などによる劣化のための故障などを表す分布と捉えることができ、幅広い分野で使用されている。
その他
故障率はワイブル分布がよく使われるが、化学反応や腐食が原因の製品故障は、通常、対数正規分布でモデル化される。ワイブル分布は極値分布の1つで、他にはガンベル分布とフレシェ分布がある。特に、ガンベル分布はさまざまな分布に従う確率変数の最大値(または最小値)が漸近的に従う分布であり、稀にしか発生しない地震や洪水などの自然災害の発生する確率をモデル化する際に使用される。
LKJ分布
Probability density function(PDF)
parameters
使用例
共分散行列を生成する際に使用される。同様に、共分散行列を生成する分布として逆ウィシャール分布があるが問題が生じるためLKJ分布から生成した相関行列を使用して共分散行列を生成することが推奨されている。
その他
パラメータ
LKJ分布を使用した分散共分散行列の事前分布に関してはこちらを参照。
また、逆ウィシャール分布の課題やLKJ分布に関してはこちらがわかりやすかったです。
離散確率分布
離散型一様分布
NumPyroでの実装
d = [dist.DiscreteUniform(low=0, high=10)]
plot_dist(d, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
サイコロのように事象が等しい確率で起こる際に使用される。
ベルヌーイ分布
NumPyroでの実装
list_dist = [
dist.Bernoulli(probs=0.2),
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
コイン投げで表か裏か、実験が成功か失敗かなど2値で表すことができる場合に使用されます。また0か0以外かの2値を表すベルヌーイ分布と他の分布を組み合わせることでゼロ過剰モデルやハードルモデルを定義できたりします。
その他
パラメータp
は0~1の範囲の実数なので、何からの値に対してロジスティック関数を適用し0~1の範囲にした結果をp
として使用する場合が多いです。そのため、NumPyroでは引数の値に対してロジスティック関数を適用してくれるdist.BernoulliLogits
という関数も用意されています。
また、二項分布の特殊なケースで、1回の試行が行われた二項分布とみなすことができす。
二項分布
NumPyroでの実装
list_dist = [
dist.Binomial(total_count=10, probs=0.2)
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
10回コイントスを行った中で表だった回数、10回実験を行った中で上手くいった回数を表す際に使用される。
その他
二項分布は全ての試行回数で同じ確率pを持つベルヌーイ分布を想定しているが、異なる確率を仮定する場合はPoisson binomial distributionやBeta-binomial distributionが使用できる。二項分布はPoisson binomial distributionのpが全て同じ特殊ケースとみなすことができる。
また、nが十分大きい場合は正規分布
nが大きく、pが十分小さい場合はポアソン分布
カテゴリカル分布
NumPyroでの実装
list_dist = [
dist.Categorical(probs=jnp.ones(6)*1/6)
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
ベルヌーイ分布の多変数版。カテゴリやインデックスを表す際に使用される。例えば、K=6,
その他
パラメータp
として使用する場合が多いです。
パラメータ
多項分布
NumPyroでの実装
ここでは0番目のカテゴリの回数の分布を表示した。
samples = dist.Multinomial(total_count=6, probs=jnp.ones(6)*1/6).sample(random.PRNGKey(0), (1000,))
sns.histplot(samples[:, 0], kde=False, stat="density")
Probability density function(PDF)
support
parameters
平均
分散
使用例
サイコロを10回投げた時の各出目が何回ずつ出るかを表す。
その他
パラメータ
二項分布の時の内容と同じように過分散に対応した分布としてDirichlet-multinomial distributionがあります。この分布の確率を固定したものが多項分布です。
ポアソン分布
NumPyroでの実装
list_dist = [
dist.Poisson(rate=1),
dist.Poisson(rate=4),
dist.Poisson(rate=10),
]
plot_dist(list_dist, kde=False)
Probability density function(PDF)
support
parameters
平均
分散
使用例
ある一定期間で機械の故障などのイベントが発生する回数を表す際に使用される。
その他
パラメータ
事前分布
以下のStan関連のリンクに非常によくまとまっていました。
最後に
以上で「各分布に関してまとめ」は終わりです。情報の羅列なので適宜参考にしてください。次回は「ガウス過程」です。
Discussion