Dear Stan (rstan) user,
I am trying to estimate a stereotype logit model using rstan, but run into problems. I would appreciate it if anyone could point me to the right direction. I would be more than happy to share the codes once I work it out. Following are two documents that discuss this model. Basically it is a reduced rank multinomial logit model, with the slopes varying across equations by a set of scalar factors that are constrained between 0 and 1 (corner constraints) to retain ordinality and obtain identification.
http://psfaculty.ucdavis.edu/bsjjones/stereotypelogit.pdfhttp://deepblue.lib.umich.edu/bitstream/handle/2027.42/64310/3693_ftp.pdf?sequence=1(see page 3149 for how some of the key parameters are given priors using Dirichlet distribution)
Jun Xu, PhD
Associate Professor
Department of Sociology
Ball State University
Here are some excerpts of the error/warning messages that I got from running the following codes:Informational Message: The current Metropolis proposal is about to be rejected because of the following issue:
Invalid value of phi: validate transformed params(N4stan5agrad3varE): phi[4] is -0.211538:0, but must be greater than or equal to 0
If this warning occurs sporadically, such as for highly constrained variable types like covariance matrices, then the sampler is fine,
but if this warning occurs often then your model may be either severely ill-conditioned or misspecified.
Rejecting proposed initial value with zero density.
Informational Message: The current Metropolis proposal is about to be rejected because of the following issue:
Invalid value of phi: validate transformed params(N4stan5agrad3varE)error occurred during calling the sampler; sampling not done
> print(stanFit)
Stan model 'modelString' does not contain samples.
Below are my r codes (see the attached files for the r script and data)Codes
###
rm(list=ls(all=TRUE))
require(rstan)
require(MASS)
require(VGAM)
require(foreign)
mydta <- read.dta("gssCum7212Teach.dta", convert.factor=F)
usevar <- c("health", "age", "educ", "impinc", "female", "year")
mydta <- mydta[complete.cases(mydta[usevar]),]
usedta <- subset(mydta, select=c(health, age, educ, impinc, female))
# set seed to get the same random sample each time
set.seed(47306)
usedta <- usedta[sample(1:nrow(usedta), size = 1000, replace=T),]
# here is the DATA used for estimation
save(usedta, file = "stanData.RData")
myologit <- polr(as.ordered(usedta$health) ~ usedta$age + usedta$educ + usedta$impinc +usedta$female,
method = c("logistic"))
summary(myologit)
# stereotype logit model
stereotypeLogitR1 <- rrvglm(as.factor(health) ~ age + educ + impinc + female,
multinomial,
usedta)
summary(stereotypeLogitR1)
# slotNames(stereotypeLogitR1)
#------------------------------------------------------------------------------
# THE MODEL.
modelString = "
data {
int<lower=2> M; // number of response levels
int<lower=1> N; // number of observations
int<lower=1> K; // number of predictors
int<lower=1, upper=M> y[N]; // y variables
row_vector[K] x[N]; // x vectors
vector<lower=0>[M-1] alpha;
}
parameters {
vector[K] b;
vector[M-1] theta;
vector[M-1] gamma;
}
transformed parameters{
vector<lower=0, upper=1>[M] phi;
phi[1] <- 0;
phi[2] <- gamma[1];
phi[3] <- gamma[1] + gamma[2];
phi[4] <- gamma[1] + gamma[2] + gamma[3];
}
model {
vector[M] prob;
vector[M] emu;
// specify priors
for (m in 1:M-1)
gamma ~ dirichlet(alpha);
for (k in 1:K)
b[k] ~ normal(0, 100);
for (m in 1:M-1)
theta[m] ~ normal(0, 100);
for (n in 1:N) {
emu[1] <- exp(phi[1]*x[n]*b);
for (m in 2:M)
emu[m] <- exp(theta[m] + phi[m]*x[n]*b);
for (m in 1:M)
prob[m] <- emu[m]/sum(emu);
y[n] ~ categorical(prob);
}
}
# generated quantitaties {
#
# }
" # close quote for modelstring
# translate model to C++ and compile to DSO:
stanDSO <- stan_model(model_code=modelString)
# prepare data
dataMat = as.matrix(usedta)
# Rename for use by generic processing later:
nData = NROW(dataMat)
x = dataMat[,-1]
predictorNames = colnames(dataMat)[-1]
nPredictors = NCOL(x)
y = as.matrix(dataMat[,1])
predictedName = colnames(dataMat)[1]
nYlevels = max(y)
distAlpha = rep(1,3)
dataList = list(
x = x ,
y = as.vector( y ) , # BUGS does not treat 1-column mat as vector
K = nPredictors ,
N = nData ,
M = nYlevels,
alpha = distAlpha
)
# get initial values for b
bInit = - coefficients(stereotypeLogitR1)[-c(1:3)]
thetaInit = - coefficients(stereotypeLogitR1)[c(1:3)]
initsList = list(
b = bInit,
theta = thetaInit)
# specify parameter values for MCMC sampling
parameters = c("b", "theta", "gamma") # The parameter(s) to be monitored.
adaptSteps = 1000 # Number of steps to "tune" the samplers.
burnInSteps = 1000 # Number of steps to "burn-in" the samplers.
nChains = 3
seedNum = 60115
# Number of chains to run.
initsChains <- list()
# initials for three chains
for (i in 1:nChains) {
initsChains[[i]] <- initsList
}
#}
numSavedSteps=10000 # Total number of steps in chains to save.
thinSteps=1 # Number of steps to "thin" (1=keep every step).
nPerChain = ceiling( ( numSavedSteps * thinSteps ) / nChains ) # Steps per chain.
# Sampling MCMC chain
cat( "Sampling final MCMC chain...\n" )
# monitor time
time.used <- proc.time()
stanFit <- sampling(object=stanDSO,
data=dataList,
seed = seedNum,
pars=parameters,
chains=nChains,
thin=thinSteps,
# init=initsChains
iter=nPerChain,
warmup=burnInSteps )
print(stanFit)
###