第1章 ベイズ推論の考え方 Part 3
市東 亘
2021 年 8 月 23 日
1 概観
テキスト「Python で体験するベイズ推論」pp.15–24
例題: メッセージ数に変化はあるか?
• 分析の背後にある統計モデルを理解する.
• PyMC3 による実装方法を学ぶ.
2 例題: メッセージ数に変化はあるか?
目的
• メッセージ数がある時点を境に変化したと言えるか?
• 変化したならいつ?
0 10 20 30 40 50 60 70
Time (days)
0
10
20
30
40
50
60
70
count
of
text-msgs
received
Did the user's texting habits change over time?
図 1: メッセージ受信数
モデル
ポアッソン分布
• ある期間を等間隔の区間に分け,その区間に生起するイベントが,
– すべての区間で平均的に同じ率で観測され,
1
– 各イベントがこれまでに観測されたイベントに依存せず独立ならば,
⇒ ポアソン分布に従う.
• 非負の整数値をとる確率変数 X がポアソン分布に従うとき,確率分布は以下で与えられる.
P({X = k}) =
λk
e−λ
k!
パラメータ λ > 0 は事象が生起する強度(intensity)を表す.
• ポアソン分布の期待値と分散
– E[X] = λ
– V ar[X] = λ
メッセージ数の確率モデル
• メッセージ数 x はポアッソン分布に従うと仮定する.
⇒ xt ∼ Poisson(λ)
• E[X] = λ より λ はメッセージ受信数の期待値を表す.
• ある時期を境にメッセージ受信数の変化があったかどうかをモデル化するには,ポアッソン
分布のパラメータ λ(メッセージ受信数の期待値)がある時期を境に変化したかを検証すれ
ば良い.
⇒ 言い換えると,ある時期を境にメッセージ受信数が従うポアッソン分布に変化が生じた
かを検証していることになる.
• 確率モデルのまとめ
xt ∼ Poisson(λ)
where λ =
{
λ1 for t < τ
λ2 for t ≥ τ
ベイズ推定の復習
• データを所与の定数として,統計モデルのパラメータを確率変数として考えるのがベイズ
推定.
Pr(H|D) =
Pr(D|H)Pr(H)
Pr(D)
∝ Pr(D|H)Pr(H)
f(θ|x) ∝ f(x|θ)f(θ)
• 我々が求めたいのはデータが従う統計モデルのパラメータの事後分布関数
⇒ f(λ|x) ∝ f(x|λ)f(λ),
ただし,x はメッセージ数のデータを表す.
西南学院大学 演習 II(2019 年) 2 担当 市東 亘
ベイズモデル
• ここでは λ は λ1, λ2, τ に依存して値が決まるとモデル化する.
f(λ|x) ∝ f(x|λ)f(λ)
↔ f({λ1, λ2, τ}|x) ∝ f(x|{λ1, λ2, τ})f({λ1, λ2, τ})
= f(x|{λ1, λ2, τ})f(λ1)f(λ2)f(τ)
– 尤度関数: f(xt|{λ1, λ2, τ}) =
λxt
e−λ
xt!
, where
{
λ1 for t < τ
λ2 for t ≥ τ
– 事前分布: f(τ) =?
– 事前分布: f(λi) =? for i = 1, 2
• τ の事前分布を考える
– τ はメッセージ数に変化が生じたと考えられる期日.
– 特に特定の日に変化が生じたという信念はない.
⇒ 期日全体に一様に分布していると考えられる.
⇒ 理由不十分の原則
– 事前分布: f(τ) = DiscreteUniform(1, 70)
• λi の事前分布を考える
– λi はポアッソン分布のパラメータで λi > 0.
– 非負の確率変数が従う指数分布が使えそう.
⇒ 事前分布は主観的であることを思い出そう!
– 事前分布: f(λi) = eα
, for i = 1, 2
ただし,α = (
∑
xt/N)−1
で定数とする.
– パラメータ α をこの様に定義すると各区間のメッセージ数の期待値を表す λ と整合的
になる.
⇒ 指数分布の期待値より E[λ] = 1/α.
⇒ 1/α が区間におけるメッセージ数の期待値に適合するように 1/α =
∑
xt/N と定義.
– λi の分布はさらに別のパラメータ α に依存することになった!
• メッセージ数のベイズモデルまとめ
f({λ1, λ2, τ}|x) ∝ f(x|{λ1, λ2, τ})f(λ1)f(λ2)f(τ)
– 尤度関数: f(xt|{λ1, λ2, τ}) =
λxt
e−λ
xt!
, where
{
λ1 for t < τ
λ2 for t ≥ τ
– 事前分布: f(τ) = DiscreteUniform(1, 70)
– 事前分布: f(λi) = eα
for i = 1, 2
ただし,α = (
∑
xt/N)−1
で定数とする.
西南学院大学 演習 II(2019 年) 3 担当 市東 亘
確率的プログラミング
• 前ページで定義した事前分布と尤度関数を全て定義すれば,Stan や PyMC3 等のプログラム
が事後分布に従うサンプルを生成してくれる.
• 事後分布に従うサンプルを用いて確率を計算すれば,事後分布を数式として求める必要もな
いし,分布関数の積分も必要ない.
PyMC3 の基本
• General API Quickstart: https://docs.pymc.io/notebooks/api_quickstart.html
• モデルは with pm.Model() ブロック内に記述する.
• 尤度の定義では observed 引数にデータを添付する.
• 非確率変数は通常の変数定義で良い.ただし確率変数のサンプルと一緒に記録したければ
pm.Deterministic() を使って定義する.
コード 1 メッセージ数の変化
1 import numpy as np
2 import pymc3 as pm
3
4 count_data = np.loadtxt("data/txtdata.csv")
5
6 n_count_data = len(count_data)
7 alpha = 1.0 / count_data.mean()
8 idx = np.arange(n_count_data) # 0 から n_count_data-1 までの index の配列を作成
9
10 with pm.Model() as model: # モデル定義
11 lambda_1 = pm.Exponential("lambda_1", alpha)
12 lambda_2 = pm.Exponential("lambda_2", alpha)
13 tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data)
14 lambda_ = pm.math.switch(tau >= idx, lambda_1, lambda_2)
15 obs = pm.Poisson("obs", lambda_, observed=count_data)
16
17 with model:
18 trace = pm.sample(40000) # サンプルの生成
コード 2 モデル定義ブロック部分
with pm.Model() as model:
# 事前分布(確率変数)の定義
lambda_1 = pm.Exponential("lambda_1", alpha)
lambda_2 = pm.Exponential("lambda_2", alpha)
tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data)
# idx の値に応じて変わる lambda 確率変数の定義
lambda_ = pm.math.switch(tau >= idx, lambda_1, lambda_2)
# 尤度の定義
obs = pm.Poisson("obs", lambda_, observed=count_data)
pm.model_to_graphviz(model)
pm.traceplot(trace)
西南学院大学 演習 II(2019 年) 4 担当 市東 亘
pm.plot_posterior(trace)
pm.summary(trace)
西南学院大学 演習 II(2019 年) 5 担当 市東 亘

演習II.第1章 ベイズ推論の考え方 Part 3.講義ノート

  • 1.
    第1章 ベイズ推論の考え方 Part3 市東 亘 2021 年 8 月 23 日 1 概観 テキスト「Python で体験するベイズ推論」pp.15–24 例題: メッセージ数に変化はあるか? • 分析の背後にある統計モデルを理解する. • PyMC3 による実装方法を学ぶ. 2 例題: メッセージ数に変化はあるか? 目的 • メッセージ数がある時点を境に変化したと言えるか? • 変化したならいつ? 0 10 20 30 40 50 60 70 Time (days) 0 10 20 30 40 50 60 70 count of text-msgs received Did the user's texting habits change over time? 図 1: メッセージ受信数 モデル ポアッソン分布 • ある期間を等間隔の区間に分け,その区間に生起するイベントが, – すべての区間で平均的に同じ率で観測され, 1
  • 2.
    – 各イベントがこれまでに観測されたイベントに依存せず独立ならば, ⇒ ポアソン分布に従う. •非負の整数値をとる確率変数 X がポアソン分布に従うとき,確率分布は以下で与えられる. P({X = k}) = λk e−λ k! パラメータ λ > 0 は事象が生起する強度(intensity)を表す. • ポアソン分布の期待値と分散 – E[X] = λ – V ar[X] = λ メッセージ数の確率モデル • メッセージ数 x はポアッソン分布に従うと仮定する. ⇒ xt ∼ Poisson(λ) • E[X] = λ より λ はメッセージ受信数の期待値を表す. • ある時期を境にメッセージ受信数の変化があったかどうかをモデル化するには,ポアッソン 分布のパラメータ λ(メッセージ受信数の期待値)がある時期を境に変化したかを検証すれ ば良い. ⇒ 言い換えると,ある時期を境にメッセージ受信数が従うポアッソン分布に変化が生じた かを検証していることになる. • 確率モデルのまとめ xt ∼ Poisson(λ) where λ = { λ1 for t < τ λ2 for t ≥ τ ベイズ推定の復習 • データを所与の定数として,統計モデルのパラメータを確率変数として考えるのがベイズ 推定. Pr(H|D) = Pr(D|H)Pr(H) Pr(D) ∝ Pr(D|H)Pr(H) f(θ|x) ∝ f(x|θ)f(θ) • 我々が求めたいのはデータが従う統計モデルのパラメータの事後分布関数 ⇒ f(λ|x) ∝ f(x|λ)f(λ), ただし,x はメッセージ数のデータを表す. 西南学院大学 演習 II(2019 年) 2 担当 市東 亘
  • 3.
    ベイズモデル • ここでは λは λ1, λ2, τ に依存して値が決まるとモデル化する. f(λ|x) ∝ f(x|λ)f(λ) ↔ f({λ1, λ2, τ}|x) ∝ f(x|{λ1, λ2, τ})f({λ1, λ2, τ}) = f(x|{λ1, λ2, τ})f(λ1)f(λ2)f(τ) – 尤度関数: f(xt|{λ1, λ2, τ}) = λxt e−λ xt! , where { λ1 for t < τ λ2 for t ≥ τ – 事前分布: f(τ) =? – 事前分布: f(λi) =? for i = 1, 2 • τ の事前分布を考える – τ はメッセージ数に変化が生じたと考えられる期日. – 特に特定の日に変化が生じたという信念はない. ⇒ 期日全体に一様に分布していると考えられる. ⇒ 理由不十分の原則 – 事前分布: f(τ) = DiscreteUniform(1, 70) • λi の事前分布を考える – λi はポアッソン分布のパラメータで λi > 0. – 非負の確率変数が従う指数分布が使えそう. ⇒ 事前分布は主観的であることを思い出そう! – 事前分布: f(λi) = eα , for i = 1, 2 ただし,α = ( ∑ xt/N)−1 で定数とする. – パラメータ α をこの様に定義すると各区間のメッセージ数の期待値を表す λ と整合的 になる. ⇒ 指数分布の期待値より E[λ] = 1/α. ⇒ 1/α が区間におけるメッセージ数の期待値に適合するように 1/α = ∑ xt/N と定義. – λi の分布はさらに別のパラメータ α に依存することになった! • メッセージ数のベイズモデルまとめ f({λ1, λ2, τ}|x) ∝ f(x|{λ1, λ2, τ})f(λ1)f(λ2)f(τ) – 尤度関数: f(xt|{λ1, λ2, τ}) = λxt e−λ xt! , where { λ1 for t < τ λ2 for t ≥ τ – 事前分布: f(τ) = DiscreteUniform(1, 70) – 事前分布: f(λi) = eα for i = 1, 2 ただし,α = ( ∑ xt/N)−1 で定数とする. 西南学院大学 演習 II(2019 年) 3 担当 市東 亘
  • 4.
    確率的プログラミング • 前ページで定義した事前分布と尤度関数を全て定義すれば,Stan やPyMC3 等のプログラム が事後分布に従うサンプルを生成してくれる. • 事後分布に従うサンプルを用いて確率を計算すれば,事後分布を数式として求める必要もな いし,分布関数の積分も必要ない. PyMC3 の基本 • General API Quickstart: https://docs.pymc.io/notebooks/api_quickstart.html • モデルは with pm.Model() ブロック内に記述する. • 尤度の定義では observed 引数にデータを添付する. • 非確率変数は通常の変数定義で良い.ただし確率変数のサンプルと一緒に記録したければ pm.Deterministic() を使って定義する. コード 1 メッセージ数の変化 1 import numpy as np 2 import pymc3 as pm 3 4 count_data = np.loadtxt("data/txtdata.csv") 5 6 n_count_data = len(count_data) 7 alpha = 1.0 / count_data.mean() 8 idx = np.arange(n_count_data) # 0 から n_count_data-1 までの index の配列を作成 9 10 with pm.Model() as model: # モデル定義 11 lambda_1 = pm.Exponential("lambda_1", alpha) 12 lambda_2 = pm.Exponential("lambda_2", alpha) 13 tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data) 14 lambda_ = pm.math.switch(tau >= idx, lambda_1, lambda_2) 15 obs = pm.Poisson("obs", lambda_, observed=count_data) 16 17 with model: 18 trace = pm.sample(40000) # サンプルの生成 コード 2 モデル定義ブロック部分 with pm.Model() as model: # 事前分布(確率変数)の定義 lambda_1 = pm.Exponential("lambda_1", alpha) lambda_2 = pm.Exponential("lambda_2", alpha) tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data) # idx の値に応じて変わる lambda 確率変数の定義 lambda_ = pm.math.switch(tau >= idx, lambda_1, lambda_2) # 尤度の定義 obs = pm.Poisson("obs", lambda_, observed=count_data) pm.model_to_graphviz(model) pm.traceplot(trace) 西南学院大学 演習 II(2019 年) 4 担当 市東 亘
  • 5.