Stan error casting parameter to int - stan

I'm trying to do a switchpoint analysis with STAN. I've got a data vector y that has two different sequences of gaussian random variables. The goal is to find the posterior distribution of when a shift might have occured. I'm using RStan to run it, but the error lies within STAN.
This is the STAN code;
data {
int N;
vector[N] y;
}
parameters {
real mu1;
real sigma1;
real mu2;
real sigma2;
real<lower=0, upper=N> shift;
}
model {
int i_shift <- round(shift);
for(n1 in 1:i_shift)
y[n1] ~ normal(mu1, sigma1);
for(n2 in i_shift:N)
y[n2] ~ normal(mu2, sigma2);
}
The parser (which comes with Rstudio) gives the following error;
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
ERROR at line 13
11: }
12: model {
13: int i_shift <- round(shift);
^
14: for(n1 in 1:i_shift)
PARSER EXPECTED: ";"
Error in stanc(model_code = paste(program, collapse = "\n"), model_name = model_cppname, :
failed to parse Stan model due to the above error.
Why can't it handle the variable assingment that does the casting? Does STAN require a different pattern for this sort of analysis. I've tried to create an integer variable in the parameters but STAN doesn't appear to have support for random integer variables, only continous ones.

The root cause is that Stan doesn't allow assignment of real values to integers. In retrospect, we probably wouldn't have included round() at all as it introduces discontinuities, and thus defeats differentiability, whichis the basis of our HMC and optimization and approximate inference algorithms.

There is currently no compound declaration and definition within the Stan program (as of v2.9.0).
Fixing the syntax issue won't fix the statistical model, however. I believe there's a continuous change point model in the manual that does what you're attempting, so please check there for a solution.

Related

"non-finite value supplied by optim" when using fitCopula

when I try to do an AIC test on different copulas, R keeps giving me this error message.
Error in optim(start, logL, lower = lower, upper = upper, method = optim.method, :
non-finite value supplied by optim
but in my code, I didn't use the function optim and some give the other warnings.
Warning in fitCopula.ml(copula, u = data, method = method, start = start, : possible convergence problem: optim() gave code=52
The error message gives the NA result while the warning message gives the number that seems on the right track.
here are my codes.
AIC.result <- function(EC,copulafunction){
AIC<- matrix(nrow=length(colnames(EC)),ncol=length(colnames(EC)),byrow=T)
for (i in 1:length(colnames(EC))) {
for (j in 1:length(colnames(EC))) {
if(i==j){
AIC[i,j] <-1
}else{
u <- pobs(as.matrix(EC[,i]))
v <- pobs(as.matrix(EC[,j]))
fit<- fitCopula(copulafunction, cbind(u,v),method="ml")
AIC[i,j] <-AIC(fit)
}
}
}
mean((AIC-length(colnames(EC)))/2)
}
EC is the returns of different countries, and copulafunction is different type of copulas. And the Clayton copula and rotated Clayton copula give the error message while the rest gives the warning messages. The weirdest thing is in my case, EC contains 7 countries and it worked smoothly. When I applied to the DC which has 6 countries, the errors and warnings came. Is anyone know why?
First of all, if you want to only find the AIC for your model, then I think the fitCopula function returns it to you by default. If not then, the easy and direct way is to use the BICopEst function from the R package VineCopula. It returns the AIC and BIC. The error message is may due to fitting a wrong copula to your data, which sometimes leads the function to not converge, hence the error or warning. So, you should try another copula family. The best way to select the most appropriate copula for your data is to apply the BICselect() function in the VineCopula package. It will select the best bivariate copula among a wide range of a list based on AIC. Hence, it works for your case. Also, you can set another selection criteria supplied in the function.

Evaluating log-likelihood of unseen data in rstan

I understand I can calculate the log likelihood of each sample during sampling, e.g.
...
model {
for (i in 1:N) {
(y[i] - 1) ~ bernoulli(p[i, 2]);
}
}
generated quantities {
vector[N] log_lik;
for (i in 1:N){
log_lik[i] = bernoulli_lpmf((y[i] - 1) | p[i, 2]);
}
}
After fitting, I can then extract log likelihood using the loo package:
log_lik_m <- extract_log_lik(stan_fit)
But I want to evaluate log likelihood of unseen data. This is possible in brms:
ll <- log_lik(fit_star, newdata = new_df)
But I would like to do this with rstan, since I can't easily define my model in brms (I am assuming).
For reference, I am trying to use Estimated LFO-CV to evaluate and compare my time-series model.
(e.g. https://github.com/paul-buerkner/LFO-CV-paper/blob/master/sim_functions.R#L186)
(https://mc-stan.org/loo/articles/loo2-lfo.html)
Thanks to the link from #dipetkov, I solved this myself. I didn't use the exact methods in the link, but came up with an alternative. You can call stan functions from R to get it to compute log likelihood for your model, even with unseen data (and its very fast!).
First, I put everything in my transformed parameters block into a function in stan's functions block. Then, I created a second function that wraps the first function, and evaluates the log likelihood for given observations and provided parameter estimates (I then removed my generated_quantities block). rstan has a function expose_stan_functions which adds all functions in the stan functions block to the R environment.
You can then call the log likelihood function you made to evaluate your model with any observations (previously seen or unseen), along with a set of parameter estimates.

Runtime error in JAGS

I'm attempting to do this in JAGS:
z[l] ~ dbeta(0.5,0.5)
y[i,l] ~ z[l]*dnorm(0,10000) + inprod(1-z[l],dnegbin(exp(eta_star[i,l]),alpha[l]))
(dnorm(0,10000) models a Dirac delta in 0: see here if you are interested in the model).
But I get:
RUNTIME ERROR:
Incorrect number of arguments in function dnegbin
But if I do this:
y[i,l] ~ dnegbin(exp(eta_star[i,l]),alpha[l])
It runs just fine. I wonder that I cannot multiply a value for a distribution, so I imagine that something like this could work:
z[l] ~ dbeta(0.5,0.5)
pointmass_0[l] ~ dnorm(0,10000)
y[i,l] ~ dnegbin(exp(eta_star[i,l]),alpha[l])
y_star[i,l] = z[l]*pointmass_0[l]+inprod(1-z[l],y[i,l])
If I run that I get:
ystar[1,1] is a logical node and cannot be observed
You are looking to model a zero-inflated negative binomial model. You can do this in JAGS if you use the "ones trick", an pseudo-likelihood method that can be used when the distribution of your outcome variables is not one of the standard distributions in JAGS but you can still write down an expression for the likelihood.
The "ones trick" consists of creating pseudo-observations with the value 1. These are then modeled as Bernoulli random variables probability parameter Lik/C where Lik is the likelihood of your observations and C is a large constant to ensure that Lik/C << 1.
data {
C <- 10000
for (i in 1:N) {
one[i,1] <- 1
}
}
model {
for (i in 1:N) {
one[i,1] ~ dbern(lik[i,1]/C)
lik[i,1] <- (y[i,1]==0)*z[1] + (1 - z[1]) * lik.NB[i,1]
lik.NB[i,1] <- dnegbin(y[i,1], exp(eta_star[i,1]), alpha[1])
}
z[l] ~ dbeta(0.5,0.5)
}
Note that the name dnegbin is overloaded in JAGS. There is a distribution that has two parameters and a function that takes three arguments and returns the likelihood. We are using the latter.
I am thinking of adding zero-inflated versions of count distributions to JAGS, since the above construction is quote awkward for the user, whereas zero-inflated distributions are quite easy to implement internally in JAGS.
I too would like to know a better way to handle this situation.
One cheesy solution is to add a stochastic node
ystarstar[i,j] ~ dnorm(ystar[i,j],10000000)
(i.e. a Normal distribution with a very high precision, or a Dirac delta in your terminology) to the model.

R function for Likelihood

I'm trying to analyze repairable systems reliability using growth models.
I have already fitted a Crow-Amsaa model but I wonder if there is any package or any code for fitting a Generalized Renewal Process (Kijima Model I) or type II
in R and find it's parameters Beta, Lambda(or alpha) and q.
(or some other model for the mean cumulative function MCF)
The equation number 15 of this article gives an expression for the
Log-likelihood
I tried to create the function like this:
likelihood.G1=function(theta,x){
# x is a vector with the failure times, theta vector of parameters
a=theta[1] #Alpha
b=theta[2] #Beta
q=theta[3] #q
logl2=log(b/a) # First part of the equation
for (i in 1:length(x)){
logl2=logl2 +(b-1)*log(x[i]/(a*(1+q)^(i-1))) -(x[i]/(a*(1+q)^(i-1)))^b
}
return(-logl2) #Negavite of the log-likelihood
}
And then use some rutine for minimize the -Log(L)
theta=c(0.5,1.2,0.8) #Start parameters (lambda,beta,q)
nlm(likelihood.G1,theta, x=Data)
Or also
optim(theta,likelihood.G1,method="BFGS",x=Data)
However it seems to be some mistake, since the parameters it returns has no sense
Any ideas of what I'm doing wrong?
Thanks
Looking at equation (16) of the paper you reference and comparing it with your code it looks like you are missing one term in the for loop. It seems that each data point contributes to three terms of the log-likelihood but in your code (inside the loop) you only have two terms (not considering the updating term)
Specifically, your code does not include the 4th term in equation (16):
and neither it does the 7th term, and so on. This is at least one error in the code. An extra consideration would be that α and β are constrained to be greater than zero. I am not sure if the solver you are using is considering this constraint.

What about the results for ksvm?

I've got the following code:
breast.svr=ksvm(Diagnosis~.,data=breast.train,kernel="rbfdot",C=4)
pred.svr=predict(breast.svr,newdata=breast.test)
tabel <- table(breast.test[,1],pred.svr)/nrow(breast.test)
tabel[1,2] + tabel[2,1]
The result is:
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 4
Gaussian Radial Basis kernel function.
Hyperparameter : sigma = 0.149121426557224
Number of Support Vectors : 99
Objective Function Value : -143.4679
Training error : 0.028947
I know that I can extract a lot of information from this model on the following manner:
coef(breast.svr)
But I don't know what to do with it? How can I interpret this? How can I make from this a model like: f(x) = ...? More specific, how can I say which predictor variables that are important?
Kernel SVM is by it's very nature not very intepretable. Each kernel uses many predictor variables so its hard to say which predictor variable is important. If you care about predictability, try to use linear regression or other interpretable models.

Resources