Сравните мультином с регрессией stan multi lo git - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь понять / воспроизвести результаты, используя stan. Тем не менее, я застрял где-то. Я использую неправильную модель стан?

library(nnet);library(rstan);library(dplyr);library(tidyr)

#set up data 
n <- 100
set.seed(1)
dat <- data.frame(DV=factor(sample(letters[1:5], n, replace=T)),
       x1 = rnorm(n, mean=4.5, sd=1.3),
       x2 = sample(c(1:5), prob=c(0.035, 0.167, 0.083, 0.415, 0.298)),
       x3 = sample(c(0,1), prob=c(.51, .49)),
       x4 = round(rnorm(n, mean=48, sd=15),0))

library(nnet)
f <- as.formula("DV ~ x1 + x2 + x3 + x4")
out <- multinom(f, data=dat)
#summary(out)

#Store output to compare later on:
out.multinom <- tidyr::gather(as.data.frame(coef(out)), values) %>%  
  mutate(option=rep(row.names(coef(out)), 5)) %>%
  mutate(coef= paste0(option, ":", values))%>%
  dplyr::select(-option, -values)%>%
  rename(multinom = value)

Пока все хорошо. Теперь сравниваем оценки с оценками stan:

Модель копируется и вставляется из здесь :

stan_model <- "
 data {
 int K;
 int N;
 int D;
 int y[N];
 matrix[N, D] x;
 }
 parameters {
 matrix[D, K] beta;
 }
 model {
 matrix[N, K] x_beta = x * beta;

 to_vector(beta) ~ normal(0, 2);

 for (n in 1:N)
 y[n] ~ categorical_logit(x_beta[n]);
 }

"

rstan_options(auto_write = TRUE)
options(mc.cores = 4)

M <- model.matrix(f, dat)

#data for stan
datlist <- list(N=nrow(M),                     #nr of obs
                K=length(unique(dat[,1])),     #possible outcomes
                D=ncol(M),                     #dimension of predictor matrix
                x=M,                           #predictor matrix
                y=as.numeric(dat[,1]))

 #estimate model
 b.out <- stan(model_code=stan_model, 
          data=datlist,
          iter = 1000,
          chains = 4,
          seed = 12591,
          control = list(max_treedepth = 11))


 res <- summary(b.out, par="beta", probs=.5)$summary %>% as.data.frame

 #store
 out.stan <- data.frame(beta=rep(colnames(M), each=5), 
                   value.stan = res[,1]) %>%
  mutate(option=rep(levels(dat$DV), length.out=25))%>%
  mutate(coef= paste0(option, ":", beta))%>%
  dplyr::select(-option, -beta)

#compare
merge(out.multinom, out.stan, by="coef", all.y=T)


            coef     multinom   value.stan
1  a:(Intercept)           NA -0.532803345
2           a:x1           NA  0.017020378
3           a:x2           NA  0.227622393
4           a:x3           NA -0.001617129
5           a:x4           NA  0.011291841
6  b:(Intercept) -0.308050243 -0.794106266
7           b:x1  0.314860536  0.353267471
8           b:x2 -0.305248243 -0.094612371
9           b:x3 -0.181849471 -0.203225779
10          b:x4 -0.002589588  0.007308861
11 c:(Intercept)  1.241939293  0.391090113
12          c:x1 -0.265908390 -0.230931524
13          c:x2 -0.121426457  0.113370970
14          c:x3 -0.486321891 -0.496869965
15          c:x4  0.004659122  0.019329331
16 d:(Intercept)  1.655236959  0.767339620
17          d:x1 -0.332715090 -0.291936815
18          d:x2 -0.159596712  0.072145756
19          d:x3  0.132897149  0.145568093
20          d:x4  0.002003899  0.017336138
21 e:(Intercept)  0.970658209  0.253888841
22          e:x1 -0.057914885 -0.017299638
23          e:x2 -0.501888386 -0.306445142
24          e:x3  0.515320410  0.517075558
25          e:x4  0.009115124  0.023669295

Что-то не так, как должно быть оценки отличаются. Я почти уверен, что что-то пропустил, просто скопировав и вставив код stan. Что это? (Я не говорю о том факте, что multinom использует a в качестве справочной категории).

Проблема не должна составлять l ie с размером набора данных, так как я использую больше данных (этот пример подготовлен для stackoverflow).

Спасибо за любую помощь.

1 Ответ

1 голос
/ 08 марта 2020

Судя по выводу, похоже, что вызываемая функция multinom использует коэффициенты K-1 для того, чтобы сделать модель идентифицируемой. При этом коэффициенты a неявно равны нулю. Если вы вычтете коэффициенты a из других коэффициентов, от b до e, вы получите примерно такой же результат. Результаты не будут точно такими же, потому что Стэн дает вам задние средства здесь, а multinom, вероятно, дает вам что-то еще. Об обсуждении использования K против K-1 кодирования для многочленов в Руководстве пользователя Stan только в том же разделе, который вы связали под заголовком "идентификация".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...