Hi everyone,
I am trying to fit an admittedly very simple model, but cannot get it to work. I have used Stan in the past, but don’t have much experience with Bayesian modeling, so I would be very happy to be pointed to the relevant sections of the Stan documentation / other literature.
The model I’m trying to fit can be described as an extended logistic regression. For a standard logistic regression, my model block would look like this (being aware that the bernoulli_logit
function would probably be a better choice):
model {
for (n in 1:N)
y[n] ~ bernoulli(inv_logit(alpha + beta * x[n]));
}
This is fine (in fact, it works as expected, i.e. produces similar results to MLE when using uniform priors), but now I want to introduce two more parameters into my link function, \gamma_l and \gamma_r. In the context of a a (simple) logistic regression these allow for data points at the very ends of the sigmoid curve to be in the “wrong” category with a certain probability (see figure).
The corresponding link function looks like this:
g(\mu,\gamma_l,\gamma_r) = \log{(\frac{\gamma_r-\mu}{\gamma_l + \mu - 1})},
g(\mu,\gamma_l,\gamma_r)^{-1} = (1 - (\gamma_l + \gamma_r)) \frac{1}{1 + e^{-\mu}} + \gamma_r,
which yields the following model:
model {
for (n in 1:N)
y[n] ~ bernoulli((1 - (gamma_l + gamma_r)) * 1/(1 + exp(-(alpha + beta * x[n]))) + gamma_r);
}
However, this does not work. What happens is that I get a lot of Informational Message: The current Metropolis proposal is about to be rejected because of the following issue: Exception: bernoulli_lpmf: Probability parameter is x, but must be in the interval [0, 1]
warnings during fitting and when sampling finally finishes, the parameter estimates are way off (as compared to the same model using MLE).
- Why does this not work? I realize that this is a rather unspecific question, so again, I would be happy to be pointed to the relevant sections in the Stan documentation.
- What would be good priors for my two parameters here, considering that \gamma_l and \gamma_r should be constrained between [0,1]? (I could use
<upper=0, upper=1>
but the compiler says that it is not advised to do so…). For my data, I would expect them to be relatively close to 0.
My full model in pystan (with uniform priors) looks like this. I’m using the breast cancer dataset from sklearnhere for illustrative purposes, because it produces the same problems as my actual data.
import stan
import sklearn. datasets as datasets
model_code = """
data {
int<lower=0> N;
vector[N] x;
int<lower=0,upper=1> y[N];
}
parameters {
real alpha;
real beta;
real gamma_l;
real gamma_r;
}
model {
for (n in 1:N)
y[n] ~ bernoulli((1 - (gamma_l + gamma_r)) * 1/(1 + exp(-(alpha + beta * x[n]))) + gamma_r);
}
"""
X, y = datasets.load_breast_cancer(return_X_y=True)
stan_data = {"N": len(y),
"y": y,
"x": X[:,0]}
model = stan.build(model_code, data=stan_data, random_seed=1)
fit = model.sample(num_chains=4, num_samples=1000)
Any help would be appreciated!