Сгенерированные количества с блоком преобразованных параметров - PullRequest
0 голосов
/ 26 марта 2020

Мне нужно расширить следующую модель с помощью блока сгенерированных количеств, но я не могу понять, как это сделать:

import pystan
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.style.use('ggplot')

data = pd.read_csv('unemployment.csv')

stan_code = """data {
  int <lower=0> T;
  vector[T] x;
  vector[T] y;
}

parameters {
  vector[T] u_err; //Slope innovation
  vector[T] v_err; //Level innovation 
  real beta;
  real <lower=0> s_obs;
  real <lower=0> s_slope;
  real <lower=0> s_level;
}

transformed parameters {
  vector[T] u; //Level
  vector[T] v; //Slope
  u[1] = u_err[1];
  v[1] = v_err[1];
  for (t in 2:T) {
    u[t] = u[t-1] + v[t-1] + s_level * u_err[t];
    v[t] = v[t-1] + s_slope * v_err[t];
  }
}

model {
  u_err ~ normal(0,1);
  v_err ~ normal(0,1);
  y ~ normal (u + beta*x, s_obs);
}"""

data_feed = {'y': data['unemployment.office'].values, 'x': np.zeros((data.shape[0], )), 'T': data.shape[0]}
sm = pystan.StanModel(model_code=stan_code)
fit = sm.sampling(data=data_feed, iter=1000)

Я внес следующие изменения в stan_code:

stan_code = """data {
  int <lower=0> T;
  vector[T] x;
  vector[T] y;
  int <lower=0> n_pred;
}

parameters {
  vector[T] u_err; //Slope innovation
  vector[T] v_err; //Level innovation
  real beta;
  real <lower=0> s_obs;
  real <lower=0> s_slope;
  real <lower=0> s_level;
}

transformed parameters {
  vector[T] u; //Level
  vector[T] v; //Slope
  u[1] = u_err[1];
  v[1] = v_err[1];
  for (t in 2:T) {
    u[t] = u[t-1] + v[t-1] + s_level * u_err[t];
    v[t] = v[t-1] + s_slope * v_err[t];
  }
}

model {
  u_err ~ normal(0,1);
  v_err ~ normal(0,1);
  y ~ normal (u + beta*x, s_obs);
}

generated quantities {
    vector[T+n_pred] u_pred;
    vector[T+n_pred] u_pred_err;
    vector[T+n_pred] v_pred;
    vector[T+n_pred] v_pred_err;
    vector[T+n_pred] y_pred;

    u_pred[1:T] = u;
    v_pred[1:T] = v;
    u_pred_err[1:T] = u_err;
    v_pred_err[1:T] = v_err;
    y_pred[1:T] = y;

    for (t in (T+1):(T+n_pred)) {
        u_pred_err[t] = normal_rng(0, 1);
        v_pred_err[t] = normal_rng(0, 1);
        u_pred[t] = u_pred[t-1] + v_pred[t-1] + s_level * u_err[t];
        v_pred[t] = v_pred[t-1] + s_slope * v_err[t];
        y_pred[t] = normal_rng(u_pred[t] + beta*x, s_obs);
    }
}

"""

Но я продолжаю получать ошибки при компиляции, не говоря уже о запуске модели.

1 Ответ

1 голос
/ 27 марта 2020

Вы должны опубликовать сообщение об ошибке, которое было

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Dimension mismatch in assignment; variable name = y_pred, type = real; right-hand side type = real[ ].
Illegal statement beginning with non-void expression parsed as
  y_pred[t]
Not a legal assignment, sampling, or function statement.  Note that
  * Assignment statements only allow variables (with optional indexes) on the left;
  * Sampling statements allow arbitrary value-denoting expressions on the left.
  * Functions used as statements must be declared to have void returns

 error in 'model50a15d294c93_gc' at line 52, column 8
  -------------------------------------------------
    50:         u_pred[t] = u_pred[t-1] + v_pred[t-1] + s_level * u_err[t];
    51:         v_pred[t] = v_pred[t-1] + s_slope * v_err[t];
    52:         y_pred[t] = normal_rng(u_pred[t] + beta*x, s_obs);
               ^
    53:     }
  -------------------------------------------------

Это явно говорит о том, что для переменной с именем y_pred и типом real (скаляр) вы пытаетесь назначить к нему правая часть, тип которой real[] (массив). Я думаю, что вы хотели индексировать вектор x:

y_pred[t] = normal_rng(u_pred[t] + beta * x[t], s_obs);
...