将“缺失”参数传递给 Turing.jl 中的伯努利模型

Passing `missing` argument to a bernoulli model in Turing.jl

Turing.jl 有一个 guide 展示了如何编写允许您传递数据或 missing 参数的模型。在第一种情况下,它将为您提供后验,而在第二种情况下,它将从所有变量中提取。

设置

using Turing
iterations = 1000
ϵ = 0.05
τ = 10

工作示例是这样的:

@model gdemo(x, ::Type{T} = Float64) where {T} = begin
    if x === missing
        # Initialize `x` if missing
        x = Vector{T}(undef, 2)
    end
    s ~ InverseGamma(2, 3)
    m ~ Normal(0, sqrt(s))
    for i in eachindex(x)
        x[i] ~ Normal(m, sqrt(s))
    end
end

# Construct a model with x = missing
model = gdemo(missing)
c = sample(model, HMC(0.01, 5), 500);

我尝试将此代码改编为简单的掷硬币。我认为 bernoulli 分布应该具有数据类型 Bool(不过我也尝试使用 Int64)。我试过这样做:

@model coinflip2(y) = begin
    if y === missing
        y = Vector{Bool}(undef, 4)
    end
    p ~ Beta(1, 1)
    N = length(y)
    for n in 1:N
        y[n] ~ Bernoulli(p)
    end
end;

chain = sample(coinflip2(missing), HMC(ϵ, τ), iterations);

但它给了我一条很长的错误消息,我没有得到但很可能指向类型问题:

MethodError: Bool(::ForwardDiff.Dual{ForwardDiff.Tag{Turing.Core.var"#f#7"{DynamicPPL.VarInfo{NamedTuple{(:p, :y),Tuple{DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:p,Tuple{}},Int64},Array{Beta{Float64},1},

尝试模仿上面工作的 gdemo 函数的语法(我没有完全理解),给你:

@model coinflip2(y, ::Type{T} = Bool) where {T} = begin
    if y === missing
        y = Vector{T}(undef, 4)
    end
    p ~ Beta(1, 1)
    N = length(y)
    for n in 1:N
        y[n] ~ Bernoulli(p)
    end
end;

chain = sample(coinflip2(missing), HMC(ϵ, τ), iterations);

它也失败并出现以以下内容开头的错误消息:

MethodError: Bool(::ForwardDiff.Dual{ForwardDiff.Tag{Turing.Core.var"#f#7"{DynamicPPL.VarInfo{NamedTuple{(:p, :y),Tuple{DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:p,Tuple{}},Int64},Array{Beta{Float64},1}

如何正确书写?解释我做错了什么的奖励积分:D 谢谢!

Hamiltonian Monte Carlo 仅适用于连续分布,因为它区分了 PDF 的函数。当您从联合模型 (p, y) 中采样时,这也适用于随机变量 y,它是伯努利,当然 不是 连续的。因此,后台使用的AD系统(默认ForwardDiff)会报错

您可以通过使用 Gibbs:

y 指定一个非哈密顿采样器来解决这个问题
chain = sample(coinflip2(missing), Gibbs(HMC(ϵ, τ, :p), MH(:y)), iterations)

MH 可能不是最佳选择,您必须自己考虑一下,但它确实有效。

请注意,这对于参数估计不是必需的:给定 yp 是连续的并且使 HMC 满意:

chain = sample(coinflip2([0,1,1,0]), HMC(ϵ, τ), iterations)