Stan是一种用于指定统计模型的概率编程语言。Stan通过马尔可夫链蒙特卡罗方法(例如No-U-Turn采样器,一种汉密尔顿蒙特卡洛采样的自适应形式)为连续变量模型提供了完整的贝叶斯推断。
可以通过R使用rstan
包来调用Stan,也可以 通过Python使用 pystan
包。这两个接口都支持基于采样和基于优化的推断,并带有诊断和后验分析。
在本文中,简要展示了Stan的主要特性。还显示了两个示例:第一个示例与简单的伯努利模型相关,第二个示例与基于常微分方程的Lotka-Volterra模型有关。
什么是Stan?
- Stan是命令式概率编程语言。
- Stan程序定义了概率模型。
- 它声明数据和(受约束的)参数变量。
- 它定义了对数后验。
- Stan推理:使模型拟合数据并做出预测。
- 它可以使用马尔可夫链蒙特卡罗(MCMC)进行完整的贝叶斯推断。
- 使用变分贝叶斯(VB)进行近似贝叶斯推断。
- 最大似然估计(MLE)用于惩罚最大似然估计。
Stan计算什么?
- 得出后验分布 。
- MCMC采样。
- 绘制顺序 ,其中每个绘制 都按后验概率 的边缘分布。
- 使用直方图,核密度估计等进行绘图
安装 rstan
要在R中运行Stan,必须安装 rstan
C ++编译器。在Windows上, Rtools 是必需的。
最后,安装 rstan
:
install.packages(rstan)
Stan中的基本语法
定义模型
Stan模型由六个程序块定义 :
- 数据(必填)。
- 转换后的数据。
- 参数(必填)。
- 转换后的参数。
- 模型(必填)。
- 生成的数量。
数据块读出的外部信息。
data { int N; int x[N]; int offset; }
变换后的数据 块允许数据的预处理。
transformed data { int y[N]; for (n in 1:N) y[n] = x[n] - offset; }
参数 块定义了采样的空间。
parameters { real<lower=0> lambda1; real<lower=0> lambda2; }
变换参数 块定义计算后验之前的参数处理。
transformed parameters { real<lower=0> lambda; lambda = lambda1 + lambda2; }
在 模型 块中,我们定义后验分布。
model { y ~ poisson(lambda); lambda1 ~ cauchy(0, 2.5); lambda2 ~ cauchy(0, 2.5); }
最后, 生成的数量 块允许进行后处理。
generated quantities { int x_predict; x_predict = poisson_rng(lambda) + offset; }
类型
Stan有两种原始数据类型, 并且两者都是有界的。
- int 是整数类型。
- real 是浮点类型。实数扩展到线性代数类型。
int<lower=1> N; real<upper=5> alpha; real<lower=-1,upper=1> beta; real gamma; real<upper=gamma> zeta;
vector[10] a; // 列向量matrix[10, 1] b; row_vector[10] c; // 行向量matrix[1, 10] d;
整数,实数,向量和矩阵的数组均可用。
real a[10]; vector[10] b; matrix[10, 10] c;
Stan还实现了各种 约束 类型。
simplex[5] theta; // sum(theta) = 1 ordered[5] o; // o[1] < ... < o[5]positive_ordered[5] p; corr_matrix[5] C; // 对称和cov_matrix[5] Sigma; // 正定的
关于Stan的更多信息
所有典型的判断和循环语句也都可用。
if/then/else for (i in 1:I) while (i < I)
有两种修改 后验的方法。
y ~ normal(0, 1); target += normal_lpdf(y | 0, 1); # 新版本的Stan中已弃用:increment_log_posterior(log_normal(y, 0, 1))
而且许多采样语句都是 矢量化的。
parameters {real mu[N];real<lower=0> sigma[N];} model {// for (n in 1:N)// y[n] ~ normal(mu[n], sigma[n]); y ~ normal(mu, sigma); // 向量化版本}
贝叶斯方法
概率是 认知的。例如, 约翰·斯图亚特·米尔 (John Stuart Mill)说:
事件的概率不是事件本身,而是我们或其他人期望发生的情况的程度。每个事件本身都是确定的,不是可能的;如果我们全部了解,我们应该或者肯定地知道它会发生,或者它不会。
对我们来说,概率表示对它发生的期望程度。
概率可以量化不确定性。
Stan的贝叶斯示例:重复试验模型
我们解决一个小例子,其中的目标是给定从伯努利分布中抽取的随机样本,以估计缺失参数的后验分布 (成功的机会)。
步骤1:问题定义
在此示例中,我们将考虑以下结构:
- 数据:
- ,试用次数。
- ,即试验n的结果 (已知的建模数据)。
- 参数:
- 先验分布
- 概率
- 后验分布
步骤2:Stan
我们创建Stan程序,我们将从R中调用它。
data {int<lower=0> N; // 试验次数int<lower=0, upper=1> y[N]; // 试验成功} model {theta ~ uniform(0, 1); // 先验y ~ bernoulli(theta);
步骤3:数据
在这种情况下,我们将使用示例随机模拟一个随机样本,而不是使用给定的数据集。
# 生成数据 y = rbinom(N, 1, 0.3)y ## [1] 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1
根据数据计算 MLE作为样本均值:
## [1] 0.25
步骤4:rstan
使用贝叶斯后验估计
最后一步是使用R中的Stan获得我们的估算值。
## ## SAMPLING FOR MODEL '6dcfbccbf2f063595ccc9b93f383e221' NOW (CHAIN 1). ## Chain 1: ## Chain 1: Gradient evaluation took 7e-06 seconds ## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.07 seconds. ## Chain 1: Adjust your expectations accordingly! ## Chain 1: ## Chain 1: ## Chain 1: Iteration: 1 / 5000 [ 0%] (Warmup) ## Chain 1: Iteration: 500 / 5000 [ 10%] (Warmup) ## Chain 1: Iteration: 1000 / 5000 [ 20%] (Warmup) ## Chain 1: Iteration: 1500 / 5000 [ 30%] (Warmup) ## Chain 1: Iteration: 2000 / 5000 [ 40%] (Warmup) ## Chain 1: Iteration: 2500 / 5000 [ 50%] (Warmup) ## Chain 1: Iteration: 2501 / 5000 [ 50%] (Sampling) ## Chain 1: Iteration: 3000 / 5000 [ 60%] (Sampling) ## Chain 1: Iteration: 3500 / 5000 [ 70%] (Sampling) ## Chain 1: Iteration: 4000 / 5000 [ 80%] (Sampling) ## Chain 1: Iteration: 4500 / 5000 [ 90%] (Sampling) ## Chain 1: Iteration: 5000 / 5000 [100%] (Sampling) ## Chain 1: ## Chain 1: Elapsed Time: 0.012914 seconds (Warm-up) ## Chain 1: 0.013376 seconds (Sampling) ## Chain 1: 0.02629 seconds (Total) ## Chain 1: ... ## SAMPLING FOR MODEL '6dcfbccbf2f063595ccc9b93f383e221' NOW (CHAIN 4). ## Chain 4: ## Chain 4: Gradient evaluation took 3e-06 seconds ## Chain 4: 1000 transitions using 10 leapfrog steps per transition would take 0.03 seconds. ## Chain 4: Adjust your expectations accordingly! ## Chain 4: ## Chain 4: ## Chain 4: Iteration: 1 / 5000 [ 0%] (Warmup) ## Chain 4: Iteration: 500 / 5000 [ 10%] (Warmup) ## Chain 4: Iteration: 1000 / 5000 [ 20%] (Warmup) ## Chain 4: Iteration: 1500 / 5000 [ 30%] (Warmup) ## Chain 4: Iteration: 2000 / 5000 [ 40%] (Warmup) ## Chain 4: Iteration: 2500 / 5000 [ 50%] (Warmup) ## Chain 4: Iteration: 2501 / 5000 [ 50%] (Sampling) ## Chain 4: Iteration: 3000 / 5000 [ 60%] (Sampling) ## Chain 4: Iteration: 3500 / 5000 [ 70%] (Sampling) ## Chain 4: Iteration: 4000 / 5000 [ 80%] (Sampling) ## Chain 4: Iteration: 4500 / 5000 [ 90%] (Sampling) ## Chain 4: Iteration: 5000 / 5000 [100%] (Sampling) ## Chain 4: ## Chain 4: Elapsed Time: 0.012823 seconds (Warm-up) ## Chain 4: 0.014169 seconds (Sampling) ## Chain 4: 0.026992 seconds (Total) ## Chain 4: