Problems adjusting Linear Regression at Stan - r

I'm having trouble adjusting a linear regression model on the stan. When observing the error message, the identification in the block part of the transformed parameters is noted.
See below the structure of the code in stan.
Packages:
library(rstan)
library(bayesplot)
Data:
head(Orange)
cols <- c(colnames(Orange[-1]))
Orange <- Orange[,cols]
str(Orange)
Code in stan:
See that the block structure within the stan follows the recommended pattern, however I am not able to identify which part of the code may seem wrong to me.
y = Orange$circumference
x = Orange$age
n = length(y)
regresstan = '
data{
int n;
real y[n];
real x[n];
}
parameters{
real alpha;
real beta;
real sigma;
}
transformed parameters{
real mu[n];
mu = alpha + beta*x;
}
model{
//Priors
alpha ~ normal(0, 100);
beta ~ normal(0, 100);
sigma ~ uniform(0, 100);
//Likelihood
y ~ normal(mu, sigma);
}
'
Error:
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
No matches for:
real * real[ ]
Available argument signatures for operator*:
real * real
vector * real
row_vector * real
matrix * real
row_vector * vector
vector * row_vector
matrix * vector
row_vector * matrix
matrix * matrix
real * vector
real * row_vector
real * matrix
No matches for:
real + ill-formed
Available argument signatures for operator+:
int + int
real + real
vector + vector
row_vector + row_vector
matrix + matrix
vector + real
row_vector + real
matrix + real
real + vector
real + row_vector
real + matrix
+int
+real
+vector
+row_vector
+matrix
Expression is ill formed.
error in 'modele28054257a16_a9d23411185fa271b60f20be43062e80' at line 16, column 23
-------------------------------------------------
14: transformed parameters{
15: real mu[n];
16: mu = alpha + beta*x;
^
17: }
-------------------------------------------------
Error in stanc(file = file, model_code = model_code, model_name = model_name, :
failed to parse Stan model 'a9d23411185fa271b60f20be43062e80' due to the above error.

The error comes from the transformed parameters block at the line
mu = alpha + beta*x;
The error is saying you can't multiply a real scalar by a real vector (the error of real * real[ ]). You can solve this by looping over the values of mu
transformed parameters {
real mu[n];
for(i in 1:n) {
mu[i] = alpha + beta * x[i];
}
}
which resolves the issue as now you have a real scalar times a real scalar.

Related

State-space models with latent variables in R

I tried to estimate State-space models with latent variables in r, but I failed.
I tried to do it in rstan package.
Does someone know how to do it better?
Let's say we have two observable variables: gdp and inflation.
We also know there are three unobservable variables: potential grow, potential gdp, output gap.
We want to estimate unobservable variables and two coefficient (a1 and a2).
Our model:
State Equations:
grow[t] = grow[t-1] + e
potential[t] = potential[t-1] + grow[t] + e
gap[t] = a1*gap[t-1] + e
Measurement Equations:
gdp[t] = potential[t] + gap[t]
inflation[t] = inflation[t-1] + a2*gap[t] + e
Here I generated data:
a1 <- 0.7
a2 <- 0.3
grow <- c()
potential <- c()
gap <- c()
gdp <- c()
inflation <- c()
grow[1] <- 2
potential[1] <- 10
gap[1] <- 0
gdp[1] <- potential[1] + gap[1]/100
inflation[1] <- 2
for (i in 2:100) {
grow[i] <- grow[i-1] + rnorm(1, 0, 0.1)
potential[i] <- potential[i-1] + grow[i]/100 + rnorm(1, 0, 0.1)
gap[i] <- a1*gap[i-1] + rnorm(1,0,0.1)
gdp[i] <- potential[i] + gap[i]/100
inflation[i] <- inflation[i-1] + a2*gap[i] + rnorm(1,0,0.1)
}
And here is my rstan code:
data {
int T; // number of obs
int P; //number of variables
matrix[T,P] Y; //dataset of generated series
}
parameters {
#Coefficients
vector[1] alfa1; //ar gap
vector[1] alfa2; //phillips curve
#State Variables (unobserved economic variables)
vector[T] gap; // output gap
vector[T] potential; // potential output
vector[T] grow; // growth of potential output
#Innovations
real<lower = 0> sigma_pot; // The scale of innovations to potential output
real<lower = 0> sigma_grow; // The scale of innovations to growth in potential output
real<lower = 0> sigma_gap; // The scale of innovations to output gap
real<lower = 0> sigma_inf; // The scale of innovations to phillips curve
}
model {
// priors
//Innovations
sigma_pot ~ cauchy(0.2,3);
sigma_grow ~ cauchy(0.3,3);
sigma_gap ~ cauchy(0.9,5);
sigma_inf ~ cauchy(2,5);
//coefficients
alfa1 ~ normal(0,1);
alfa2 ~ normal(0,1);
//Initialize State Equations
potential[1] ~ normal(0,1);
grow[1] ~ normal(0,1);
gap[1] ~ normal(0,1);
// State Equations
for(t in 2:T) {
grow[t] ~ normal(grow[t-1], sigma_grow);
potential[t] ~ normal(potential[t-1] + grow[t], sigma_pot);
gap[t] ~ normal( alfa1*gap[t-1], sigma_gap);
}
// Measurement Equations
for(t in 1:T) {
Y[t,1] = potential[t] + gap[t];
Y[t,2] ~ normal(Y[t-1,2] + alfa1*gap[t],sigma_inf);
}
}
Here I tried model
mvf_model <- stan(file = "newstan.stan" ,
data = list(T = nrow(data),
P = ncol(data),
Y = data),
chains = 4)
And here is the error I've got
Cannot assign to variable outside of declaration block; left-hand-side variable origin=data
Illegal statement beginning with non-void expression parsed as
Y[[t, 1]]
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 'model16a4a72378d_newstan' at line 27, column 3
-------------------------------------------------
25: transformed parameters {
26: for(t in 1:T) {
27: Y[t,1] = potential[t] + gap[t];
^
28: }
-------------------------------------------------
PARSER EXPECTED: "}"
Error in stanc(file = file, model_code = model_code, model_name = model_name, :
failed to parse Stan model 'newstan' due to the above error.

Stan syntax to create vector of products from parameters without sampling the product

I have a latent variable model in which I produce a product term. The product term is the product of two latent variables who's scores are sampled. Currently, my model is sampling the product term. This has drastically increased the number of parameters in my model.
My original model was in non matrix formulation:
vector [N] mueta;
matrix [N ,2] xi ;
mueta = b1[1] +
b1[2]*xi[,1] +
b1[3]*xi[,2] +
b1[4]*(xi[,2].*xi[,1]) ;
I changed it to a matrix formulation wherexi[,1] is an N length vector of 1s (intercept), xi[,2:3] are factor scores, and xi[,4] is an interaction effect.
vector [N] mueta;
xi[,1] = rep_vector(1, N);
xi[,2:3] = zi * diag_pre_multiply(sigmaxi,L1)' ;
xi[,4] = (xi[,2].*xi[,3]);
mueta = xi * b1 ;
The first model does not sample the product of the xi matrix, the second formulation does. Is there a way for me to specify this in Stan so that xi[,4] is not sampled, and is just a generated value from the product of the sampled scores of the 2 factors.
I have to formulate this as an answer because I can't format code in a comment. I'd suggest declaring xi one size bigger and calculating this as
vector[N] mueta;
xi[ , 1] = rep_vector(1, N);
xi[ , 2:3] = zi * diag_pre_multiply(sigmaxi, L1)' ;
xi[ , 4] = xi[ , 2] .* xi[ , 3];
mueta = xi * b1
If xi[ , 2] and xi[ , 3] are data, then you can also precompute their elementwise product. So this can be:
transformed data {
vector[N] intercept = rep_vector(1, N);
vector[N] xi2_3 = xi[ , 2] .* xi[ , 3];
...
vector[N] mueta
= append_row(intercept,
append_row(zi * diag_pre_multiply(sigmaxi, L1)',
xi2_3))
* b1;
It'd be even better to reorganize the predictors so that you have append_row(intercept, xi2_3) defined as a transformed data variable.
It's probably possible to go further and just directly define the elements of mueta (mu_eta?) without first construting a matrix.
It looks like I solved my own issue. I wanted to post this answer for others who may have a similar problem.
vector [N] mueta;
xi[,1] = rep_vector(1, N);
xi[,2:3] = zi * diag_pre_multiply(sigmaxi,L1)' ;
mueta = (append_col(xi,(xi[,2].*xi[,3])) * b1) ;

Writing a custom Probit function in Stan

I am trying to code a custom Probit function in Stan to improve my understanding of the Stan language and likelihoods. So far I've written the logarithm of the normal pdf but am receiving an error message that I've found to be unintelligible when I am trying to write the likelihood. What am I doing wrong?
Stan model
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);
}
}
Error
PARSER EXPECTED:
Error in stanc(model_code = paste(program, collapse = "\n"), model_name = model_cppname, :
failed to parse Stan model 'Probit_lpdf' due to the above error.
R code to simulate data
## 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 )
The full error message is
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: }
-------------------------------------------------
which is telling you that the normal_lpdf function excepts three inputs and a vertical bar separating the first from the second.
It is also not a good idea to give your function the same name as a function that is already in the Stan language, such as normal_lpdf.
But the functions you have written do not implement the log-likelihood of a probit model anyway. First, the standard deviation of the errors is not identified by the data, so you do not need sigma. Then, the correct expressions would be something like
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;
although that is just a slow way of doing
target += bernoulli_lpmf(y | Phi(mu));

meaning of brm regression parameters

I am using the brms package to build a multilevel model with a gaussian process on the predictor, x. The model looks like this: make_stancode(y ~ gp(x, cov = "exp_quad", by= groups) + (1| groups), data = dat) so a gp on the x predictor and a multilevel group variable. In my case I have 5 groups. I've been looking at the code for that (below) and I'm trying to figure out the meanings and dimensions of some of the parameters.
I see that M_1 is the number of groups
My questions are:
What is the meaning of N_1, is it the same as the number of observations , N? It is used here: vector[N_1] z_1[M_1]; // unscaled group-level effects
For Kgp_1 and Mgp_1 ( int Kgp_1; and int Mgp_1;), if I have 5 groups are both Kgp_1 and Mgp_1 equal to 5? If so, why are two variables used?
// generated with brms 1.10.0
functions {
/* compute a latent Gaussian process
* Args:
* x: array of continuous predictor values
* sdgp: marginal SD parameter
* lscale: length-scale parameter
* zgp: vector of independent standard normal variables
* Returns:
* a vector to be added to the linear predictor
*/
vector gp(vector[] x, real sdgp, real lscale, vector zgp) {
matrix[size(x), size(x)] cov;
cov = cov_exp_quad(x, sdgp, lscale);
for (n in 1:size(x)) {
// deal with numerical non-positive-definiteness
cov[n, n] = cov[n, n] + 1e-12;
}
return cholesky_decompose(cov) * zgp;
}
}
data {
int<lower=1> N; // total number of observations
vector[N] Y; // response variable
int<lower=1> Kgp_1;
int<lower=1> Mgp_1;
vector[Mgp_1] Xgp_1[N];
int<lower=1> Igp_1[Kgp_1];
int<lower=1> Jgp_1_1[Igp_1[1]];
int<lower=1> Jgp_1_2[Igp_1[2]];
int<lower=1> Jgp_1_3[Igp_1[3]];
int<lower=1> Jgp_1_4[Igp_1[4]];
int<lower=1> Jgp_1_5[Igp_1[5]];
// data for group-level effects of ID 1
int<lower=1> J_1[N];
int<lower=1> N_1;
int<lower=1> M_1;
vector[N] Z_1_1;
int prior_only; // should the likelihood be ignored?
}
transformed data {
}
parameters {
real temp_Intercept; // temporary intercept
// GP hyperparameters
vector<lower=0>[Kgp_1] sdgp_1;
vector<lower=0>[Kgp_1] lscale_1;
vector[N] zgp_1;
real<lower=0> sigma; // residual SD
vector<lower=0>[M_1] sd_1; // group-level standard deviations
vector[N_1] z_1[M_1]; // unscaled group-level effects
}
transformed parameters {
// group-level effects
vector[N_1] r_1_1 = sd_1[1] * (z_1[1]);
}
model {
vector[N] mu = rep_vector(0, N) + temp_Intercept;
mu[Jgp_1_1] = mu[Jgp_1_1] + gp(Xgp_1[Jgp_1_1], sdgp_1[1], lscale_1[1], zgp_1[Jgp_1_1]);
mu[Jgp_1_2] = mu[Jgp_1_2] + gp(Xgp_1[Jgp_1_2], sdgp_1[2], lscale_1[2], zgp_1[Jgp_1_2]);
mu[Jgp_1_3] = mu[Jgp_1_3] + gp(Xgp_1[Jgp_1_3], sdgp_1[3], lscale_1[3], zgp_1[Jgp_1_3]);
mu[Jgp_1_4] = mu[Jgp_1_4] + gp(Xgp_1[Jgp_1_4], sdgp_1[4], lscale_1[4], zgp_1[Jgp_1_4]);
mu[Jgp_1_5] = mu[Jgp_1_5] + gp(Xgp_1[Jgp_1_5], sdgp_1[5], lscale_1[5], zgp_1[Jgp_1_5]);
for (n in 1:N) {
mu[n] = mu[n] + (r_1_1[J_1[n]]) * Z_1_1[n];
}
// priors including all constants
target += student_t_lpdf(sdgp_1 | 3, 0, 10)
- 1 * student_t_lccdf(0 | 3, 0, 10);
target += normal_lpdf(lscale_1 | 0, 0.5)
- 1 * normal_lccdf(0 | 0, 0.5);
target += normal_lpdf(zgp_1 | 0, 1);
target += student_t_lpdf(sigma | 3, 0, 10)
- 1 * student_t_lccdf(0 | 3, 0, 10);
target += student_t_lpdf(sd_1 | 3, 0, 10)
- 1 * student_t_lccdf(0 | 3, 0, 10);
target += normal_lpdf(z_1[1] | 0, 1);
// likelihood including all constants
if (!prior_only) {
target += normal_lpdf(Y | mu, sigma);
}
}
generated quantities {
// actual population-level intercept
real b_Intercept = temp_Intercept;
}
If you use make_standata(...) on the same formula, you can see the data that would be passed onto Stan. From here, you can piece together what some of the variables do. If I use the lme4::sleepstudy dataset as a proxy for your data, I get:
library(brms)
dat <- lme4::sleepstudy
dat$groups <- dat$Subject
dat$y <- dat$Reaction
dat$x <- dat$Days
s_data <- make_standata(
y ~ gp(x, cov = "exp_quad", by= groups) + (1| groups), data = dat)
s_data$N_1
#> 18
For N_1, I get 18 which is the number of levels in groups in this dataset.
For Kgp_1 and Mgp_1 ( int Kgp_1; and int Mgp_1;), if I have 5 groups are both Kgp_1 and Mgp_1 equal to 5? If so, why are two variables used?
s_data$Mgp_1
#> 1
s_data$Kgp_1
#> 18
It looks like Kgp_1 is again the number of groups. I am not sure what Mgp_1 does besides set the length of the vector vector[Mgp_1] Xgp_1[N];

Stan error: require unconstrained variable declaration. found simplex

In Stan, I get the following error:
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
require unconstrained variable declaration. found simplex.
ERROR at line 48
46: for (j in 1:records) {
47: real phenology_predictor;
48: simplex[7] pi;
^
I don't quite understand what is the problem. When I used real pi[7] instead of simplex[7] pi, I got different error:
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
no matches for function name="categorical_log"
arg 0 type=int
arg 1 type=real[1]
available function signatures for categorical_log:
0. categorical_log(int, vector) : real
1. categorical_log(int[1], vector) : real
unknown distribution=categorical
ERROR at line 63
62:
63: Y[j] ~ categorical(pi);
^
64:
which I don't understand either... My whole code:
data {
int sites;
int records;
int Y[records];
vector[records] yday;
int site[records];
}
transformed data {
int M[sites];
}
parameters {
real<lower=0,upper=1> psi;
real<lower=0,upper=1000> phi_phen_scale;
real phi_alpha;
real q_date;
real q_date2;
real q_site[sites];
}
model {
real p[records];
real q[records];
// priors
phi_phen_scale ~ normal(0, 10);
phi_alpha ~ normal(0, 10);
q_date ~ normal(0, 10);
q_date2 ~ normal(0, 10);
// vectorized
M ~ bernoulli(psi);
q_site ~ normal(0, 10);
for (j in 1:records) {
real phenology_predictor;
simplex[7] pi;
phenology_predictor <- q_date * yday[j] + q_date2 * yday[j]^2;
p[j] <- M[site[j]] * inv_logit(phi_alpha + phi_phen_scale * phenology_predictor);
q[j] <- inv_logit(q_site[site[j]] + phenology_predictor);
pi[1] <- 1-p[j] + p[j]*(1-q[j])^6;
pi[2] <- p[j]*q[j] ;
pi[3] <- p[j]*(1-q[j])*q[j];
pi[4] <- p[j]*(1-q[j])^2*q[j];
pi[5] <- p[j]*(1-q[j])^3*q[j];
pi[6] <- p[j]*(1-q[j])^4*q[j];
pi[7] <- p[j]*(1-q[j])^5*q[j];
Y[j] ~ categorical(pi);
}
}
Constrained local parameters, such as simplexes, cannot be declared inside the model block because they are not checked. So, you should just declare pi to be a plain vector of length 7, like vector[7] pi;. Nevertheless, pi needs to be on the simplex in order to be an admissible argument to the categorical function.
If it is the case that symbolically pi is non-negative and sums to 1, then it is a question of making sure that numerically they are sufficiently close to non-negative and sum to something that is sufficiently close to 1. I'm not sure what the numerical tolerance is for a simplex in Stan but there is some wiggle room. If numerical error is the problem then doing pi <- pi / sum(pi); before passing pi to the categorical function may help.

Resources