1. 勾配を用いる必要性
対数事後分布の勾配を計算するのが今後のアプローチのコアである。
1.2 勾配を用いた計算の効率化
歴史上、統計が実戦で応用されるまでに計算機やアルゴリズムの発展を待つ必要があったのはこのような計算効率の問題があったためであった。これに対して、近年では連鎖法や近似、逐次法や変分推論などの計算手法が登場し、現実的な推論計算手段を提供するようになってきた。これらは「無駄な計算を省き、重要な計算のみ重点的に行う」というアイディアの下で開発されてきた。
目的とな事後分布について勾配を計算すると、勾配は各時点で事後分布の密度が高い場所の向きを表し、標本が発生しやすい方向を選択することができる。
事後分布の勾配を利用することでサンプリングを効率化できる。勾配が分かっていれば、「勾配の矢印が向いている先の領域においてより多くの標本を発生させ、逆に向いていない領域からはあまり標本を発生させない」ことによってそうした勾配=分布に従う標本を生成できそうである。ただしただただ密度の高い部分からサンプリングしたのでは真の事後分布からサンプリングしたとは言い難い。 法はそのバランスを上手く取るようにしている。
もう1つの方法として、事後分布をより扱いやすい分布を用いて近似・簡略化する方法がある。近似手法はサンプリングよりも高速であるものの、正規分布などの(極度に)簡単な分布に簡略化するために、事後分布の近似能力は低く(=粗く)なることが多い。
1.2.2 ラッパー関数を挟む
### ラッパー関数を挟む ### :関数外の変数を直接参照するとJuliaの計算速度が著しく低下する ### :そこでラッパー関数を挟んで、計算に必要なデータやパラメータをすべて関数の引数として与える # 最適化パラメータ w₁_init = 0.0 maxiter = 100 η = 0.01 # 最適化ラッパー関数の定義 function inference_wrapper_gd_1dim(log_joint, params, w₁_init, η, maxiter) ulp(w₁) = log_joint(w₁, params...) w₁_seq = gradient_method_1dim(ulp, w₁_init, η, maxiter) w₁_seq end # 対数同時分布 log_joint(w₁, X, Y, w₂,σ,μ₁,σ₁) = sum(logpdf.(Normal.(w₁*X.+w₂,σ), Y)) + logpdf(Normal(μ₁,σ₁), w₁) params = (X_obs, Y_obs, w₁_init, σ, μ₁, σ₁) # 最適化の実施 w₁_seq = inference_wrapper_gd_1dim(log_joint, params, w₁_init, η, maxiter) ############# w₁_init = 0.0 maxiter = 1_000_000 η = 0.01 # グローバル変数を参照する場合 @time gradient_method_1dim(ulp, w₁_init, η, maxiter) # ラッパーを用いる場合 @time inference_wrapper_gd_1dim(log_joint, params, w₁_init, η, maxiter)