using Turing
using StatsPlots
using Random
using Suppressor
using DataFrames
Random.seed!(1234)
TaskLocalRNG()
@model function gdemo(x::AbstractArray{<:Real})
# Prior of Target Parameter
# P(s²,m) = P(s²)P(m)
# P(s²) ∝ pdf(InverseGamma(2,3),s²)
s² ~ InverseGamma(2,3)
# P(m) ∝ pdf(Normal(0, √s²),s²)
m ~ Normal(0, √s²)
# Likelihood
# x = {x₁,x₂,...,xₙ}
# P(x|m,s²)
# P(x|m,s²) ∝ pdf.(Normal(m, √s²),x)
x ~ Normal(m, √s²)
#return
# pdf.(Normal(m, √s²),x)*Normal(0, √s²)*pdf(InverseGamma(2,3),s²)
# return x
end
gdemo (generic function with 2 methods)
# Make test sample
# x ~ Normal(3.5, 2.0)
x = rand(Normal(2.5, √2.0), 300)
density(x, label="Probability Density of x")
samples = sample(gdemo(x), NUTS(),1000)
┌ Info: Found initial step size └ ϵ = 0.2 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
Chains MCMC chain (1000×14×1 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 1 Samples per chain = 1000 Wall duration = 10.03 seconds Compute duration = 10.03 seconds parameters = s², m internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s² 2.3377 0.1950 0.0065 955.6722 640.0229 1.0081 ⋯ m 2.3511 0.0888 0.0027 1061.0144 843.2654 0.9995 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s² 2.0204 2.2034 2.3190 2.4602 2.7617 m 2.1845 2.2896 2.3513 2.4093 2.5246
fieldnames(typeof(samples))
(:value, :logevidence, :name_map, :info)
samples.name_map
(parameters = [:s², :m], internals = [:lp, :n_steps, :is_accept, :acceptance_rate, :log_density, :hamiltonian_energy, :hamiltonian_energy_error, :max_hamiltonian_energy_error, :tree_depth, :numerical_error, :step_size, :nom_step_size])
plot(samples)
samples[:m][1:3] |> display
1-dimensional AxisArray{Float64,1,...} with axes: :row, Base.OneTo(3) And data, a 3-element Vector{Float64}: 2.5001000822783443 2.3754059003239014 2.355634943865946
samples[:s²][1:3] |> display
samples["s²"][1:3]|> display
1-dimensional AxisArray{Float64,1,...} with axes: :row, Base.OneTo(3) And data, a 3-element Vector{Float64}: 2.374601897723656 2.1637177928075286 2.2423605153574666
1-dimensional AxisArray{Float64,1,...} with axes: :row, Base.OneTo(3) And data, a 3-element Vector{Float64}: 2.374601897723656 2.1637177928075286 2.2423605153574666
# sample(model, sampler, parallel_type, n, n_chains)
samples = sample(gdemo(x),NUTS(),MCMCThreads(),1000,5)
p1 = plot(samples)
fieldnames(typeof(samples)) |> display
size(samples) |> display
size(samples[:m]) |> display
(mean(samples[:m]) , mean(samples[:s²])) |> display
plot(p1)
┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.4 ┌ Info: Found initial step size └ ϵ = 0.2 ┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.0125
(:value, :logevidence, :name_map, :info)
(1000, 14, 5)
(1000, 5)
(2.3540283799147232, 2.3274197580434497)
samples[:,:,1]
Chains MCMC chain (1000×14×1 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 1 Samples per chain = 1000 Wall duration = 0.48 seconds Compute duration = 1.28 seconds parameters = s², m internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s² 2.3299 0.1875 0.0062 932.9716 654.7551 1.0000 ⋯ m 2.3572 0.0896 0.0026 1187.4449 735.2058 1.0001 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s² 1.9799 2.2008 2.3186 2.4470 2.7127 m 2.1927 2.2958 2.3554 2.4200 2.5372
@model function gdemo(x)
n = length(x)
s²= Vector{Real}(undef,n)
m = Vector{Real}(undef,n)
for i in eachindex(x)
s²[i] ~ InverseGamma(2,3)
m[i] ~ Normal(0, √(s²[i]))
x[i] ~ Normal(m[i],√(s²[i]))
end
end
x = rand(Normal(2.5, √2.0), 200)
y = rand(Normal(-1.0, √3.0), 200)
p1 = density(x, label="Probability Density of x")
density!(p1,y, label="Probability Density of y") |> display
model = gdemo([x,y])
samples = sample(model, NUTS(), MCMCThreads(), 1000, 5)
samples |> display
plot(samples)
┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.2 ┌ Info: Found initial step size └ ϵ = 0.05
Chains MCMC chain (1000×16×5 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 5 Samples per chain = 1000 Wall duration = 5.01 seconds Compute duration = 24.59 seconds parameters = s²[1], s²[2], m[1], m[2] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s²[1] 1.6677 0.1632 0.0020 6988.8789 4163.0998 1.0007 ⋯ s²[2] 3.3253 0.3276 0.0039 7113.3700 4380.5059 1.0003 ⋯ m[1] 2.2191 0.0920 0.0010 7790.1820 4024.6893 1.0005 ⋯ m[2] -0.8220 0.1277 0.0015 7296.1149 3641.5370 0.9999 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s²[1] 1.3851 1.5530 1.6569 1.7733 2.0131 s²[2] 2.7434 3.0999 3.3094 3.5232 4.0239 m[1] 2.0405 2.1579 2.2176 2.2807 2.4021 m[2] -1.0749 -0.9065 -0.8207 -0.7358 -0.5739
samples["m[1]"][1:2] |> display
group(samples,"m") |> display
1-dimensional AxisArray{Float64,1,...} with axes: :row, Base.OneTo(2) And data, a 2-element Vector{Float64}: 2.150920623843303 2.2805898485444533
Chains MCMC chain (1000×2×5 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 5 Samples per chain = 1000 Wall duration = 5.01 seconds Compute duration = 24.59 seconds parameters = m[1], m[2] internals = Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ m[1] 2.2191 0.0920 0.0010 7790.1820 4024.6893 1.0005 ⋯ m[2] -0.8220 0.1277 0.0015 7296.1149 3641.5370 0.9999 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 m[1] 2.0405 2.1579 2.2176 2.2807 2.4021 m[2] -1.0749 -0.9065 -0.8207 -0.7358 -0.5739
using Distributed
let
n_process = 4
addprocs(n_process)
# 모든 process에서 turing과 model을 사용할 수 있게
@everywhere using Turing
@everywhere @model function gdemo(x)
n = length(x)
s²= Vector{Real}(undef,n)
m = Vector{Real}(undef,n)
for i in eachindex(x)
s²[i] ~ InverseGamma(2,3)
m[i] ~ Normal(0, √(s²[i]))
x[i] ~ Normal(m[i],√(s²[i]))
end
end
@everywhere x = rand(Normal(2.5, √2.0), 200)
@everywhere y = rand(Normal(-1.0, √3.0), 200)
p1 = density(x, label="Probability Density of x")
density!(p1,y, label="Probability Density of y") |> display
@everywhere model = gdemo([x,y])
samples = sample(model, NUTS(), MCMCThreads(), 1000, 5)
samples |> display
plot(samples)
end
┌ Info: Found initial step size └ ϵ = 0.025 ┌ Info: Found initial step size └ ϵ = 0.025 ┌ Info: Found initial step size └ ϵ = 0.05 ┌ Info: Found initial step size └ ϵ = 0.025 ┌ Info: Found initial step size └ ϵ = 0.05
Chains MCMC chain (1000×16×5 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 5 Samples per chain = 1000 Wall duration = 1.4 seconds Compute duration = 5.67 seconds parameters = s²[1], s²[2], m[1], m[2] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s²[1] 1.8682 0.1821 0.0021 7532.7276 3863.6923 1.0005 ⋯ s²[2] 2.6048 0.2585 0.0028 8597.8616 4103.2110 0.9999 ⋯ m[1] 2.5091 0.0954 0.0010 9175.4662 3751.2857 1.0003 ⋯ m[2] -0.9552 0.1111 0.0013 7586.4452 4357.6853 1.0018 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s²[1] 1.5476 1.7375 1.8564 1.9860 2.2552 s²[2] 2.1437 2.4223 2.5874 2.7659 3.1640 m[1] 2.3279 2.4458 2.5090 2.5723 2.6942 m[2] -1.1709 -1.0285 -0.9553 -0.8812 -0.7372
$ P(m,s^2,x_1,x_2) \propto P(x_1) \cdot P(x_2) \cdot P(m) \cdot P(s^2)\\ $
using LaTeXStrings
let
@model function gdemo(x,y)
s² ~ InverseGamma(2,3)
m ~ Normal(0, √s²)
x ~ Normal(m, √s²)
y ~ Normal(m, √s²)
return x,y
end
# model을 함수 처럼 직접 호출하여 사전분포에서 sampling
# ※주의 : 모델에서 사용한 파라미터 m, s²를 vector로
# 사용하여 push!(m,v[1]) 을 호출하면 에러가 발생
# 하는데 이유는 모르겠으나 문제 발생하니
# model에서 사용한 파라미터(모수)는 파해야 함
g_prior_sample = gdemo(missing, missing)
σ² = Vector{Real}()
μ= Vector{Real}()
n_sample = 1000
for i in 1:n_sample
v = g_prior_sample()
push!(σ²,v[1])
push!(μ,v[2])
end
p1 = density(σ²,label=L"s^2")
p2 = density(μ, label="m")
"model을 함수처럼 호출하여사전분포에서 샘플링 하기" |> display
plot(p1,p2,layout=(1,2)) |> display
# sampler 통해 사전분포에서 샘플링 하기
model = gdemo(missing, missing)
samples = sample(model, Prior(), n_sample)
"Sampler를 통해 사전분포에서 샘플링 하기" |> display
plot(samples) |> display
samples
end
"model을 함수처럼 호출하여사전분포에서 샘플링 하기"
"Sampler를 통해 사전분포에서 샘플링 하기"
Chains MCMC chain (1000×5×1 Array{Float64, 3}): Iterations = 1:1:1000 Number of chains = 1 Samples per chain = 1000 Wall duration = 0.31 seconds Compute duration = 0.31 seconds parameters = s², m, x, y internals = lp Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s² 3.1413 6.7636 0.2198 893.6556 907.7013 1.0011 ⋯ m 0.0544 1.6973 0.0528 1008.9203 889.9348 0.9999 ⋯ x -0.0334 2.5532 0.0777 1080.0696 1030.6930 0.9995 ⋯ y 0.0303 2.3488 0.0737 985.3144 1025.7469 0.9994 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s² 0.5659 1.1395 1.7994 3.3211 13.1305 m -3.5274 -0.8647 0.0864 0.9247 3.7447 x -5.3766 -1.4937 0.0084 1.2415 5.3605 y -4.5638 -1.2242 -0.0006 1.3849 4.9284
let
@model function gdemo(x, ::Type{T} = Float64) where {T}
# 이 경우 x는 데이터가 아니라 파라미터로 취급 된다.
if x === missing
# Initialize `x` if missing
x = Vector{T}(undef,2)
end
s²~ InverseGamma(2,3)
m ~ Normal(0, √s²)
for i in eachindex(x)
x[i] ~ Normal(m, √s²)
end
end
# Construct a model with x = missing
model = gdemo(missing)
# c = sample(model, HMC(0.01,5), 500)
c = sample(model, NUTS(), 500)
plot(c) |> display
c |> display
end
┌ Info: Found initial step size └ ϵ = 0.42500000000000004 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
Chains MCMC chain (500×16×1 Array{Float64, 3}): Iterations = 251:1:750 Number of chains = 1 Samples per chain = 500 Wall duration = 4.15 seconds Compute duration = 4.15 seconds parameters = s², m, x[1], x[2] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat e ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s² 2.7624 2.9191 0.2679 99.8749 94.0338 0.9982 ⋯ m -0.0045 1.5138 0.1159 178.1741 172.4582 1.0088 ⋯ x[1] -0.0850 2.2217 0.1396 267.7089 210.8655 1.0056 ⋯ x[2] 0.0700 2.1855 0.1436 231.3029 168.2802 1.0030 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s² 0.5052 1.1032 1.9166 3.1812 10.9506 m -3.7048 -0.8142 -0.0125 0.8082 3.4494 x[1] -5.0158 -1.2540 -0.0730 1.1185 4.3958 x[2] -4.5940 -1.1276 0.1646 1.1763 4.4872
let
@model function gdemo(x)
s²~ InverseGamma(2, 3)
m ~ Normal(0, √s²)
for i in eachindex(x)
x[i] ~ Normal(m, √s²)
end
end
# x[1] is parameter, but x[2] is an observation
model = gdemo([missing, 2.4])
# c = sample(model, HMC(0.01, 5), 1000)
c = sample(model, NUTS(), 1000)
plot(c) |> display
c |> display
end
┌ Info: Found initial step size └ ϵ = 0.8 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
Chains MCMC chain (1000×15×1 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 1 Samples per chain = 1000 Wall duration = 3.8 seconds Compute duration = 3.8 seconds parameters = s², m, x[1] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat e ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s² 2.6711 2.3203 0.1163 343.5518 378.3130 0.9998 ⋯ m 1.2877 1.1422 0.0564 429.2675 412.8486 1.0017 ⋯ x[1] 1.4401 1.9348 0.1014 376.5340 393.0771 1.0009 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s² 0.7772 1.2832 1.9731 3.1616 9.1785 m -0.9917 0.6002 1.3167 1.9541 3.6421 x[1] -2.3558 0.2496 1.3502 2.5362 5.5510
튜링 모델에 대한 인수는 일반 줄리아 함수에서 기본값이 작동하는 방식과 매우 유사하게 기본값을 가질 수 있습니다. 예를 들어 다음은 x에 missing을 할당하고 이를 랜덤 변수로 처리합니다. 기본값이 누락되지 않은 경우 x에 해당 값이 할당되고 대신 관측값으로 처리됩니다.
let
@model function generative(x = missing, ::Type{T} = Float64) where {T <: Real}
if x === missing
# Initialize x when missing
x = Vector{T}(undef,10)
end
s² ~ InverseGamma(2, 3)
m ~ Normal(0, √s²)
for i in 1:length(x)
x[i] ~ Normal(m, √s²)
end
return s²,m
end
model = generative()
samples = sample(model, NUTS(), 1000)
plot(samples)
end
┌ Info: Found initial step size └ ϵ = 0.8 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
체인 내부의 값에 액세스하는 방법은 여러 가지가 있습니다:
DataFrame
개체로 변환AxisArray
사용Array
객체 만들기예를 들어, c가 체인이라고 가정합니다:
DataFrame(c)
는 c
를 DataFrame
으로 변환합니다,c.value
는 c
내부의 값을 AxisArray
로, 그리고c.value.data
는 c
내부의 값을 3D Array
로 검색합니다.@model function gdemo(x)
n = length(x)
s²= Vector{Real}(undef,n)
m = Vector{Real}(undef,n)
for i in eachindex(x)
s²[i] ~ InverseGamma(2,3)
m[i] ~ Normal(0, √(s²[i]))
x[i] ~ Normal(m[i],√(s²[i]))
end
end
x = rand(Normal(2.5, √2.0), 200)
y = rand(Normal(-1.0, √3.0), 200)
model = gdemo([x,y])
c = sample(model, NUTS(), MCMCThreads(), 1000, 2)
c |> display
plot(c) |> display
autocorplot(c) |> display
┌ Info: Found initial step size └ ϵ = 0.2 ┌ Info: Found initial step size └ ϵ = 0.2
Chains MCMC chain (1000×16×2 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 2 Samples per chain = 1000 Wall duration = 1.21 seconds Compute duration = 2.36 seconds parameters = s²[1], s²[2], m[1], m[2] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ s²[1] 2.0265 0.2043 0.0039 2848.5842 1573.2193 1.0000 ⋯ s²[2] 3.0390 0.2976 0.0055 2901.4464 1667.9545 1.0004 ⋯ m[1] 2.4018 0.1014 0.0020 2555.9499 1485.1916 1.0014 ⋯ m[2] -0.9410 0.1228 0.0020 3698.3345 1534.9285 0.9998 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 s²[1] 1.6669 1.8835 2.0114 2.1517 2.4632 s²[2] 2.5013 2.8319 3.0268 3.2217 3.6829 m[1] 2.2116 2.3310 2.4014 2.4714 2.5981 m[2] -1.1769 -1.0262 -0.9389 -0.8613 -0.6992
let
using DataFrames
df = DataFrame(c)
"DataFrame" |> display
df |> display
"c.value" |> display
c.value |> display
"c.value.data" |> display
c.value.data |> display
end
"DataFrame"
Row | iteration | chain | s²[1] | s²[2] | m[1] | m[2] | lp | n_steps | is_accept | acceptance_rate | log_density | hamiltonian_energy | hamiltonian_energy_error | max_hamiltonian_energy_error | tree_depth | numerical_error | step_size | nom_step_size |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Int64 | Int64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 501 | 1 | 1.79171 | 2.9259 | 2.47615 | -1.00088 | -754.783 | 3.0 | 1.0 | 0.989894 | -754.783 | 755.1 | 0.0307885 | -0.170808 | 2.0 | 0.0 | 0.943774 | 0.943774 |
2 | 502 | 1 | 1.79171 | 2.9259 | 2.47615 | -1.00088 | -754.783 | 3.0 | 1.0 | 0.507124 | -754.783 | 758.473 | 0.0 | 0.774826 | 2.0 | 0.0 | 0.943774 | 0.943774 |
3 | 503 | 1 | 1.78365 | 3.20117 | 2.44422 | -0.715697 | -756.268 | 3.0 | 1.0 | 0.587669 | -756.268 | 758.1 | 0.434744 | 0.638666 | 2.0 | 0.0 | 0.943774 | 0.943774 |
4 | 504 | 1 | 2.04188 | 2.71877 | 2.36068 | -0.952244 | -754.322 | 7.0 | 1.0 | 0.971073 | -754.322 | 756.786 | -0.53635 | -0.53635 | 2.0 | 0.0 | 0.943774 | 0.943774 |
5 | 505 | 1 | 2.0008 | 3.34844 | 2.48828 | -0.923913 | -754.648 | 3.0 | 1.0 | 0.873075 | -754.648 | 755.73 | 0.0695649 | 0.274697 | 2.0 | 0.0 | 0.943774 | 0.943774 |
6 | 506 | 1 | 2.04423 | 2.64108 | 2.39721 | -0.955044 | -754.595 | 7.0 | 1.0 | 0.624175 | -754.595 | 758.041 | -0.0385271 | 0.954011 | 2.0 | 0.0 | 0.943774 | 0.943774 |
7 | 507 | 1 | 2.02032 | 3.60037 | 2.29273 | -0.911933 | -755.93 | 3.0 | 1.0 | 0.347244 | -755.93 | 761.517 | 0.549919 | 1.53466 | 2.0 | 0.0 | 0.943774 | 0.943774 |
8 | 508 | 1 | 2.11052 | 2.62496 | 2.50005 | -0.97364 | -755.279 | 3.0 | 1.0 | 0.861626 | -755.279 | 757.751 | -0.00467744 | 0.53635 | 2.0 | 0.0 | 0.943774 | 0.943774 |
9 | 509 | 1 | 1.96377 | 3.46645 | 2.45473 | -1.09452 | -755.545 | 7.0 | 1.0 | 0.867588 | -755.545 | 757.131 | 0.101735 | 0.269872 | 2.0 | 0.0 | 0.943774 | 0.943774 |
10 | 510 | 1 | 2.29862 | 3.644 | 2.55443 | -0.889306 | -757.515 | 3.0 | 1.0 | 0.746443 | -757.515 | 759.255 | 0.407749 | 0.554807 | 2.0 | 0.0 | 0.943774 | 0.943774 |
11 | 511 | 1 | 1.76988 | 3.4902 | 2.38863 | -0.820608 | -756.021 | 3.0 | 1.0 | 1.0 | -756.021 | 758.849 | -0.282026 | -0.404501 | 2.0 | 0.0 | 0.943774 | 0.943774 |
12 | 512 | 1 | 1.94839 | 3.01624 | 2.55037 | -0.704091 | -756.69 | 7.0 | 1.0 | 0.768924 | -756.69 | 759.332 | 0.225851 | 0.749128 | 2.0 | 0.0 | 0.943774 | 0.943774 |
13 | 513 | 1 | 2.07774 | 2.84975 | 2.38127 | -0.993518 | -754.025 | 3.0 | 1.0 | 0.87768 | -754.025 | 758.076 | -0.67024 | -0.67024 | 1.0 | 0.0 | 0.943774 | 0.943774 |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
1989 | 1489 | 2 | 2.05396 | 3.58051 | 2.13081 | -1.01232 | -759.023 | 3.0 | 1.0 | 1.0 | -759.023 | 760.536 | -0.00138792 | -0.737895 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1990 | 1490 | 2 | 2.10231 | 3.03291 | 2.20647 | -1.07199 | -756.255 | 3.0 | 1.0 | 1.0 | -756.255 | 759.247 | -0.682672 | -0.877664 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1991 | 1491 | 2 | 2.10231 | 3.03291 | 2.20647 | -1.07199 | -756.255 | 1.0 | 1.0 | 0.652801 | -756.255 | 757.843 | 0.0 | 0.426483 | 1.0 | 0.0 | 0.963539 | 0.963539 |
1992 | 1492 | 2 | 1.99741 | 3.06072 | 2.59206 | -0.80927 | -756.055 | 3.0 | 1.0 | 1.0 | -756.055 | 757.351 | -0.0692518 | -0.291639 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1993 | 1493 | 2 | 1.54651 | 3.0422 | 2.37786 | -1.03687 | -757.744 | 3.0 | 1.0 | 0.557181 | -757.744 | 761.694 | -0.0470792 | 1.45061 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1994 | 1494 | 2 | 2.16404 | 3.1245 | 2.53922 | -0.777052 | -755.79 | 3.0 | 1.0 | 0.984179 | -755.79 | 759.128 | -0.315962 | -0.315962 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1995 | 1495 | 2 | 2.06172 | 2.946 | 2.29504 | -1.04885 | -754.731 | 3.0 | 1.0 | 0.755407 | -754.731 | 759.38 | -0.428327 | 0.728862 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1996 | 1496 | 2 | 1.92062 | 3.1204 | 2.52605 | -0.775365 | -755.507 | 3.0 | 1.0 | 0.711448 | -755.507 | 757.549 | 0.323141 | 0.890449 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1997 | 1497 | 2 | 2.14108 | 3.02875 | 2.51964 | -1.02001 | -754.768 | 3.0 | 1.0 | 0.889048 | -754.768 | 756.74 | -0.239446 | 0.23982 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1998 | 1498 | 2 | 1.94667 | 2.99099 | 2.28703 | -0.833088 | -754.814 | 3.0 | 1.0 | 0.91457 | -754.814 | 755.964 | 0.0557582 | 0.22572 | 2.0 | 0.0 | 0.963539 | 0.963539 |
1999 | 1499 | 2 | 2.08583 | 2.8571 | 2.53715 | -0.91628 | -754.781 | 3.0 | 1.0 | 0.989534 | -754.781 | 755.584 | -0.0136338 | 0.0319016 | 2.0 | 0.0 | 0.963539 | 0.963539 |
2000 | 1500 | 2 | 2.08659 | 3.72413 | 2.3523 | -0.85725 | -756.319 | 3.0 | 1.0 | 0.417331 | -756.319 | 759.25 | 0.436238 | 1.2405 | 2.0 | 0.0 | 0.963539 | 0.963539 |
"c.value"
3-dimensional AxisArray{Float64,3,...} with axes: :iter, 501:1:1500 :var, [Symbol("s²[1]"), Symbol("s²[2]"), Symbol("m[1]"), Symbol("m[2]"), :lp, :n_steps, :is_accept, :acceptance_rate, :log_density, :hamiltonian_energy, :hamiltonian_energy_error, :max_hamiltonian_energy_error, :tree_depth, :numerical_error, :step_size, :nom_step_size] :chain, 1:2 And data, a 1000×16×2 Array{Float64, 3}: [:, :, 1] = 1.79171 2.9259 2.47615 -1.00088 … 2.0 0.0 0.943774 0.943774 1.79171 2.9259 2.47615 -1.00088 2.0 0.0 0.943774 0.943774 1.78365 3.20117 2.44422 -0.715697 2.0 0.0 0.943774 0.943774 2.04188 2.71877 2.36068 -0.952244 2.0 0.0 0.943774 0.943774 2.0008 3.34844 2.48828 -0.923913 2.0 0.0 0.943774 0.943774 2.04423 2.64108 2.39721 -0.955044 … 2.0 0.0 0.943774 0.943774 2.02032 3.60037 2.29273 -0.911933 2.0 0.0 0.943774 0.943774 2.11052 2.62496 2.50005 -0.97364 2.0 0.0 0.943774 0.943774 1.96377 3.46645 2.45473 -1.09452 2.0 0.0 0.943774 0.943774 2.29862 3.644 2.55443 -0.889306 2.0 0.0 0.943774 0.943774 1.76988 3.4902 2.38863 -0.820608 … 2.0 0.0 0.943774 0.943774 1.94839 3.01624 2.55037 -0.704091 2.0 0.0 0.943774 0.943774 2.07774 2.84975 2.38127 -0.993518 1.0 0.0 0.943774 0.943774 ⋮ ⋱ ⋮ 1.84218 3.05626 2.29374 -0.911148 2.0 0.0 0.943774 0.943774 1.99603 3.36006 2.40845 -1.07951 2.0 0.0 0.943774 0.943774 1.98988 2.53361 2.374 -0.787454 … 3.0 0.0 0.943774 0.943774 1.98688 2.67816 2.35937 -1.17963 2.0 0.0 0.943774 0.943774 1.74054 2.76433 2.4468 -0.91494 2.0 0.0 0.943774 0.943774 1.6844 3.23351 2.39102 -0.881826 2.0 0.0 0.943774 0.943774 1.70373 2.93048 2.36806 -1.00723 2.0 0.0 0.943774 0.943774 1.95558 3.21013 2.29591 -0.785725 … 2.0 0.0 0.943774 0.943774 2.25762 3.5584 2.14025 -0.684222 2.0 0.0 0.943774 0.943774 2.02272 3.16815 2.28926 -0.661574 2.0 0.0 0.943774 0.943774 1.98888 2.85139 2.28506 -1.10707 2.0 0.0 0.943774 0.943774 2.22531 2.53992 2.42093 -0.805889 2.0 0.0 0.943774 0.943774 [:, :, 2] = 1.72913 3.374 2.48625 -0.850005 … 2.0 0.0 0.963539 0.963539 2.34423 2.83456 2.1521 -0.915034 2.0 0.0 0.963539 0.963539 2.12179 3.28248 2.55795 -0.98139 2.0 0.0 0.963539 0.963539 1.93434 2.76009 2.25582 -0.898026 2.0 0.0 0.963539 0.963539 2.05398 3.38753 2.51174 -0.996847 2.0 0.0 0.963539 0.963539 2.01156 3.23139 2.37644 -0.714993 … 2.0 0.0 0.963539 0.963539 2.01497 2.84762 2.48929 -1.15969 2.0 0.0 0.963539 0.963539 2.05198 3.18417 2.31318 -0.711841 2.0 0.0 0.963539 0.963539 2.49279 2.88198 2.45869 -1.05922 2.0 0.0 0.963539 0.963539 2.01664 2.70077 2.65417 -0.983525 2.0 0.0 0.963539 0.963539 2.33802 3.23896 2.5254 -1.05236 … 2.0 0.0 0.963539 0.963539 1.73717 2.79669 2.31026 -0.831214 2.0 0.0 0.963539 0.963539 2.16339 2.72781 2.37655 -0.925699 2.0 0.0 0.963539 0.963539 ⋮ ⋱ ⋮ 2.05396 3.58051 2.13081 -1.01232 2.0 0.0 0.963539 0.963539 2.10231 3.03291 2.20647 -1.07199 2.0 0.0 0.963539 0.963539 2.10231 3.03291 2.20647 -1.07199 … 1.0 0.0 0.963539 0.963539 1.99741 3.06072 2.59206 -0.80927 2.0 0.0 0.963539 0.963539 1.54651 3.0422 2.37786 -1.03687 2.0 0.0 0.963539 0.963539 2.16404 3.1245 2.53922 -0.777052 2.0 0.0 0.963539 0.963539 2.06172 2.946 2.29504 -1.04885 2.0 0.0 0.963539 0.963539 1.92062 3.1204 2.52605 -0.775365 … 2.0 0.0 0.963539 0.963539 2.14108 3.02875 2.51964 -1.02001 2.0 0.0 0.963539 0.963539 1.94667 2.99099 2.28703 -0.833088 2.0 0.0 0.963539 0.963539 2.08583 2.8571 2.53715 -0.91628 2.0 0.0 0.963539 0.963539 2.08659 3.72413 2.3523 -0.85725 2.0 0.0 0.963539 0.963539
"c.value.data"
1000×16×2 Array{Float64, 3}: [:, :, 1] = 1.79171 2.9259 2.47615 -1.00088 … 2.0 0.0 0.943774 0.943774 1.79171 2.9259 2.47615 -1.00088 2.0 0.0 0.943774 0.943774 1.78365 3.20117 2.44422 -0.715697 2.0 0.0 0.943774 0.943774 2.04188 2.71877 2.36068 -0.952244 2.0 0.0 0.943774 0.943774 2.0008 3.34844 2.48828 -0.923913 2.0 0.0 0.943774 0.943774 2.04423 2.64108 2.39721 -0.955044 … 2.0 0.0 0.943774 0.943774 2.02032 3.60037 2.29273 -0.911933 2.0 0.0 0.943774 0.943774 2.11052 2.62496 2.50005 -0.97364 2.0 0.0 0.943774 0.943774 1.96377 3.46645 2.45473 -1.09452 2.0 0.0 0.943774 0.943774 2.29862 3.644 2.55443 -0.889306 2.0 0.0 0.943774 0.943774 1.76988 3.4902 2.38863 -0.820608 … 2.0 0.0 0.943774 0.943774 1.94839 3.01624 2.55037 -0.704091 2.0 0.0 0.943774 0.943774 2.07774 2.84975 2.38127 -0.993518 1.0 0.0 0.943774 0.943774 ⋮ ⋱ ⋮ 1.84218 3.05626 2.29374 -0.911148 2.0 0.0 0.943774 0.943774 1.99603 3.36006 2.40845 -1.07951 2.0 0.0 0.943774 0.943774 1.98988 2.53361 2.374 -0.787454 … 3.0 0.0 0.943774 0.943774 1.98688 2.67816 2.35937 -1.17963 2.0 0.0 0.943774 0.943774 1.74054 2.76433 2.4468 -0.91494 2.0 0.0 0.943774 0.943774 1.6844 3.23351 2.39102 -0.881826 2.0 0.0 0.943774 0.943774 1.70373 2.93048 2.36806 -1.00723 2.0 0.0 0.943774 0.943774 1.95558 3.21013 2.29591 -0.785725 … 2.0 0.0 0.943774 0.943774 2.25762 3.5584 2.14025 -0.684222 2.0 0.0 0.943774 0.943774 2.02272 3.16815 2.28926 -0.661574 2.0 0.0 0.943774 0.943774 1.98888 2.85139 2.28506 -1.10707 2.0 0.0 0.943774 0.943774 2.22531 2.53992 2.42093 -0.805889 2.0 0.0 0.943774 0.943774 [:, :, 2] = 1.72913 3.374 2.48625 -0.850005 … 2.0 0.0 0.963539 0.963539 2.34423 2.83456 2.1521 -0.915034 2.0 0.0 0.963539 0.963539 2.12179 3.28248 2.55795 -0.98139 2.0 0.0 0.963539 0.963539 1.93434 2.76009 2.25582 -0.898026 2.0 0.0 0.963539 0.963539 2.05398 3.38753 2.51174 -0.996847 2.0 0.0 0.963539 0.963539 2.01156 3.23139 2.37644 -0.714993 … 2.0 0.0 0.963539 0.963539 2.01497 2.84762 2.48929 -1.15969 2.0 0.0 0.963539 0.963539 2.05198 3.18417 2.31318 -0.711841 2.0 0.0 0.963539 0.963539 2.49279 2.88198 2.45869 -1.05922 2.0 0.0 0.963539 0.963539 2.01664 2.70077 2.65417 -0.983525 2.0 0.0 0.963539 0.963539 2.33802 3.23896 2.5254 -1.05236 … 2.0 0.0 0.963539 0.963539 1.73717 2.79669 2.31026 -0.831214 2.0 0.0 0.963539 0.963539 2.16339 2.72781 2.37655 -0.925699 2.0 0.0 0.963539 0.963539 ⋮ ⋱ ⋮ 2.05396 3.58051 2.13081 -1.01232 2.0 0.0 0.963539 0.963539 2.10231 3.03291 2.20647 -1.07199 2.0 0.0 0.963539 0.963539 2.10231 3.03291 2.20647 -1.07199 … 1.0 0.0 0.963539 0.963539 1.99741 3.06072 2.59206 -0.80927 2.0 0.0 0.963539 0.963539 1.54651 3.0422 2.37786 -1.03687 2.0 0.0 0.963539 0.963539 2.16404 3.1245 2.53922 -0.777052 2.0 0.0 0.963539 0.963539 2.06172 2.946 2.29504 -1.04885 2.0 0.0 0.963539 0.963539 1.92062 3.1204 2.52605 -0.775365 … 2.0 0.0 0.963539 0.963539 2.14108 3.02875 2.51964 -1.02001 2.0 0.0 0.963539 0.963539 1.94667 2.99099 2.28703 -0.833088 2.0 0.0 0.963539 0.963539 2.08583 2.8571 2.53715 -0.91628 2.0 0.0 0.963539 0.963539 2.08659 3.72413 2.3523 -0.85725 2.0 0.0 0.963539 0.963539
랜덤 변수의 벡터(또는 행렬)의 엘리먼트 유형은 사전분포의 eltype
과 일치해야 합니다. 불연속 분포의 경우 <: Integer
, 연속 분포의 경우 <: AbstractFloat
여야 합니다.또한 해밀턴 샘플러를 사용하여 연속형 확률 변수를 샘플링하려면 벡터의 요소 유형이 1. 실수(Real
)여야 합니다. 실수(Real
)의 하위 유형인 특정 숫자 유형을 사용하는 모델을 통해 자동미분(auto-diffrentiation) 이 가능하거나 2. type parameter 구문을 사용하여 모델 헤더에 정의된 일부 type parameter T(예: function gdemo(x, ::Type{T} = Float64) where {T}
). 마찬가지로 파티클 샘플러를 사용할 때 사용되는 Julia 변수는 1. TArray
이거나 2. type parameter 구문을 사용하여 모델 헤더에 정의된 type parameter T의 인스턴스(예: function gdemo(x, ::Type{T} = Vector{Float64}) where {T}
).
prob"x=2.5 , s=1.2| model = m"
prob"x=2.5 | model=m, s=1.2"
prob"s=1.2 | model = m, x = nothing"
let
@model function gdemo(x)
s ~ Normal(0, 1)
x ~ Normal(s, 1)
end
# model instance를 만들기 위해서 입력값을 아무거나 넣어도 되지만
# nothing 으로 설정
m = gdemo(nothing)
# 사전확률밀도 계산
prior_01 = prob"s=1.2 | model = m, x = nothing"
# 직접계산
prior_02 = pdf(Normal(0,1), 1.2)
println("prior_01 : ", prior_01)
println("prior_02 : ", prior_02)
# 우도 계산
likelihood_01 = prob"x=2.5 |model = m, s=1.2"
# 직접계산
# s = 1.2, x=2.5
likelihood_02 = pdf(Normal(1.2,1),2.5)
println("likelihood_01 : ", likelihood_01)
println("likelihood_02 : ", likelihood_02)
# 사후확률밀도 계산
# 사후확률밀도 = 우도 * 사전확률밀도
posterior_01 = prob"s=1.2, x=2.5 | model=m"
# 직접계산
posterior_02 = pdf(Normal(1.2,1),2.5)*pdf(Normal(0,1),1.2)
println("posterior_01: ", posterior_01)
println("posterior_02: ", posterior_02)
end
prior_01 : 0.19418605498321292 prior_02 : 0.19418605498321295 likelihood_01 : 0.17136859204780733 likelihood_02 : 0.17136859204780736 posterior_01: 0.0332773908377913 posterior_02: 0.03327739083779131
let
using Plots, KernelDensity
plotlyjs()
# x,y : i.i.d
# m,s²: i.i.d
@model function gdemo(x,y)
s²~ InverseGamma(2, 3)
m ~ Normal(0, √s²)
x ~ Normal(m, √s²)
y ~ Normal(m, √s²)
end
model_instance= gdemo(nothing,nothing)
pdf_s2(v) = pdf(InverseGamma(2,3),v)
#--------------------------------
# Likelihood : x,y
#--------------------------------
likelihood_01 = prob"x = 1.0, y = 3.0 | s² = 1.5, m = 2.0, model = model_instance"
# p(x,y|m,s²) = p(x|m,s²)*p(y|m,s²)
likelihood_02 = pdf(Normal(2.0,√1.5),1.0) * pdf(Normal(2.0,√1.5),3.0)
println("likehood_01 : ",likelihood_01)
println("likehood_02 : ",likelihood_02)
#--------------------------------
# Joint probability : m,s²
#--------------------------------
joint_prob1_01 = prob"s² = 1.5, m = 2.0 | x = nothing, y = nothing, model = model_instance"
# p(s²,m) = p(s²) * p(m)
joint_prob1_02 = pdf_s2(1.5)*pdf(Normal(0,√1.5),2.0)
println("joint_prob1_01 of m, s² : ",joint_prob1_01)
println("joint_prob1_02 of m, s² : ",joint_prob1_02)
#--------------------------------
# Joint probability : m,s²,x
#--------------------------------
joint_prob2_01 = prob"s² = 1.5, m = 2.0, x = 1.0 | y = nothing, model = model_instance"
# p(s²,m,x) = p(s²) * p(m) * p(x)
joint_prob2_02 = pdf_s2(1.5)*pdf(Normal(0,√1.5),2.0)*pdf(Normal(2.0,√1.5),1.0)
println("joint_prob2_01 of m, s²,x : ",joint_prob2_01)
println("joint_prob2_02 of m, s²,x : ",joint_prob2_02)
#--------------------------------
# Joint probability : m,s²,x, y
#--------------------------------
joint_prob3_01 = prob"s² = 1.5, m = 2.0, x = 1.0, y = 3.0 | model = model_instance"
# p(s²,m,x) = p(s²) * p(m) * p(x)
joint_prob3_02 = pdf_s2(1.5)*pdf(Normal(0,√1.5),2.0)*
pdf(Normal(2.0,√1.5),1.0)*pdf(Normal(2.0,√1.5),3.0)
println("joint_prob3_01 of m, s²,x, y : ",joint_prob3_01)
println("joint_prob3_02 of m, s²,x, y : ",joint_prob3_02)
#--------------------------------
# MCMC Sampling 이후
#--------------------------------
chain = sample(gdemo(1.0, 3.0), NUTS(), 1000)
plot(chain) |> display
autocorplot(chain) |> display
# DataFrame으로 chian 데이터 읽어 오기
df = DataFrame(chain)
df[1:5,:] |> display
#--------------------------------
# Likelihood : x,y
# MCMC에서 샘플링한 1000개의 m, s²에 대해
# x,y의 likelihood 계산
# p(x,y | m,s²)
#--------------------------------
# 경고 숨기기
likelihood_mcmc = @suppress begin
likelihood_mcmc = prob"x = 1.0, y = 3.0 | chain=chain, model = model_instance"
likelihood_mcmc
end
println("likelihood_mcmc size : ",size(likelihood_mcmc))
println("size(chain[:s²]) : ",size(chain[:s²]))
println("size(chain[:m]) : ",size(chain[:m]))
#--------------------------------
# Sampleing된 m, s²데이터로 부터
# density를 구하고 argmax를 구한다
# KDE 방법으로 데이터 밀도 추정
#--------------------------------
s²_density = kde(df.s²)
s²_max_idx = argmax(s²_density.density)
s²_map = s²_density.x[s²_max_idx]
m_density = kde(df.m)
m_max_idx = argmax(m_density.density)
m_map = m_density.x[m_max_idx]
#plot(m_density.x,m_density.density) |> display
#-------------------------------
# Visualize s²,m with KDE
#-------------------------------
plot(s²_density.x, s²_density.density, label="", lw=2)
vline!([s²_map], color=:red, label="Max Density at s²= $(round(s²_map,digits=4))",
linestyle=:dash,lw=2)
xlabel!("s² value")
ylabel!("Density")
p1 = title!("Kernel Density Estimation of s²")
plot(m_density.x, m_density.density, label="", lw=2)
vline!([m_map], color=:red, label="Max Density at m = $(round(m_map,digits=4))", lw=2)
xlabel!("m value")
ylabel!("Density")
p2 = title!("Kernel Density Estimation of m")
plot(p1,p2, layout= (1,2), legend=:bottomright, titlefontsize=12) |> display
println("Max Posterior of s²,m : $(s²_map), $(m_map)")
#--------------------------------
# Visualize
#--------------------------------
# (1000,1) => (1000,) 으로 변환
l_mcmc = reshape(likelihood_mcmc,(:,))
idx = argmax(l_mcmc)
println("max likelihood index : ",idx)
df[idx:idx,:] |> display
println("max likelihood : p(x=1.0, y=3.0 | s²= $(df.s²[idx]),m=$(df.m[idx])) = $(l_mcmc[idx]) ")
sp1 = scatter3d(df.s²,df.m, l_mcmc, markersize=0.3,legend=false,
xlabel="s²", ylabel="m", zlabel="p(x=1.0,y=3.0 | s²,m)", size=(1000,800))
sp2 = scatter3d(sp1,[df.s²[idx]],[df.m[idx]], [l_mcmc[idx]], markersize=1.0,color=:red)
x,y,z = df.s²[idx],df.m[idx],l_mcmc[idx]
x_line = [x, x, x]
y_line = [0, y, y]
z_line = [0, 0, z]
plot3d!(sp2,x_line, y_line,z_line, mode="lines", color=:red, linewidth=5)
end
The WebIO Jupyter extension was not detected. See the WebIO Jupyter integration documentation for more information.
likehood_01 : 0.05447524824135803 likehood_02 : 0.054475248241358035 joint_prob1_01 of m, s² : 0.030987382682801004 joint_prob1_02 of m, s² : 0.03098738268280102 joint_prob2_01 of m, s²,x : 0.007232434422796936 joint_prob2_02 of m, s²,x : 0.007232434422796939 joint_prob3_01 of m, s²,x, y : 0.0016880453639955442 joint_prob3_02 of m, s²,x, y : 0.0016880453639955449
┌ Info: Found initial step size └ ϵ = 0.8
Row | iteration | chain | s² | m | lp | n_steps | is_accept | acceptance_rate | log_density | hamiltonian_energy | hamiltonian_energy_error | max_hamiltonian_energy_error | tree_depth | numerical_error | step_size | nom_step_size |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Int64 | Int64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 501 | 1 | 3.20274 | 0.451147 | -6.66335 | 3.0 | 1.0 | 0.995849 | -6.66335 | 7.38575 | -0.0443729 | -0.297267 | 2.0 | 0.0 | 0.856725 | 0.856725 |
2 | 502 | 1 | 1.69526 | 0.855131 | -5.75538 | 3.0 | 1.0 | 0.996916 | -5.75538 | 6.71051 | -0.128104 | -0.128104 | 2.0 | 0.0 | 0.856725 | 0.856725 |
3 | 503 | 1 | 5.2232 | -0.481347 | -8.31227 | 7.0 | 1.0 | 0.790509 | -8.31227 | 8.4373 | 0.317679 | 0.972632 | 2.0 | 0.0 | 0.856725 | 0.856725 |
4 | 504 | 1 | 5.59103 | 0.646362 | -7.66418 | 3.0 | 1.0 | 0.938712 | -7.66418 | 8.99453 | 0.0632611 | -0.302526 | 2.0 | 0.0 | 0.856725 | 0.856725 |
5 | 505 | 1 | 4.17639 | -0.646191 | -8.24706 | 3.0 | 1.0 | 1.0 | -8.24706 | 8.81888 | -0.071352 | -0.459079 | 2.0 | 0.0 | 0.856725 | 0.856725 |
likelihood_mcmc size : (1000, 1) size(chain[:s²]) : (1000, 1) size(chain[:m]) : (1000, 1)
Max Posterior of s²,m : 1.4815249676020907, 1.2829839545006743 max likelihood index : 554
Row | iteration | chain | s² | m | lp | n_steps | is_accept | acceptance_rate | log_density | hamiltonian_energy | hamiltonian_energy_error | max_hamiltonian_energy_error | tree_depth | numerical_error | step_size | nom_step_size |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Int64 | Int64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 1054 | 1 | 0.928537 | 2.01965 | -6.80481 | 3.0 | 1.0 | 0.877812 | -6.80481 | 7.40648 | 0.3798 | 0.3798 | 2.0 | 0.0 | 0.856725 | 0.856725 |
max likelihood : p(x=1.0, y=3.0 | s²= 0.9285366482105682,m=2.019651684307102) = 0.05836079317783932
Turing은 두 가지 모드 추정 기법, 즉 최대우도추정(MLE-maximum likelihood estimation)과 최대사후추정(MAP-maximum a posterior)을 지원합니다. 최적화는 Optim.jl 패키지에 의해 수행됩니다.
일부 메서드는 충분한 반복이 허용되지 않거나 함수 호출 사이에 대상 함수가 위로 이동하여 모드를 계산하는 데 문제가 있을 수 있습니다. Optim.converge를 실행하여 Optim이 수렴에 실패하면 Turing에서 경고를 표시합니다. 이에 대한 일반적인 해결책은 반복을 더 추가하거나 함수 반복 사이에 옵티마이저가 증가하도록 허용하는 것입니다:
(mle_estimate, map_estimate,model) = let
using Optim
@model function gdemo(x)
s²~InverseGamma(2,3)
m ~ Normal(0, √s²)
for i in eachindex(x)
x[i] ~ Normal(m, √s²)
end
end
data = [1.0, 3.0]
model = gdemo(data)
#---------------------------------
# MLE, MAP Optimization
# default optimizer : LBFGS optimizer
#---------------------------------
# Generate a MLE estimate.
mle_estimate = optimize(model, MLE())
# Generate a MAP estimate.
map_estimate = optimize(model, MAP())
fieldnames(typeof(map_estimate)) |> display
println("MLE of x=1.0, y=3.0 : ")
mle_estimate |> display
println("MAP of x=1.0, y=3.0 : ")
map_estimate |> display
#---------------------------------
# Use NelderMead
#---------------------------------
# Increase the iterations and allow function eval to increase between calls.
mle_estimate2 = optimize(model, MLE(), NelderMead())
println("MLE-NelderMead of x=1.0, y=3.0 : ")
mle_estimate2 |> display
(mle_estimate, map_estimate,model)
end;
(:values, :optim_result, :lp, :f)
MLE of x=1.0, y=3.0 :
ModeResult with maximized lp of -2.84 [1.000000000710164, 2.0000000009077112]
MAP of x=1.0, y=3.0 :
ModeResult with maximized lp of -5.82 [1.1851851851851711, 1.3333333333333324]
MLE-NelderMead of x=1.0, y=3.0 :
ModeResult with maximized lp of -2.84 [0.999937799356961, 1.999951237477533]
Turing은 모드 추정 결과를 분석하는 데 사용할 수 있는 StatsBase의 여러 메서드를 확장합니다. 구현된 메서드에는 vcov
, informationmatrix
, coeftable
, params
, coef
등이 있습니다.
표준 오차는 피셔 정보 행렬(로그 확률 또는 로그 조인트의 역 헤시안)에서 계산되며, 빈도 통계학자에게는 t-통계가 친숙할 것입니다. 경고 - 이러한 방식으로 계산된 표준 오차는 MAP 추정치에 항상 적합하지 않을 수 있으므로 해석에 주의하세요.
For example, let's examine our ML estimate from above using coeftable
:
let (mle_estimate, map_estimate) = (mle_estimate, map_estimate)
using StatsBase
# Print out the coefficient table
coeftable(mle_estimate) |> DataFrame |> display
coeftable(map_estimate) |> DataFrame |> display
end
Row | Name | Coef. | Std. Error | z | Pr(>|z|) | Lower 95% | Upper 95% |
---|---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | s² | 1.0 | 1.0 | 1.0 | 0.317311 | -0.959964 | 2.95996 |
2 | m | 2.0 | 0.707107 | 2.82843 | 0.00467773 | 0.614096 | 3.3859 |
Row | Name | Coef. | Std. Error | z | Pr(>|z|) | Lower 95% | Upper 95% |
---|---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | s² | 1.18519 | 0.558702 | 2.12132 | 0.0338949 | 0.0901501 | 2.28022 |
2 | m | 1.33333 | 0.628539 | 2.12132 | 0.0338949 | 0.101419 | 2.56525 |
파라미터 값의 벡터를 추출하고 키워드 init_params
를 사용하여 샘플 함수에 제공함으로써 MLE/MAP 추정치에서 체인 샘플링을 시작할 수 있습니다. 예를 들어, 다음은 MAP 추정치를 시작점으로 사용하여 전체 사후분포(posterior)에서 샘플링하는 방법입니다:
let model = model
# G
map_estimate =optimize(model, MAP())
coeftable(map_estimate) |> DataFrame |> display
# Sample with the MAP estimate as the starting point.
chain = sample(model, NUTS(), 1_000, init_params = map_estimate.values.array)
#chain |> DataFrame |> display
plot(chain,titlefontsize=10) |> display
end
Row | Name | Coef. | Std. Error | z | Pr(>|z|) | Lower 95% | Upper 95% |
---|---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | s² | 1.18519 | 0.558702 | 2.12132 | 0.0338949 | 0.0901501 | 2.28022 |
2 | m | 1.33333 | 0.628539 | 2.12132 | 0.0338949 | 0.101419 | 2.56525 |
┌ Info: Found initial step size └ ϵ = 1.6 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
Turing.jl은 서로 다른 샘플러를 결합할 수 있는 Gibbs 인터페이스를 제공합니다. 예를 들어, 아래와 같이 HMC
샘플러와 PG
샘플러를 결합하여 단일 모델에서 다양한 파라미터에 대한 추론을 실행할 수 있습니다.
깁스 샘플러를 사용하여 다양한 변수 공간에 대해 고유한 자동미분(Automatic Differentiation) 백엔드를 지정할 수 있습니다. 자세한 내용은 자동미분(Automatic Differentiation) 문서를 참조하세요.
Turing.jl의 컴포지션 샘플링에 대한 자세한 내용은 해당 논문을 참조하세요.
let
@model function simple_choice(xs)
p ~ Beta(2, 2)
z ~ Bernoulli(p)
for i in 1:length(xs)
if z == 1
xs[i] ~ Normal(0, 1)
else
xs[i] ~ Normal(2, 1)
end
end
end
simple_choice_f = simple_choice([1.5, 2.0, 0.3])
chn = sample(simple_choice_f, Gibbs(HMC(0.2, 3, :p), PG(20, :z)), 1000)
plot(chn) |> display
chn |> display
end
Sampling: 100%|█████████████████████████████████████████| Time: 0:00:16
Chains MCMC chain (1000×3×1 Array{Float64, 3}): Iterations = 1:1:1000 Number of chains = 1 Samples per chain = 1000 Wall duration = 27.65 seconds Compute duration = 27.65 seconds parameters = p, z internals = lp Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat e ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ p 0.3929 0.2087 0.0329 42.9175 176.4490 1.0389 ⋯ z 0.1270 0.3331 0.0162 425.3284 NaN 0.9990 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 p 0.0694 0.2252 0.3734 0.5460 0.8089 z 0.0000 0.0000 0.0000 0.0000 1.0000
Turing은 production 분포를 구성하기 위한 단순화된 인터페이스로 filldist(dist::Distribution, n::Int) 및 arraydist(dists::AbstractVector{<:Distribution})를 제공합니다(예: 동일한 구조를 공유하지만 그룹마다 다른 변수 집합을 모델링하기 위해).
a ~ filldist(Exponential(), k) 는 아래와 동일
a[1] ~ Exponential()
...
a[k] ~ Exponential()
filldist
함수는 동일한 유형 및 매개변수화 분포에 대한 분포곱하기을 구성하는 일반 인터페이스를 제공합니다. Distributions.jl(Product)에서 제공하는 Production Distribution 인터페이스와 달리 filldist
는 단변량 또는 다변량 분포에 대한 분포
곱하기를 지원한다는 점에 유의하세요.
아래 코드는 주어진 x
데이터와 그룹 정보 g
를 사용하여 간단한 계층적 모델을 정의하는 Julia 코드입니다. 모델의 주요 개념과 구성 요소를 설명하겠습니다:
함수 정의:
@model
매크로는 Turing.jl에서 확률 모델을 정의할 때 사용합니다. demo
라는 함수가 정의되었으며, 이 함수는 x
(관측 데이터)와 g
(그룹 또는 카테고리 정보) 두 가지 인수를 받습니다.
그룹의 수 계산:
k = length(unique(g))
- g
내의 고유한 그룹 또는 카테고리의 수를 계산합니다. 예를 들어, g = [1, 1, 2, 3, 3]
이라면 k
는 3이 됩니다.
계층적 사전 분포:
a ~ filldist(Exponential(), k)
- k
개의 그룹 각각에 대해 지수 분포 (Exponential()
)로부터 뽑힌 값을 갖는 a
벡터를 정의합니다. 즉, 각 그룹에 대한 파라미터 a
를 독립적으로 지수 분포에서 샘플링합니다.
모델링 mu
:
mu = a[g]
- 데이터 포인트 각각에 대한 평균 값을 나타내는 mu
를 계산합니다. 여기서 g
의 각 원소는 해당 데이터 포인트가 속하는 그룹을 나타내므로, mu
는 해당 그룹의 a
값으로 설정됩니다.
관측 데이터에 대한 가능도:
x .~ Normal.(mu)
- 관측 데이터 x
각각은 해당 데이터 포인트에 대한 mu
값으로 평균을 갖는 정규 분포에서 독립적으로 샘플링되었다고 가정합니다.
이 모델은 그룹화 된 데이터에 대한 계층적 구조를 가진 확률 모델을 나타냅니다. 각 그룹은 독립적인 지수 분포에서 파라미터를 가지며, 각 데이터 포인트는 해당 그룹의 파라미터를 평균으로 하는 정규 분포에서 샘플링된 것으로 가정합니다.
let
@model function demo(x, g)
k = length(unique(g))
a ~ filldist(Exponential(), k) # = Product(fill(Exponential(), k))
mu = a[g]
x .~ Normal.(mu)
end
x = [rand(Normal(0,1),30);] #rand(Normal(3,1),3);rand(Normal(5,1),3);]
g = rand(1:3,length(x))
model = demo(x,g)
samples = sample(model,NUTS(),1000)
plot(samples, titlefontsize=10)
end
┌ Info: Found initial step size └ ϵ = 0.05 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
arraydist 함수는 다양한 유형 및 매개변수화 분포에 대한 production 분포를 구성하는 일반적인 인터페이스를 제공합니다. Distributions.jl(Product)에서 제공하는 Production 분포 인터페이스와 달리 arraydist는 단변량 또는 다변량 분포에 대한 Production 분포를 지원한다는 점에 유의하세요.
let
@model function demo(x, g)
k = length(unique(g))
a ~ arraydist([Exponential(i) for i in 1:k])
mu = a[g]
x .~ Normal.(mu)
end
x = [rand(Normal(0,1),30);] #rand(Normal(3,1),3);rand(Normal(5,1),3);]
g = rand(1:3,length(x))
model = demo(x,g)
samples = sample(model,NUTS(),1000)
plot(samples, titlefontsize=10)
end
┌ Info: Found initial step size └ ϵ = 0.2 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
계층적 확률 모델은 데이터의 계층적 구조를 반영하기 위해 설계된 모델입니다. 이러한 모델은 다수의 관측 단위와 그룹 간 및 그룹 내 변동을 설명하는 변수들을 포함합니다. 계층적 모델은 특히 그룹화된 데이터에서 유용하며, 각 그룹이 고유한 패턴을 가질 수 있지만 전체적으로 일관된 추세를 공유하는 경우에 많이 사용됩니다.
계층적 모델링: 데이터에 내재된 계층 구조를 반영하여 파라미터를 추정합니다. 각 계층은 그룹별 차이와 전체적인 차이를 모두 포함합니다.
분산 구조: 그룹 내와 그룹 간 변동성을 모두 모델링하여, 각 그룹의 특성과 전체 특성을 모두 반영합니다.
학생들의 시험 점수를 모델링하려고 할 때, 각 학생은 특정 학교에 속합니다. 학생들의 점수는 그들의 개인적인 능력 뿐만 아니라 학교의 특성에 따라 다를 수 있습니다.
모델은 일반적으로 다음과 같이 나타낼 수 있습니다:
모델은 다음과 같이 표현됩니다:
$y_{ij} = \mu_i + \epsilon_{ij}$
여기서, ( $\mu_i$ )는 학교 효과를 나타내며, 이 효과는 전체 학교에 대한 평균 효과 ( $\alpha$ )와 함께 모델에 포함됩니다.
이러한 계층적 구조를 사용하면 각 학교의 특성과 전체적인 특성을 동시에 추정할 수 있습니다. 그 결과, 특정 학교의 데이터가 부족한 경우에도 전체적인 추세를 기반으로 그 학교에 대한 추정을 더 정확하게 할 수 있습니다.
먼저, 간단한 예제 데이터를 생성합니다:
5개의 학교에서 각각 30명의 학생들의 성적을 생성합니다. 각 학교마다 고유한 평균 점수를 가정하며, 학생들의 점수는 학교의 평균을 중심으로 랜덤하게 분포됩니다.
이 모델에서:
NUTS()
sampler를 사용하여 모델을 샘플링하고, 결과를 chain
변수에 저장합니다.
$ \alpha \sim \mathcal{N}(0, 10^2) $
$ \sigma \sim \text{Truncated}(\text{Cauchy}(0, 10), 0, \infty) $
$ \mu_j \sim \mathcal{N}(\alpha, \sigma^2) \quad \text{for } j = 1, \ldots, n_{\text{schools}} $
학생별 점수에 대한 우도: $ \epsilon = 5\\ \text{grades}_i \sim \mathcal{N}(\mu_{\text{school_ids}[i]}, \epsilon^2) \quad \text{for } i = 1, \ldots, \text{length(grades)} \\ $
사후분포는 위의 사전분포와 우도를 조합하여 계산됩니다. 수식으로 간단하게 표현하면:
$ p(\alpha, \sigma, \mu | \text{grades}) \propto p(\alpha) p(\sigma) \prod_{j=1}^{n_{\text{schools}}} p(\mu_j | \alpha, \sigma) \prod_{i=1}^{\text{length(grades)}} p(\text{grades}_i | \mu_{\text{school_ids}[i]}) $
여기서, $p(\alpha)$ , $p(\sigma)$ , $p(\mu_j | \alpha, \sigma)$ , 그리고 $p(\text{grades}_i | \mu_{\text{school_ids}[i]})$ 는 각각 위에서 설명한 사전분포와 우도를 나타냅니다.
μ ~ filldist(Normal(α, σ), 3) 는 아래와 같은 내용임
μ[1] ~ Normal(α, σ), μ[2] ~ Normal(α, σ), μ[2] ~ Normal(α, σ)
전체학교 평균 = $\alpha + \sigma$
st_chain = let
using Turing, Distributions, Random
# 예제 데이터 생성
Random.seed!(1234) # 재현성을 위한 시드 설정
n_schools = 5
students_per_school = 30
# 학교별 평균 점수
school_avg = [85, 90, 75, 80, 70]
# 각 학교의 학생들의 점수 생성
grades = []
school_ids = []
for i in 1:n_schools
school_grades = rand(Normal(school_avg[i], 10), students_per_school)
push!(grades, school_grades)
push!(school_ids, fill(i, students_per_school))
end
grades = vcat(grades...)
school_ids = vcat(school_ids...)
# 모델 정의
@model function hierarchical_model(grades, school_ids, n_schools)
α ~ Normal(0, 10) # 전체 학교 평균에 대한 사전분포 (0점이라고 가정 - 무리한 가정)
σ ~ Truncated(Cauchy(0, 10), 0, Inf) # 학교 간 분산
μ ~ filldist(Normal(α, σ), n_schools) # 학교별 평균
for i in 1:length(grades)
grades[i] ~ Normal(μ[school_ids[i]], 5) # 학생별 점수
end
end
# 샘플링
chain = sample(hierarchical_model(grades, school_ids, n_schools), NUTS(), 1000)
plot(Truncated(Cauchy(0, 10), 0, 200), title="σ ~ Truncated(Cauchy(0, 10), 0, Inf)",
titlefontsize=10, legend=false, size=(800,200)) |> display
plot(chain, titlefontsize=8) |> display
chain
end
┌ Info: Found initial step size └ ϵ = 0.8 Sampling: 100%|█████████████████████████████████████████| Time: 0:00:00
Chains MCMC chain (1000×19×1 Array{Float64, 3}): Iterations = 501:1:1500 Number of chains = 1 Samples per chain = 1000 Wall duration = 7.0 seconds Compute duration = 7.0 seconds parameters = α, σ, μ[1], μ[2], μ[3], μ[4], μ[5] internals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ α 8.9753 10.7545 0.4211 656.0845 555.2656 1.0051 ⋯ σ 74.6378 28.7578 1.0974 561.8351 662.6308 1.0032 ⋯ μ[1] 85.7657 0.9061 0.0240 1412.4900 444.3103 1.0038 ⋯ μ[2] 89.6041 0.9454 0.0257 1360.8753 693.5409 1.0006 ⋯ μ[3] 71.1830 0.9059 0.0305 886.0895 592.2101 1.0001 ⋯ μ[4] 82.0604 0.9339 0.0258 1379.9769 611.3171 1.0069 ⋯ μ[5] 70.4427 0.9181 0.0318 831.5316 679.7763 1.0034 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 α -11.4631 1.3864 8.4896 16.4780 30.2636 σ 37.6910 54.8507 68.6761 87.8000 146.9226 μ[1] 84.0517 85.1536 85.7371 86.3947 87.5047 μ[2] 87.8123 88.9465 89.5805 90.2405 91.5007 μ[3] 69.3960 70.5671 71.2126 71.7931 72.9761 μ[4] 80.1276 81.4287 82.0722 82.7079 83.7709 μ[5] 68.6682 69.8429 70.4582 71.0207 72.2448
Turing.jl은 MCMCChains.Chain을 사용하여 샘플을 래핑하므로 MCMCChains.Chain에서 작동하는 모든 함수를 Turing.jl에서 재사용할 수 있습니다. 대표적인 두 가지 함수는 MCMCChains.describe와 MCMCChains.plot이며, 획득한 체인 chn에 대해 다음과 같이 사용할 수 있습니다. MCMCChains에 대한 자세한 내용은 GitHub 리포지토리를 참조하세요.
let
describe(st_chain) |> display
describe(st_chain["α"]) |> display
describe(st_chain["σ"]) |> display
describe(st_chain["μ[1]"]) |> display
end;
2-element Vector{ChainDataFrame}: Summary Statistics (7 x 8) Quantiles (7 x 6)
Summary Stats: Length: 1000 Missing Count: 0 Mean: 8.975331 Minimum: -22.544918 1st Quartile: 1.386443 Median: 8.489586 3rd Quartile: 16.478041 Maximum: 41.300121 Type: Float64
nothing
Summary Stats: Length: 1000 Missing Count: 0 Mean: 74.637763 Minimum: 28.109327 1st Quartile: 54.850704 Median: 68.676125 3rd Quartile: 87.799981 Maximum: 257.789839 Type: Float64
nothing
Summary Stats: Length: 1000 Missing Count: 0 Mean: 85.765668 Minimum: 82.353224 1st Quartile: 85.153615 Median: 85.737066 3rd Quartile: 86.394738 Maximum: 89.386477 Type: Float64
nothing
Libtask.jl 라이브러리는 Turing의 particle(입자) 기반 샘플러에서 사용하기에 안전한 write-on-copy
데이터 구조를 제공합니다. 특히 TArray
를 사용해야 하는 경우가 많습니다. 다음 샘플러 유형은 분포를 저장하기 위해 TArray를 사용해야 합니다:
IPMCMC
IS
PG
PMMH
SMC
particle(입자) 기반 샘플러를 사용할 때 분포 배열을 저장할 때 TArray를 사용하지 않으면 오류가 발생할 수 있습니다.
let
@model function BayesHmm(y,N, K)
# Declare a TArray with a length of N.
s = tzeros(Int, N)
m = Vector{Float64}(undef, K)
T = Vector{Vector{Float64}}(undef, K)
for i = 1:K
T[i] ~ Dirichlet(ones(K)/K)
m[i] ~ Normal(i, 0.01)
end
# Draw from a distribution for each element in s.
s[1] ~ Categorical(K)
for i=2:N
s[i] ~ Categorical(vec(T[s[i-1]]))
y[i] ~ Normal(m[s[i]], 0.1)
end
return (s,m)
end
N = 3
K = 2
y = rand(Normal(3,1),N)
model = BayesHmm(y,N,K)
samples = sample(model, PG(K), 1000)
plot(samples, titlefontsize=9) |> display
samples
end
Sampling: 100%|█████████████████████████████████████████| Time: 0:00:03
Chains MCMC chain (1000×11×1 Array{Float64, 3}): Log evidence = -293.45395345351056 Iterations = 1:1:1000 Number of chains = 1 Samples per chain = 1000 Wall duration = 9.25 seconds Compute duration = 9.25 seconds parameters = T[1][1], T[1][2], T[2][1], T[2][2], m[1], m[2], s[1], s[2], s[3] internals = lp, logevidence Summary Statistics parameters mean std mcse ess_bulk ess_tail rhat e ⋯ Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯ T[1][1] 0.5438 0.4116 0.1093 23.5815 48.3905 1.0505 ⋯ T[1][2] 0.4562 0.4116 0.1093 23.5815 8.5954 1.0505 ⋯ T[2][1] 0.2529 0.2524 0.0675 20.0704 25.1402 1.0441 ⋯ T[2][2] 0.7471 0.2524 0.0675 20.0704 8.9894 1.0441 ⋯ m[1] 1.0042 0.0073 0.0015 22.6124 50.2898 1.0651 ⋯ m[2] 2.0164 0.0052 0.0013 17.0329 29.6524 1.0903 ⋯ s[1] 1.7070 0.4554 0.0792 33.0317 NaN 0.9991 ⋯ s[2] 2.0000 0.0000 NaN NaN NaN NaN ⋯ s[3] 1.9920 0.0891 0.0101 77.5916 NaN 1.0071 ⋯ 1 column omitted Quantiles parameters 2.5% 25.0% 50.0% 75.0% 97.5% Symbol Float64 Float64 Float64 Float64 Float64 T[1][1] 0.0005 0.1448 0.6160 0.9715 0.9904 T[1][2] 0.0096 0.0285 0.3840 0.8552 0.9995 T[2][1] 0.0004 0.0203 0.1608 0.4824 0.6642 T[2][2] 0.3358 0.5176 0.8392 0.9797 0.9996 m[1] 0.9867 0.9986 1.0066 1.0083 1.0137 m[2] 2.0055 2.0136 2.0165 2.0183 2.0252 s[1] 1.0000 1.0000 2.0000 2.0000 2.0000 s[2] 2.0000 2.0000 2.0000 2.0000 2.0000 s[3] 2.0000 2.0000 2.0000 2.0000 2.0000