m10.04d2

Load Julia packages (libraries) needed for the snippets in chapter 0

using DynamicHMCModels, ForwardDiff, Flux, ReverseDiff
gr(size=(400,400))

CmdStan uses a tmp directory to store the output of cmdstan

ProjDir = rel_path_d("..", "scripts", "10")
cd(ProjDir)

snippet 10.4

d = CSV.read(rel_path("..", "data", "chimpanzees.csv"), delim=';');
df = convert(DataFrame, d);
df[:pulled_left] = convert(Array{Int64}, df[:pulled_left])
df[:prosoc_left] = convert(Array{Int64}, df[:prosoc_left])
df[:condition] = convert(Array{Int64}, df[:condition])
df[:actor] = convert(Array{Int64}, df[:actor])
first(df[[:actor, :pulled_left, :prosoc_left, :condition]], 5)

struct m_10_04d_model{TY <: AbstractVector, TX <: AbstractMatrix,
  TA <: AbstractVector}
    "Observations."
    y::TY
    "Covariates"
    X::TX
    "Actors"
    A::TA
    "Number of observations"
    N::Int
    "Number of unique actors"
    N_actors::Int
end

Make the type callable with the parameters as a single argument.

function (problem::m_10_04d_model)(θ)
    @unpack y, X, A, N, N_actors = problem   # extract the data
    @unpack β, α = θ  # works on the named tuple too
    ll = 0.0
    ll += sum(logpdf.(Normal(0, 10), β)) # bp & bpC
    ll += sum(logpdf.(Normal(0, 10), α)) # alpha[1:7]
    ll += sum(
      [loglikelihood(Binomial(1, logistic(α[A[i]] + dot(X[i, :], β))), [y[i]]) for i in 1:N]
    )
    ll
end

Instantiate the model with data and inits.

N = size(df, 1)
N_actors = length(unique(df[:actor]))
X = hcat(ones(Int64, N), df[:prosoc_left] .* df[:condition]);
A = df[:actor]
y = df[:pulled_left]
p = m_10_04d_model(y, X, A, N, N_actors);
θ = (β = [1.0, 0.0], α = [-1.0, 10.0, -1.0, -1.0, -1.0, 0.0, 2.0])
p(θ)
-305.21943396408915

Write a function to return properly dimensioned transformation.

problem_transformation(p::m_10_04d_model) =
    as( (β = as(Array, size(p.X, 2)), α = as(Array, p.N_actors), ) )

Wrap the problem with a transformation, then use Flux for the gradient.

P = TransformedLogDensity(problem_transformation(p), p)
TransformedLogDensity of dimension 9

For stress testing

stresstest = false

#ad = :Flux
ad = :ForwardDiff
#ad = :ReverseDiff

if stresstest
  ∇P = ADgradient(:ForwardDiff, P);
  LogDensityProblems.stresstest(p, N=1000, scale=1.0)
else
  ∇P = LogDensityRejectErrors(ADgradient(ad, P));
end
LogDensityRejectErrors{InvalidLogDensityException,LogDensityProblems.ForwardDiffLogDensity{TransformedLogDensity{TransformVariables.TransformNamedTuple{(:β, :α),Tuple{TransformVariables.ArrayTransform{TransformVariables.Identity,1},TransformVariables.ArrayTransform{TransformVariables.Identity,1}}},Main.ex-m10.04d2.m_10_04d_model{Array{Int64,1},Array{Int64,2},Array{Int64,1}}},ForwardDiff.GradientConfig{ForwardDiff.Tag{getfield(LogDensityProblems, Symbol("##1#2")){TransformedLogDensity{TransformVariables.TransformNamedTuple{(:β, :α),Tuple{TransformVariables.ArrayTransform{TransformVariables.Identity,1},TransformVariables.ArrayTransform{TransformVariables.Identity,1}}},Main.ex-m10.04d2.m_10_04d_model{Array{Int64,1},Array{Int64,2},Array{Int64,1}}}},Float64},Float64,9,Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(LogDensityProblems, Symbol("##1#2")){TransformedLogDensity{TransformVariables.TransformNamedTuple{(:β, :α),Tuple{TransformVariables.ArrayTransform{TransformVariables.Identity,1},TransformVariables.ArrayTransform{TransformVariables.Identity,1}}},Main.ex-m10.04d2.m_10_04d_model{Array{Int64,1},Array{Int64,2},Array{Int64,1}}}},Float64},Float64,9},1}}}}(ForwardDiff AD wrapper for TransformedLogDensity of dimension 9, w/ chunk size 9)

Run N chains

posterior = Vector{Array{NamedTuple{(:β, :α),Tuple{Array{Float64,1},
  Array{Float64,1}}},1}}(undef, 4)

for i in 1:4
  chain, NUTS_tuned = NUTS_init_tune_mcmc(∇P, 1000);
  posterior[i] = TransformVariables.transform.(Ref(problem_transformation(p)),
    get_position.(chain));
end
MCMC, adapting ϵ (75 steps)
0.014 s/step ...done
MCMC, adapting ϵ (25 steps)
0.015 s/step ...done
MCMC, adapting ϵ (50 steps)
0.013 s/step ...done
MCMC, adapting ϵ (100 steps)
0.0099 s/step ...done
MCMC, adapting ϵ (200 steps)
step 158 (of 200), 0.0063 s/step
0.0063 s/step ...done
MCMC, adapting ϵ (400 steps)
step 208 (of 400), 0.0049 s/step
0.0044 s/step ...done
MCMC, adapting ϵ (50 steps)
0.0062 s/step ...done
MCMC (1000 steps)
step 215 (of 1000), 0.0047 s/step
step 446 (of 1000), 0.0045 s/step
step 675 (of 1000), 0.0045 s/step
step 892 (of 1000), 0.0045 s/step
0.0045 s/step ...done
MCMC, adapting ϵ (75 steps)
0.012 s/step ...done
MCMC, adapting ϵ (25 steps)
0.011 s/step ...done
MCMC, adapting ϵ (50 steps)
0.011 s/step ...done
MCMC, adapting ϵ (100 steps)
0.0082 s/step ...done
MCMC, adapting ϵ (200 steps)
step 149 (of 200), 0.0067 s/step
0.0063 s/step ...done
MCMC, adapting ϵ (400 steps)
step 187 (of 400), 0.0054 s/step
0.0046 s/step ...done
MCMC, adapting ϵ (50 steps)
0.0056 s/step ...done
MCMC (1000 steps)
step 220 (of 1000), 0.0046 s/step
step 437 (of 1000), 0.0046 s/step
step 650 (of 1000), 0.0046 s/step
step 858 (of 1000), 0.0047 s/step
0.0047 s/step ...done
MCMC, adapting ϵ (75 steps)
0.019 s/step ...done
MCMC, adapting ϵ (25 steps)
0.01 s/step ...done
MCMC, adapting ϵ (50 steps)
0.014 s/step ...done
MCMC, adapting ϵ (100 steps)
0.0063 s/step ...done
MCMC, adapting ϵ (200 steps)
step 155 (of 200), 0.0065 s/step
0.006 s/step ...done
MCMC, adapting ϵ (400 steps)
step 212 (of 400), 0.0047 s/step
0.0045 s/step ...done
MCMC, adapting ϵ (50 steps)
0.0046 s/step ...done
MCMC (1000 steps)
step 209 (of 1000), 0.0048 s/step
step 423 (of 1000), 0.0048 s/step
step 639 (of 1000), 0.0047 s/step
step 863 (of 1000), 0.0047 s/step
0.0047 s/step ...done
MCMC, adapting ϵ (75 steps)
0.017 s/step ...done
MCMC, adapting ϵ (25 steps)
0.0098 s/step ...done
MCMC, adapting ϵ (50 steps)
0.01 s/step ...done
MCMC, adapting ϵ (100 steps)
0.008 s/step ...done
MCMC, adapting ϵ (200 steps)
step 165 (of 200), 0.0061 s/step
0.006 s/step ...done
MCMC, adapting ϵ (400 steps)
step 233 (of 400), 0.0043 s/step
0.0044 s/step ...done
MCMC, adapting ϵ (50 steps)
0.0048 s/step ...done
MCMC (1000 steps)
step 206 (of 1000), 0.0049 s/step
step 420 (of 1000), 0.0048 s/step
step 624 (of 1000), 0.0048 s/step
step 840 (of 1000), 0.0048 s/step
0.0047 s/step ...done

Result rethinking

rethinking = "
      mean   sd  5.5% 94.5% n_eff Rhat
a[1] -0.74 0.27 -1.19 -0.31  2899    1
a[2] 10.77 5.20  4.60 20.45  1916    1
a[3] -1.05 0.28 -1.50 -0.62  3146    1
a[4] -1.05 0.28 -1.50 -0.61  3525    1
a[5] -0.73 0.28 -1.17 -0.28  3637    1
a[6]  0.22 0.27 -0.21  0.67  3496    1
a[7]  1.82 0.41  1.21  2.50  3202    1
bp    0.83 0.27  0.42  1.27  2070    1
bpC  -0.13 0.31 -0.62  0.34  3430    1
";
"\n      mean   sd  5.5% 94.5% n_eff Rhat\na[1] -0.74 0.27 -1.19 -0.31  2899    1\na[2] 10.77 5.20  4.60 20.45  1916    1\na[3] -1.05 0.28 -1.50 -0.62  3146    1\na[4] -1.05 0.28 -1.50 -0.61  3525    1\na[5] -0.73 0.28 -1.17 -0.28  3637    1\na[6]  0.22 0.27 -0.21  0.67  3496    1\na[7]  1.82 0.41  1.21  2.50  3202    1\nbp    0.83 0.27  0.42  1.27  2070    1\nbpC  -0.13 0.31 -0.62  0.34  3430    1\n"

Set varable names

parameter_names = ["bp", "bpC"]
pooled_parameter_names = ["a[$i]" for i in 1:7]
7-element Array{String,1}:
 "a[1]"
 "a[2]"
 "a[3]"
 "a[4]"
 "a[5]"
 "a[6]"
 "a[7]"

Create a3d

a3d = Array{Float64, 3}(undef, 1000, 9, 4);
for j in 1:4
  for i in 1:1000
    a3d[i, 1:2, j] = values(posterior[j][i][1])
    a3d[i, 3:9, j] = values(posterior[j][i][2])
  end
end

chns = MCMCChains.Chains(a3d,
  vcat(parameter_names, pooled_parameter_names),
  Dict(
    :parameters => parameter_names,
    :pooled => pooled_parameter_names
  )
);
Object of type Chains, with data of type 1000×9×4 Array{Float64,3}

Log evidence      = 0.0
Iterations        = 1:1000
Thinning interval = 1
Chains            = 1, 2, 3, 4
Samples per chain = 1000
pooled            = a[1], a[2], a[3], a[4], a[5], a[6], a[7]
parameters        = bp, bpC

parameters
     Mean    SD   Naive SE  MCSE   ESS
 bp 1.4813 3.5252   0.0557 0.0754 1000
bpC 0.4098 0.2437   0.0039 0.0034 1000

Describe the chain

describe(chns)
Log evidence      = 0.0
Iterations        = 1:1000
Thinning interval = 1
Chains            = 1, 2, 3, 4
Samples per chain = 1000
parameters        = bp, bpC

Empirical Posterior Estimates
──────────────────────────────────────────
parameters
     Mean    SD   Naive SE  MCSE   ESS
 bp 1.4813 3.5252   0.0557 0.0754 1000
bpC 0.4098 0.2437   0.0039 0.0034 1000

Quantiles
──────────────────────────────────────────
parameters
      2.5%    25.0%   50.0%  75.0%  97.5%
 bp -10.5565 -0.8979 1.4917 3.8829 12.1537
bpC  -0.4207  0.2435 0.4107 0.5756  1.5195

Describe the chain

describe(chns, section=:pooled)
Log evidence      = 0.0
Iterations        = 1:1000
Thinning interval = 1
Chains            = 1, 2, 3, 4
Samples per chain = 1000
pooled            = a[1], a[2], a[3], a[4], a[5], a[6], a[7]

Empirical Posterior Estimates
─────────────────────────────────────────────
pooled
       Mean    SD   Naive SE  MCSE   ESS
a[1] -1.9205 3.5272   0.0558 0.0750 1000
a[2] 10.0882 6.1479   0.0972 0.1462 1000
a[3] -2.2276 3.5309   0.0558 0.0756 1000
a[4] -2.2246 3.5311   0.0558 0.0761 1000
a[5] -1.9258 3.5353   0.0559 0.0743 1000
a[6] -0.9982 3.5373   0.0559 0.0757 1000
a[7]  0.5566 3.5314   0.0558 0.0771 1000

Quantiles
─────────────────────────────────────────────
pooled
       2.5%    25.0%   50.0%   75.0%   97.5%
a[1] -12.9120 -4.3099 -1.9193  0.5005 10.3960
a[2]  -5.6394  5.6250  9.5843 13.9126 32.8906
a[3] -13.0093 -4.6430 -2.2524  0.1682  9.4858
a[4] -13.3029 -4.5972 -2.2408  0.1639 10.1828
a[5] -12.6149 -4.3398 -1.9261  0.4659 10.4256
a[6] -11.5104 -3.3880 -1.0156  1.4154 11.1344
a[7] -10.7024 -1.8301  0.5457  2.9491 12.8552

Plot the chain parameters

plot(chns)
0 250 500 750 1000 -10 -5 0 5 10 bp Iteration Sample value -10 -5 0 5 10 15 0.000 0.025 0.050 0.075 0.100 bp Sample value Density 0 250 500 750 1000 0.0 0.5 1.0 1.5 bpC Iteration Sample value -0.5 0.0 0.5 1.0 1.5 0.0 0.5 1.0 1.5 bpC Sample value Density

Plot the chain pooled parameters

plot(chns, section=:pooled)
0 250 500 750 1000 -10 -5 0 5 10 a[1] Iteration Sample value -15 -10 -5 0 5 10 0.000 0.025 0.050 0.075 0.100 a[1] Sample value Density 0 250 500 750 1000 0 10 20 30 a[2] Iteration Sample value -10 0 10 20 30 40 0.00 0.01 0.02 0.03 0.04 0.05 0.06 a[2] Sample value Density 0 250 500 750 1000 -10 -5 0 5 10 a[3] Iteration Sample value -15 -10 -5 0 5 10 0.000 0.025 0.050 0.075 0.100 a[3] Sample value Density 0 250 500 750 1000 -10 -5 0 5 10 a[4] Iteration Sample value -15 -10 -5 0 5 10 0.000 0.025 0.050 0.075 0.100 a[4] Sample value Density 0 250 500 750 1000 -10 -5 0 5 10 a[5] Iteration Sample value -15 -10 -5 0 5 10 0.000 0.025 0.050 0.075 0.100 a[5] Sample value Density 0 250 500 750 1000 -10 -5 0 5 10 a[6] Iteration Sample value -15 -10 -5 0 5 10 15 0.000 0.025 0.050 0.075 0.100 a[6] Sample value Density 0 250 500 750 1000 -10 -5 0 5 10 a[7] Iteration Sample value -10 -5 0 5 10 15 0.000 0.025 0.050 0.075 0.100 a[7] Sample value Density

End of m10.04d1.jl

This page was generated using Literate.jl.