0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Turingで度数分布からGamma分布のパラメータを調べる

Posted at

モチベーション

1次データが手に入らずおおまかな度数分布しかないとき、限られたデータ(度数分布/分位数)からサンプルのGamma分布をTuringで調べたい。
gamma-question.png

Gamma分布!

この記事の続きです。マラソンランナーの到着時間を標準分布で推定しましたが、それぞれ独立した事象(ランナー)の到着時間を表すガンマー分布のほうが適したモデルかもしれない。そこで度数データで推定したいのですが、実はJuliaのgammacdf関数が自動微分をサポートしないので、前項で示した分位数から推定する方法ではエラーになってしまいます。

    MethodError: no method matching __gamma_inc_inv(::ForwardDiff.Dual{ForwardDiff.Tag{Turing.TuringTag, Float64}, Float64, 4}, ::ForwardDiff.Dual{ForwardDiff.Tag{Turing.TuringTag, Float64}, Float64, 4}, ::Bool)
    Closest candidates are:
      __gamma_inc_inv(::T, ::T, ::Bool) where T<:Union{Float16, Float32} at C:\Users\xxxxxx\.julia\packages\SpecialFunctions\hefUc\src\gamma_inc.jl:1089
      __gamma_inc_inv(::Float64, ::Float64, ::Bool) at C:\Users\xxxxxx\.julia\packages\SpecialFunctions\hefUc\src\gamma_inc.jl:1012
    
    Stacktrace:....省略

どうやらSpecialFunctionsパッケージの関数__gamma_inc_invが自動微分(ForwardDiff)のstructを認識できないのでこれを強引に食わせることで解決をはかります。gamma_inc_invは不完全ガンマ函数gamma_incの逆関数。

    using ForwardDiff,StatsFuns,SpecialFunctions
    function SpecialFunctions.__gamma_inc_inv(a::ForwardDiff.Dual{T}, 
            minpq::ForwardDiff.Dual{T}, pcase::Bool) where {T}
        v_a= ForwardDiff.value(a)
        v_pq = ForwardDiff.value(minpq)
        SpecialFunctions.__gamma_inc_inv(v_a,v_pq,pcase)
    end

Toyデータを次のように準備する。

    q4 = quantile(Gamma(3,1.5),0.4) #q4= 3.427615356005071
    q2 = quantile(Gamma(3,1.5),0.2) #q2= 2.302566303966965

モデルを次のように定義して実行する。

    @model function gdemo()
        m ~ InverseGamma(2,3)
        s ~ InverseGamma(2,3)
        dist = Gamma(m,s)
        
        y4 ~ Normal(quantile(dist,0.4),0.1)
        y2 ~ Normal(quantile(dist,0.2),0.1)
        
        y4 ~ Normal(q4,0.1) #q4 is a constance , 3.4276
        y2 ~ Normal(q2,0.1) #q2 is a constance , 2.3025
    end   
    
    c = sample(gdemo(),NUTS(),6000)

結果は次の通りで正解に近似した結果が得られた。

Summary Statistics
      parameters      mean       std   naive_se      mcse       ess      rhat   es ⋯
          Symbol   Float64   Float64    Float64   Float64   Float64   Float64      ⋯
    
               m    3.0844    0.8489     0.0110    0.0841   46.3321    1.0234      ⋯
               s    1.6008    0.5086     0.0066    0.0485   52.3757    1.0242      ⋯
                                                                    1 column omitted
    Quantiles
      parameters      2.5%     25.0%     50.0%     75.0%     97.5% 
          Symbol   Float64   Float64   Float64   Float64   Float64 
    
               m    1.9430    2.4611    2.8759    3.5576    5.0975
               s    0.7607    1.2086    1.5787    1.9368    2.6341

quantileはうまくいくがcdf関数はうまくいかない。

gammacdf関数が呼び出すgamma_incのAuto Difference対応は難しそうでお手上げ。しかし知っている情報が階級数と分位数だけなら、cdfでもquantileでも構わないのでとりあえず良しとする。

マラソンのランナー分布

前回の課題であった北海道マラソンのランナー到着時間分布をGamma分布で推定した結果を掲載する。ガンマ分布を採用した場合95%の確信区間として211分~317分と推定できる。

累積度数分布 標準分布 ガンマ分布
1 0.001820 0.002075 0.001080
2 0.003389 0.004362 0.003015
3 0.008913 0.008685 0.007355
4 0.017324 0.016384 0.015944
5 0.035652 0.029310 0.031169
6 0.054105 0.049763 0.055634
7 0.085865 0.080268 0.091634
8 0.130304 0.123147 0.140568
9 0.179450 0.179960 0.202470
10 0.238137 0.250907 0.275820
11 0.319232 0.334413 0.357692
12 0.844652 0.849784 0.815851
13 1.0 0.999963 0.998646

marathon-3graph.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?