Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Turing.jl によるベイジアンなデータ分析 Bayesian Data Analysis with Turing.jl (JuliaTokyo #10)

Turing.jl によるベイジアンなデータ分析
Bayesian Data Analysis with Turing.jl
(including comparison with Gen.jl and PyMC3)
JuliaTokyo #10 https://juliatokyo.connpass.com/event/153435/
November 29, 2019
Ryo Yamamoto

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

Turing.jl によるベイジアンなデータ分析 Bayesian Data Analysis with Turing.jl (JuliaTokyo #10)

  1. 1. Turing.jl による ベイジアンなデータ分析 Bayesian Data Analysis with Turing.jl November 29, 2019 ⼭本遼Ryo Yamamoto Speee, Inc. JuliaTokyo #10 1
  2. 2. ⾃⼰紹介  ⼭本遼Ryo Yamamoto  GitHub: @ryoyam  Twitter: @ryoyam11 データサイエンティスト/ ビジネストランスレーター@ Speee, Inc. 「PAAM」(データ活⽤によるマーケティング⽀援サービス) で 主にPython を利⽤してデータ分析を⾏っています Julia でのデータ分析ツール・事例が増えているトレンドを踏まえ、 状況に応じて導⼊を検討できるよう調査・使⽤中です JuliaTokyo #10 2
  3. 3. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 3
  4. 4. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 4
  5. 5. はじめに: ベイズ推論とPPL の概要 JuliaTokyo #10 5
  6. 6. ベイズ推論の考え⽅ 確率を「事象に対する確信度」として扱い、 観測データに基づき更新していく(事前分布→事後分布) “データ⽣成の背後にある構造” (確率モデル) を表現し、 実際の観測データによって具体形を推し量ることができる 従来(non-Bayesian) の機械学習と⽐べ、得られる情報が多い: 従来: 最適化後の「点」 vs ベイズ推論: 潜在変数/観測変数の「分布」 JuliaTokyo #10 6
  7. 7. ベイズ推論を実⾏するには 実際は推論結果を解析的に求められない場合も多く、 様々な近似推論法がある サンプリング(例. MCMC) 変分推論etc. PPL (Probabilistic Programming Language): 確率モデルを記述し、推論を⾏うための⾔語(ツール) ※厳密にはベイズ推論に限定されない JuliaTokyo #10 7
  8. 8. PPL の選択肢 Stan, JAGS Python PyMC3 その他: Pyro, Edward2 etc. Julia Turing.jl Gen.jl その他: Mamba.jl etc. JuliaTokyo #10 8
  9. 9. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 9
  10. 10. Turing.jl による ビジネスデータの分析例 JuliaTokyo #10 10
  11. 11. 例題 次のようなケースを考えます: あるEC サイトの運営者からの分析依頼 ⾃社ブランドを気に⼊ってくれそうな潜在顧客に 早期からアプローチし、購⼊につなげたい そこで、⾃社サイトの「アクセスログ」を使って、 どのようなユーザーであれば再訪してくれるか (傾向, 条件) を知りたい JuliaTokyo #10 11
  12. 12. 利⽤可能なデータ(アクセスログ) ユーザーがWeb サイトを訪れた際、 ブラウザごとに⼀意なID を発⾏して 「訪問時刻」 「訪問したページのURL」 「流⼊元(訪問直前に閲覧していた外部Web サイト) のURL 」 などを記録したもの 2回⽬以降の訪問時は、初回訪問時のID で同様に記録し、 ユーザーの閲覧⾏動を追跡できる JuliaTokyo #10 12
  13. 13. 分析にあたって置く仮説 訪問初⽇の合計閲覧回数が多いユーザーほど、 再訪しやすいのでは? ⾃社ブランドと関連性が⾼い流⼊元(“重要な流⼊元”) から やってくるユーザーほど、再訪しやすいのでは? 例. Twitter の公式アカウントのページ ⾃社ブランドについて詳しく紹介したページ(“重要なページ”) を 訪れるユーザーほど、再訪しやすいのでは? 例: 個別商品に関するページ JuliaTokyo #10 13
  14. 14. 分析課題 ある期間にサイトを新たに訪れたユーザー(約200,000 件) ごとに: 初回訪問⽇の合計閲覧回数(≧1) 初回訪問⽇に1回以上“重要な流⼊元” から訪問したか(0=No, 1=Yes) 初回訪問⽇に1回以上“重要なページ” を訪問したか(0=No, 1=Yes) ↓予測(ロジスティック回帰による2値分類) ⾃社サイトを初回訪問⽇から30⽇以内に再訪したか(0=No, 1=Yes) JuliaTokyo #10 14
  15. 15. 確率モデルの定義 ロジスティック回帰による2値分類 潜在変数: 各特徴量の係数・切⽚(それぞれ正規分布を想定) JuliaTokyo #10 15
  16. 16. 確率モデルの定義※ここからTuring.jl @model logistic_model(X, y) = begin m = 0 s = 10 intercept ~ Normal(m, s) w_pvs ~ Normal(m, s) w_domain ~ Normal(m, s) w_cat ~ Normal(m, s) for i = 1:size(X, 1) p = logistic(intercept + (w_pvs * X[i, 1]) + ...) y[i] ~ Bernoulli(p) end end JuliaTokyo #10 16
  17. 17. 推論 model_observed = logistic_model(X, y) n_samples = 20000 sampler = NUTS(10000, ...) chain = sample(model_observed, sampler, n_samples) バーンイン(初期のチェインの削除) の指定⽅法に注意 例: 20,000点サンプルし、うち最初の10,000点を捨てる場合 sample(model(), NUTS(10000, ...), 20000) ※この仕様は2019年10⽉から(詳細) JuliaTokyo #10 17
  18. 18. 推論結果の検証 チェイン(サンプリング結果) に関する指標やプロットを確認 →収束性の判断: ⾃⼰相関, チェイン間の差異etc. 例. トレースプロット+ KDE プロット(各特徴量の係数) JuliaTokyo #10 18
  19. 19. JuliaTokyo #10 19
  20. 20. 推論結果の検証 指標の算出・プロット機能とも⽐較的充実 summarystats() , gelmandiag() , quantile() plot() , traceplot() , autocorplot() , corner() 変数の順序がモデル定義時/ 評価の出⼒時で⾒かけ上変わる ⼀部指標の値が正確でない 例. ESS (開発者からも⾔及あり) JuliaTokyo #10 20
  21. 21. 予測(1) 確率パラメータ 推論結果から潜在変数の組を再度サンプリングし、 それぞれ予測値を算出、プロット 横軸: 合計閲覧回数 縦軸: 確率パラメータ 「重要なページ」 への訪問なし 「重要なページ」 への訪問あり 「重要な流⼊元」 からの訪問なし 「重要な流⼊元」 からの訪問あり (StatsPlots.jl を利⽤) JuliaTokyo #10 21
  22. 22. 予測(2) 再訪有無 予測(1) の中央値をとり、 しきい値を適⽤ 今回はAUC = 0.58 (→モデリングの⼯夫が必要) (ScikitLearn.jl + StatsPlots.jl を利⽤) ※AUC を計算するツールがまだ少なそう JuliaTokyo #10 22
  23. 23. 予測 予測をワンストップで⾏う機能はない 「潜在変数の事後分布のサンプリング」+「予測値の算出」 を順に⾏う必要がある JuliaTokyo #10 23
  24. 24. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 24
  25. 25. その他のPPL との使⽤感の⽐較 JuliaTokyo #10 25
  26. 26. ⽐較対象 Turing.jl (分析例で紹介) v0.7.2, v0.7.3 Gen.jl v0.3.1 PyMC3 v3.7 JuliaTokyo #10 26
  27. 27. Gen.jl の使⽤感 特徴 General-purpose = MCMC 以外の⼿法もカバー 確率モデルの定義: 他ツールと似た構⽂ 推論: low-level な部分をカスタマイズできる サンプル1回ごとに値の更新⽅法(update) の指定 提案分布(proposal) の指定etc. JuliaTokyo #10 27
  28. 28. (例. HMC での推論) Turing.jl sample(model(train), HMC(...), n_samples) Gen.jl ... for iter=1:n_samples (tr, _) = hmc(tr, select(:var), ...) end ... JuliaTokyo #10 28
  29. 29. Gen.jl の使⽤感 注意点 「更新」「観測データの設定」のコードを毎度書く必要がある 更新⽅法を⾃動的にチューニングする機能はない 例. HMC はあるがNUTS はない まだpre-release →現状では、実務で⼿軽に使いたい場合には向かない JuliaTokyo #10 29
  30. 30. Gen.jl の使⽤感 注意点 実⽤⾯からは「あると嬉しい」機能が少ない: 収束性の検証のための機能 可視化の機能 GenViz.jl: 各更新におけるスナップショットを可視化できる が、traceplot, autocorplot などは出せない 予測(PPC) の機能 JuliaTokyo #10 30
  31. 31. PyMC3 の使⽤感 特徴 (Python ゆえ) Jupyter Notebook 上でもストレスがない速さ ⼀部モデルの定義が⼿軽: GLM.from_formula('y ~ x1 + x2', df) 各種指標・推定値の算出, プロットの機能が充実 MAP 推定: find_MAP() 事後分布とHDI の可視化: plot_posterior() etc. 予測が⼿軽: sample_posterior_predictive() JuliaTokyo #10 31
  32. 32. PyMC3 の使⽤感 注意点 PyMC3 はv3.7 で開発終了、PyMC4 がリリース予定(参考) ⼤幅な仕様変更の可能性も JuliaTokyo #10 32
  33. 33. 推論時間の計測: Turing.jl (Julia 1.3) / PyMC3 図: チェイン数に対する実⾏時間 (real time) の平均値・標本標準偏差 ※条件 環境: iMac (Retina 5K, 27 inch, Late 2015; 8-core) + Docker containers (16GiB memory; Turing v0.7.3 on julia:1.3.0-stretch / PyMC3 v3.7 on python:3.7-stretch) 観測データ: 約9,000点(4%) サンプラー: NUTS (20,000 samples/chain; ⽬標採択率0.8) 計測対象: モデル定義(前節)+推論+結果の出⼒ 計測回数: 各PPL・チェイン数に対し5回 JuliaTokyo #10 33
  34. 34. 補⾜ Turing.jl の場合の注意点 Julia v1.3.0 で並列実⾏しようとするとエラーとなった Github 上の回避策を使うと無事動作した JuliaTokyo #10 34
  35. 35. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 35
  36. 36. おわりに: 実⽤的観点からの所感 PPL の選択について 機能⾯: PyMC3 がカバレッジ・⼿軽さとも勝る 速度⾯: Turing.jl はPyMC3 と同等かそれ以上の⽔準 今後について Julia 製ツールの多くは今まさに発展途中という印象 実務で本格的に利⽤できる⽇が楽しみ JuliaTokyo #10 36
  37. 37. 参考⽂献 Julia を学ぶにあたり、活⽤させていただきました: Kamiński et al., Julia プログラミングクックブック, O'Reilly, 2019 佐藤他, はじめてのJulia, WEB+DB PRESS vol. 111, 技術評論社, 2019 JuliaTokyo #10 37
  38. 38. 本⽇お話しすること はじめに: ベイズ推論とPPL の概要 Turing.jl によるビジネスデータの分析例 その他のPPL との使⽤感の⽐較 おわりに: 実⽤的観点からの所感 JuliaTokyo #10 38
  39. 39. 終 ありがとうございました JuliaTokyo #10 39
  40. 40. JuliaTokyo #10 40
  41. 41. Appendices JuliaTokyo #10 41
  42. 42. Turing.jl: モデル定義 @model logistic_model(X::Matrix{Float64}, y::Vector{Float64}) = begin m = 0 s = 10 intercept ~ Normal(m, s) w_pvs ~ Normal(m, s) w_domain ~ Normal(m, s) w_cat ~ Normal(m, s) for i = 1:size(X, 1) p = logistic( intercept + (w_pvs * X[i, 1]) + (w_domain * X[i, 2]) + (w_cat * X[i, 3]) ) y[i] ~ Bernoulli(p) end end JuliaTokyo #10 42
  43. 43. Turing.jl: 推論 model_observed = logistic_model(X_train, y_train) n_samples = 20000 sampler = NUTS(10000, 0.8) chain = sample(model_observed, sampler, n_samples) JuliaTokyo #10 43
  44. 44. Turing.jl: 推論(並列化) Julia v1.2.0 using Distributed; addprocs(N_CORES) @everywhere using Turing @everywhere @model logistic_model(data) = begin ... end reduce( chainscat, pmap(x -> sample(logistic_model(data), ...), 1:n_chains) ) JuliaTokyo #10 44
  45. 45. Turing.jl: 推論(並列化) Julia v1.3.0 + Turing.jl v0.7.3 ... function wrapper(model, data, n_samples, ...) return reduce( chainscat, pmap(x -> sample(model(data), ...), 1:n_samples) ) end wrapper(model, data, n_samples, ...) ... JuliaTokyo #10 45
  46. 46. Gen.jl: モデル定義 @gen function logistic_model(X::Matrix{Float64}) m = 0 s = 10 intercept = @trace(normal(m, s), :intercept) w_pvs = @trace(normal(m, s), :w_pvs) w_domain = @trace(normal(m, s), :w_domain) w_cat = @trace(normal(m, s), :w_cat) n = size(X, 1) y = Vector{Float64}(undef, n) for i = 1:n p = logistic( intercept + w_pvs * X[:, 1] + w_domain * X[:, 2] + w_cat * X[:, 3] ) y[i] = @trace(bernoulli(p), :data => i => :y) end ys end JuliaTokyo #10 46
  47. 47. Gen.jl: 推論 function make_constraints(ys::Vector{Float64}) constraints = Gen.choicemap() for i=1:length(ys) constraints[:data => i => :y] = ys[i] end constraints end function update(tr) (xs,) = get_args(tr) for i=1:length(xs) (tr, _) = mh(tr, select(:data => i => :is_outlier)) end end function infer(xs::Vector{Float64}, ys::Vector{Float64}) observations = make_constraints(ys) (tr, _) = generate(model, (xs,), observations) for iter=1:500 tr = update(tr) end tr end JuliaTokyo #10 47
  48. 48. PyMC3: モデル定義 X, y = ... with pm.Model() as logistic_model: m = 0 s = 10 intercept = pm.Normal("intercept", mu=m, sigma=s) w_pvs = pm.Normal("w_pvs", mu=m, sigma=s) w_domain = pm.Normal("w_domain", mu=m, sigma=s) w_cat = pm.Normal("w_cat", mu=m, sigma=s) p = pm.math.invlogit( intercept + w_pvs * X[:, 0] + w_domain * X[:, 1] + w_cat * X[:, 2] ) y_ = pm.Bernoulli("y", p=p, observed=y) JuliaTokyo #10 48
  49. 49. PyMC3: 推論 with logistic_model: step = pm.NUTS(target_accept=0.8) trace = pm.sample( draws=10000, tune=10000, chains=2, cores=2, step=step, ... ) JuliaTokyo #10 49
  50. 50. Turing.jl: References Cameron Pfiffer, Turing: Probabalistic Programming in Julia, JuliaCon 2019. Hong Ge, Kai Xu, and Zoubin Ghahramani, Turing: a language for flexible probabilistic inference, AISTATS 2018. JuliaTokyo #10 50
  51. 51. JuliaTokyo #10 51

×