【问题标题】:Writing a custom Probit function in Stan在 Stan 中编写自定义 Probit 函数
【发布时间】:2019-05-16 10:19:24
【问题描述】:

我正在尝试在 Stan 中编写一个自定义 Probit 函数,以提高我对 Stan 语言和可能性的理解。到目前为止,我已经编写了普通 pdf 的对数,但收到一条错误消息,当我尝试编写可能性时,我发现该消息难以理解。我做错了什么?

斯坦模型

functions {
    real normal_lpdf(real mu, real sigma) {
      return -log(2 * pi()) / 2 - log(sigma) 
             - square(mu) / (2 * sigma^2);
    }
    real myprobit_lpdf(int y | real mu, real sigma) {
      return normal_lpdf(mu, sigma)^y * (1 - normal_lpdf(mu, sigma))^(1-y);
    }
}

data {
    int N;
    int y[N];
}

parameters {
    real mu;
    real<lower = 0> sigma;
}

model {
    for (n in 1:N) {
        target += myprobit_lpdf(y[n] | mu, sigma);
    }
}

错误

解析器预期: stanc(model_code = paste(program, collapse = "\n"), model_name = model_cppname, 中的错误: 由于上述错误,无法解析 Stan 模型“Probit_lpdf”。

R 代码模拟数据

## DESCRIPTION

# testing a Probit model

## DATA
N <- 2000
sigma <- 1
mu <- 0.3
u <- rnorm(N, 0, 2)
y.star <- rnorm(N, mu, sigma)
y <- ifelse(y.star > 0,1, 0)

data = list(
    N = N,
    y = y
)

## MODEL
out.stan <- stan("Probit_lpdf.stan",data = data, chains = 2, iter = 1000 )

【问题讨论】:

    标签: stan


    【解决方案1】:

    完整的错误信息是

    SYNTAX ERROR, MESSAGE(S) FROM PARSER:
    Probabilty functions with suffixes _lpdf, _lpmf, _lcdf, and _lccdf,
    require a vertical bar (|) between the first two arguments.
     error in 'model2a7252aef8cf_probit' at line 7, column 27
      -------------------------------------------------
         5:     }
         6:     real myprobit_lpdf(real y,  real mu, real sigma) {
         7:       return normal_lpdf(mu, sigma)^y * (1 - normal_lpdf(mu, sigma))^(1-y);
                                      ^
         8:     }
      -------------------------------------------------
    

    这告诉您normal_lpdf 函数除了三个输入和一个将第一个与第二个分隔开的竖线。

    将您的函数与 Stan 语言中已有的函数同名也不是一个好主意,例如 normal_lpdf

    但是您编写的函数无论如何都没有实现概率模型的对数似然。首先,误差的标准差没有被数据识别,所以你不需要sigma。那么,正确的表达方式应该是这样的

    real Phi_mu = Phi(mu);
    real log_Phi_mu = log(Phi_mu);
    real log1m_Phi_mu = log1m(Phi_mu);
    for (n in 1:N)
      target += y[n] == 1 ? log_Phi_mu : log1m_Phi_mu;
    

    虽然这只是一种缓慢的做法

    target += bernoulli_lpmf(y | Phi(mu));
    

    【讨论】:

    • 谢谢!只是为了澄清 Phi 是标准偏差为 1 的正态分布的 CDF?为什么最后一行不是“target += y[n] ==1 ? log_Phi_mu : log1m_Phi_mu;”
    • Phi 是标准正态分布的 CDF。我修复了 for 循环。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 2016-02-14
    • 2018-12-16
    • 2023-03-27
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多