将“缺失”参数传递给 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 可能不是最佳选择,您必须自己考虑一下,但它确实有效。
请注意,这对于参数估计不是必需的:给定 y
的 p
是连续的并且使 HMC 满意:
chain = sample(coinflip2([0,1,1,0]), HMC(ϵ, τ), iterations)
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 可能不是最佳选择,您必须自己考虑一下,但它确实有效。
请注意,这对于参数估计不是必需的:给定 y
的 p
是连续的并且使 HMC 满意:
chain = sample(coinflip2([0,1,1,0]), HMC(ϵ, τ), iterations)