拓端數據tecdat|R語言RStan貝葉斯示例:重復試驗模型和種群競爭模型Lotka Volterra


原文鏈接:http://tecdat.cn/?p=19737

 

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模型由六個程序塊定義 :

  • 數據(必填)。
  • 轉換后的數據。
  • 參數(必填)。
  • 轉換后的參數。
  • 模型(必填)。
  • 生成的數量。

數據塊讀出的外部信息。

  1.  
    data {
  2.  
    int N;
  3.  
    int x[N];
  4.  
    int offset;
  5.  
    }

變換后的數據 塊允許數據的預處理。

  1.  
    transformed data {
  2.  
    int y[N];
  3.  
    for (n in 1:N)
  4.  
    y[n] = x[n] - offset;
  5.  
    }

 參數 塊定義了采樣的空間。

  1.  
    parameters {
  2.  
    real <lower=0> lambda1;
  3.  
    real <lower=0> lambda2;
  4.  
    }

變換參數 塊定義計算后驗之前的參數處理。

  1.  
    transformed parameters {
  2.  
    real<lower=0> lambda;
  3.  
    lambda = lambda1 + lambda2;
  4.  
    }

在 模型 塊中,我們定義后驗分布。

  1.  
    model {
  2.  
    y ~ poisson(lambda);
  3.  
    lambda1 ~ cauchy(0, 2.5);
  4.  
    lambda2 ~ cauchy(0, 2.5);
  5.  
    }

最后, 生成的數量 塊允許進行后處理。

  1.  
    generated quantities {
  2.  
    int x_predict;
  3.  
    x_predict = poisson_rng(lambda) + offset;
  4.  
    }

類型

Stan有兩種原始數據類型, 並且兩者都是有界的。

  • int 是整數類型。
  • real 是浮點類型。
  1.  
    int<lower=1> N;
  2.  
     
  3.  
    real<upper=5> alpha;
  4.  
    real<lower=-1,upper=1> beta;
  5.  
     
  6.  
    real gamma;
  7.  
    real<upper=gamma> zeta;

實數擴展到線性代數類型。

  1.  
    vector[10] a; // 列向量
  2.  
    matrix[10, 1] b;
  3.  
     
  4.  
    row_vector[10] c; // 行向量
  5.  
    matrix[1, 10] d;

整數,實數,向量和矩陣的數組均可用。

  1.  
    real a[10];
  2.  
     
  3.  
    vector[10] b;
  4.  
     
  5.  
    matrix[10, 10] c;

Stan還實現了各種 約束 類型。

  1.  
    simplex[5] theta; // sum(theta) = 1
  2.  
     
  3.  
    ordered[5] o; // o[1] < ... < o[5]
  4.  
    positive_ordered[5] p;
  5.  
     
  6.  
    corr_matrix[5] C; // 對稱和
  7.  
    cov_matrix[5] Sigma; // 正定的

關於Stan的更多信息

所有典型的判斷和循環語句也都可用。

  1.  
    if/then/else
  2.  
     
  3.  
    for ( i in 1:I)
  4.  
     
  5.  
    while ( i < I)

有兩種修改 后驗的方法。

  1.  
    y ~ normal(0, 1);
  2.  
     
  3.  
    target += normal_lpdf(y | 0, 1);
  4.  
     
  5.  
    # 新版本的Stan中已棄用:
  6.  
    increment_log_posterior(log_normal(y, 0, 1))

而且許多采樣語句都是 矢量化的

  1.  
    parameters {
  2.  
    real mu[N];
  3.  
    real<lower=0> sigma[N];
  4.  
    }
  5.  
     
  6.  
    model {
  7.  
    // for (n in 1:N)
  8.  
    // y[n] ~ normal(mu[n], sigma[n]);
  9.  
     
  10.  
    y ~ normal(mu, sigma); // 向量化版本
  11.  
    }

貝葉斯方法

概率是 認知的。例如, 約翰·斯圖亞特·米爾 (John Stuart Mill)說:

事件的概率不是事件本身,而是我們或其他人期望發生的情況的程度。每個事件本身都是確定的,不是可能的;如果我們全部了解,我們應該或者肯定地知道它會發生,或者它不會。

對我們來說,概率表示對它發生的期望程度。

概率可以量化不確定性。

Stan的貝葉斯示例:重復試驗模型

我們解決一個小例子,其中的目標是給定從伯努利分布中抽取的隨機樣本,以估計缺失參數的后驗分布  (成功的機會)。

步驟1:問題定義

在此示例中,我們將考慮以下結構:

  • 數據:

    • ,試用次數。
    • ,即試驗n的結果  (已知的建模數據)。
  • 參數:

  • 先驗分布

  • 概率

  • 后驗分布

步驟2:Stan

我們創建Stan程序,我們將從R中調用它。

  1.  
     
  2.  
    data {
  3.  
    int<lower=0> N; // 試驗次數
  4.  
    int<lower=0, upper=1> y[N]; // 試驗成功
  5.  
    }
  6.  
     
  7.  
     
  8.  
    model {
  9.  
    theta ~ uniform( 0, 1); // 先驗
  10.  
    y ~ bernoulli(theta); // 似然
  11.  
    }

步驟3:數據

在這種情況下,我們將使用示例隨機模擬一個隨機樣本,而不是使用給定的數據集。

  1.  
    # 生成數據
  2.  
     
  3.  
    y = rbinom(N, 1, 0.3)
  4.  
    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獲得我們的估算值。

  1.  
    ##
  2.  
    ## SAMPLING FOR MODEL '6dcfbccbf2f063595ccc9b93f383e221' NOW (CHAIN 1).
  3.  
    ## Chain 1:
  4.  
    ## Chain 1: Gradient evaluation took 7e-06 seconds
  5.  
    ## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.07 seconds.
  6.  
    ## Chain 1: Adjust your expectations accordingly!
  7.  
    ## Chain 1:
  8.  
    ## Chain 1:
  9.  
    ## Chain 1: Iteration: 1 / 5000 [ 0%] (Warmup)
  10.  
    ## Chain 1: Iteration: 500 / 5000 [ 10%] (Warmup)
  11.  
    ## Chain 1: Iteration: 1000 / 5000 [ 20%] (Warmup)
  12.  
    ## Chain 1: Iteration: 1500 / 5000 [ 30%] (Warmup)
  13.  
    ## Chain 1: Iteration: 2000 / 5000 [ 40%] (Warmup)
  14.  
    ## Chain 1: Iteration: 2500 / 5000 [ 50%] (Warmup)
  15.  
    ## Chain 1: Iteration: 2501 / 5000 [ 50%] (Sampling)
  16.  
    ## Chain 1: Iteration: 3000 / 5000 [ 60%] (Sampling)
  17.  
    ## Chain 1: Iteration: 3500 / 5000 [ 70%] (Sampling)
  18.  
    ## Chain 1: Iteration: 4000 / 5000 [ 80%] (Sampling)
  19.  
    ## Chain 1: Iteration: 4500 / 5000 [ 90%] (Sampling)
  20.  
    ## Chain 1: Iteration: 5000 / 5000 [100%] (Sampling)
  21.  
    ## Chain 1:
  22.  
    ## Chain 1: Elapsed Time: 0.012914 seconds (Warm-up)
  23.  
    ## Chain 1: 0.013376 seconds (Sampling)
  24.  
    ## Chain 1: 0.02629 seconds (Total)
  25.  
    ## Chain 1:
  26.  
    ...
  27.  
     
  28.  
    # # SAMPLING FOR MODEL '6dcfbccbf2f063595ccc9b93f383e221' NOW (CHAIN 4).
  29.  
    ## Chain 4:
  30.  
    ## Chain 4: Gradient evaluation took 3e-06 seconds
  31.  
    ## Chain 4: 1000 transitions using 10 leapfrog steps per transition would take 0.03 seconds.
  32.  
    ## Chain 4: Adjust your expectations accordingly!
  33.  
    ## Chain 4:
  34.  
    ## Chain 4:
  35.  
    ## Chain 4: Iteration: 1 / 5000 [ 0%] (Warmup)
  36.  
    ## Chain 4: Iteration: 500 / 5000 [ 10%] (Warmup)
  37.  
    ## Chain 4: Iteration: 1000 / 5000 [ 20%] (Warmup)
  38.  
    ## Chain 4: Iteration: 1500 / 5000 [ 30%] (Warmup)
  39.  
    ## Chain 4: Iteration: 2000 / 5000 [ 40%] (Warmup)
  40.  
    ## Chain 4: Iteration: 2500 / 5000 [ 50%] (Warmup)
  41.  
    ## Chain 4: Iteration: 2501 / 5000 [ 50%] (Sampling)
  42.  
    ## Chain 4: Iteration: 3000 / 5000 [ 60%] (Sampling)
  43.  
    ## Chain 4: Iteration: 3500 / 5000 [ 70%] (Sampling)
  44.  
    ## Chain 4: Iteration: 4000 / 5000 [ 80%] (Sampling)
  45.  
    ## Chain 4: Iteration: 4500 / 5000 [ 90%] (Sampling)
  46.  
    ## Chain 4: Iteration: 5000 / 5000 [100%] (Sampling)
  47.  
    ## Chain 4:
  48.  
    ## Chain 4: Elapsed Time: 0.012823 seconds (Warm-up)
  49.  
    ## Chain 4: 0.014169 seconds (Sampling)
  50.  
    ## Chain 4: 0.026992 seconds (Total)
  51.  
    ## Chain 4:
  1.  
    ## Inference for Stan model: 6dcfbccbf2f063595ccc9b93f383e221.
  2.  
    ## 4 chains, each with iter=5000; warmup=2500; thin=1;
  3.  
    ## post-warmup draws per chain=2500, total post-warmup draws=10000.
  4.  
    ##
  5.  
    ## mean se_mean sd 10% 90% n_eff Rhat
  6.  
    ## theta 0.27 0.00 0.09 0.16 0.39 3821 1
  7.  
    ## lp__ -13.40 0.01 0.73 -14.25 -12.90 3998 1
  8.  
    ##
  1.  
    # 提取后驗抽樣
  2.  
    # 計算后均值(估計)
  3.  
    mean(theta _draws)
## [1] 0.2715866
# 計算后驗區間 
  1.  
    ## 10% 90%
  2.  
    ## 0.1569165 0.3934832
  1.  
    ggplot( theta_draws_df, aes(x=theta)) +
  2.  
    geom_histogram( bins=20, color="gray")

 

RStan:MAP,MLE

Stan的估算優化;兩種觀點:

  • 最大后驗估計(MAP)
  • 最大似然估計(MLE)。
optimizing(model, data=c("N", "y")) 
  1.  
    ## $par
  2.  
    ## theta
  3.  
    ## 0.4
  4.  
    ##
  5.  
    ## $value
  6.  
    ## [1] -3.4
  7.  
    ##
  8.  
    ## $return_code
  9.  
    ## [1] 0

種群競爭模型 ---Lotka-Volterra模型

  • 洛特卡(Lotka,1925)和沃爾泰拉(Volterra,1926)制定了參數化微分方程,描述了食肉動物和獵物的競爭種群。
  • 完整的貝葉斯推斷可用於估計未來(或過去)的種群數量。
  • Stan用於對統計模型進行編碼並執行完整的貝葉斯推理,以解決從噪聲數據中推斷參數的逆問題。

 

在此示例中,我們希望根據公司每年收集的毛皮數量,將模型擬合到1900年至1920年之間各自種群的加拿大貓科食肉動物和野兔獵物。

數學模型

我們表示U(t)和V(t)作為獵物和捕食者種群數量 分別。與它們相關的微分方程為:

這里:

  • α:獵物增長速度。
  • β:捕食引起的獵物減少速度。
  • γ:自然的捕食者減少速度。
  • δ:捕食者從捕食中增長速度。

stan中的Lotka-Volterra

  1.  
    real[] dz_dt(data real t, // 時間
  2.  
    real[] z, // 系統狀態
  3.  
    real[] theta, // 參數
  4.  
    data real[] x_r, // 數值數據
  5.  
    data int[] x_i) // 整數數據
  6.  
    {
  7.  
    real u = z[1]; // 提取狀態
  8.  
    real v = z[2];

觀察到已知變量:

  • :表示在時間 物種數量

必須推斷未知變量):

  • 初始狀態: :k的初始物種數量。
  • 后續狀態:在時間t的物種數量k。
  • 參量 

假設誤差是成比例的(而不是相加的):

等效:

建立模型

已知常數和觀測數據的變量。

  1.  
    data {
  2.  
    int<lower = 0> N; // 數量測量
  3.  
    real ts[N]; // 測量次數>0
  4.  
    real y0[2]; // 初始數量
  5.  
    real<lower=0> y[N,2]; // 后續數量
  6.  
    }

未知參數的變量。

  1.  
    parameters {
  2.  
    real<lower=0> theta[4]; // alpha, beta, gamma, delta
  3.  
    real<lower=0> z0[2]; // 原始種群
  4.  
    real<lower=0> sigma[2]; // 預測誤差
  5.  
    }

先驗分布和概率。

  1.  
    model {
  2.  
    // 先驗
  3.  
    sigma ~ lognormal(0, 0.5);
  4.  
    theta[{1, 3}] ~ normal(1, 0.5);
  5.  
     
  6.  
    // 似然(對數正態)
  7.  
    for (k in 1:2) {
  8.  
    y0[k] ~ lognormal(log(z0[k]), sigma[k]);

我們必須為預測的總體定義變量 :

  • 初始種群(z0)。
  • 初始時間(0.0),時間(ts)。
  • 參數(theta)。
  • 最大迭代次數(1e3)。

Lotka-Volterra參數估計

print(fit, c("theta", "sigma"), probs=c(0.1, 0.5, 0.9))

獲得結果:

  1.  
    mean se_mean sd 10% 50% 90% n_eff Rhat
  2.  
    ## theta[1] 0.55 0 0.07 0.46 0.54 0.64 1168 1
  3.  
    ## theta[2] 0.03 0 0.00 0.02 0.03 0.03 1305 1
  4.  
    ## theta[3] 0.80 0 0.10 0.68 0.80 0.94 1117 1
  5.  
    ## theta[4] 0.02 0 0.00 0.02 0.02 0.03 1230 1
  6.  
    ## sigma[1] 0.29 0 0.05 0.23 0.28 0.36 2673 1
  7.  
    ## sigma[2] 0.29 0 0.06 0.23 0.29 0.37 2821 1

分析所得結果:

  • Rhat接近1表示收斂;n_eff是有效樣本大小。
  • 10%,后驗分位數;例如
  • 后驗均值是貝葉斯點估計:α=0.55。
  • 后驗平均估計的標准誤為0。
  • α的后驗標准偏差為0.07。

最受歡迎的見解

1.matlab使用貝葉斯優化的深度學習

2.matlab貝葉斯隱馬爾可夫hmm模型實現

3.R語言Gibbs抽樣的貝葉斯簡單線性回歸仿真

4.R語言中的block Gibbs吉布斯采樣貝葉斯多元線性回歸

5.R語言中的Stan概率編程MCMC采樣的貝葉斯模型

6.Python用PyMC3實現貝葉斯線性回歸模型

7.R語言使用貝葉斯 層次模型進行空間數據分析

8.R語言隨機搜索變量選擇SSVS估計貝葉斯向量自回歸(BVAR)模型

9.matlab貝葉斯隱馬爾可夫hmm模型實現

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM