I'm trying to implement a logistic regression model with random effects and interactions. For some reason, when I remove an interaction between a parameter and a random effect parameter (Player and Shot.after.PC), the variance and random effect values decrease to 0.
glmer(GOAL~ (1|Player) + match_seconds_bin * Score.Difference + Home + Shot.after.PC + Blocked.or.goal.after.block,
family="binomial", control = glmerControl(optimizer="bobyqa",
optCtrl = list(maxfun=2e6)),
data=nu_shots)
Random effects:
Groups Name Variance Std.Dev.
Player (Intercept) 0 0
Yet, when I include the interaction, the variance appears to increase, which I feel doesn't make sense because I am adding an additional relationship between parameters to the model in an attempt for it to fit with a greater amount of data.
glmer(GOAL~ (1|Player:Shot.after.PC) + match_seconds_bin * Score.Difference + Home + Shot.after.PC + Blocked.or.goal.after.block,
family="binomial", control = glmerControl(optimizer="bobyqa",
optCtrl = list(maxfun=2e6)),
data=nu_shots)
Random effects:
Groups Name Variance Std.Dev.
Player:Shot.after.PC (Intercept) 0.4448 0.667
Most of my confusion derives from how when I implement the data with RStan, the random effect values do not match the ones presented in the glmer model at all. The random effect values are not close to zero or the ones outputted from the model specifying an interaction between Player and Shot.after.PC (however, the relationship between the glmer effect random effect values and corresponding RStan values is strongly linear). I am not sure why there is a discrepancy between the two models.
data {
// Define variables in data
// Number of observations (an integer; the number of shots)
int<lower=0> N;
// Number of parameters (an integer; the number of predictors, i.e. Score_Difference, Home, etc.)
// NOT including Shot.after.PC
int<lower=0> p;
// Number of groups (an integer; the number of unique players)
int<lower=0> M;
// Outcome
int<lower=0, upper=1> GOAL[N]; // defining the binary goal outcome variable
// Predictors
row_vector[p] x[N]; // throwing all predictors into a vector (except spc)
row_vector[1] spc[N]; // spc by itself to use in estimating random effect
// Mapping observations (shots) to groups (players)
int g[N];
}
parameters {
// Define parameters to estimate
real alpha;
vector[p] beta1; // fixed effects, excluding intercept
vector[1] beta2; // specifically for spc
matrix[2,M] psi; // random effects, two for each player
vector<lower=0, upper=10>[2] sigma; // error scale (captures the noise)
}
model {
// Prior part of Bayesian inference (flat if unspecified)
alpha ~ normal(0,100);
psi[1] ~ normal(0,sigma[1]);
psi[2] ~ normal(0,sigma[2]);
beta1 ~ normal(0,100);
beta2 ~ normal(0,100);
// Likelihood part of Bayesian inference
for (n in 1:N) {
GOAL[n] ~ bernoulli_logit(alpha +
psi[1,g[n]]*(1-spc[n]) + psi[2,g[n]]*spc[n] +
x[n]*beta1 + spc[n]*beta2);
}
}
new_dat <- list(N=nrow(neu_shots_only), M = length(unique(neu_shots_only$Player)),
p=17, GOAL=neu_shots_only$GOAL, x=cbind(neu_shots_only$'match_seconds_bin_(0,600]', neu_shots_only$'match_seconds_bin_(600,1.2e+03]', neu_shots_only$'match_seconds_bin_(1.2e+03,1.8e+03]', neu_shots_only$'match_seconds_bin_(1.8e+03,2.4e+03]', neu_shots_only$'match_seconds_bin_(2.4e+03,3e+03]', neu_shots_only$'match_seconds_bin_(3e+03,3.6e+03]', neu_shots_only$'match_seconds_bin_(3.6e+03,4.36e+03]', neu_shots_only$Score.Difference, neu_shots_only$Home, neu_shots_only$Blocked.or.goal.after.block, neu_shots_only$'match_seconds_bin_(0,600]'*neu_shots_only$Score.Difference, neu_shots_only$'match_seconds_bin_(600,1.2e+03]'*neu_shots_only$Score.Difference, neu_shots_only$'match_seconds_bin_(1.2e+03,1.8e+03]'*neu_shots_only$Score.Difference, neu_shots_only$'match_seconds_bin_(1.8e+03,2.4e+03]'*neu_shots_only$Score.Difference, neu_shots_only$'match_seconds_bin_(2.4e+03,3e+03]'*neu_shots_only$Score.Difference, neu_shots_only$'match_seconds_bin_(3e+03,3.6e+03]'*neu_shots_only$Score.Difference, neu_shots_only$"match_seconds_bin_(3.6e+03,4.36e+03]"*neu_shots_only$Score.Difference),
spc=cbind(neu_shots_only$Shot.after.PC),
g=as.integer(as.factor(neu_shots_only$Player)))
I appreciate your assistance in this matter!
nAGQ
argument ofglmer()
to a higher number, e.g., 11. You can also try using the GLMMadaptive package: drizopoulos.github.io/GLMMadaptive $\endgroup$