Как получить средние предельные эффекты (AME) со стандартными ошибками полиномиальной логит-модели?

Я хочу получить средние предельные эффекты (AME) для модели полиномиального логита со стандартными ошибками. Для этого я пробовал разные методы, но они пока не привели к цели.

Лучшая попытка

Моя лучшая попытка состояла в том, чтобы получить AME вручную, используя mlogit который я покажу ниже.

library(mlogit)
ml.d <- mlogit.data(df1, choice="Y", shape="wide")  # shape data for `mlogit()`
ml.fit <- mlogit(Y ~ 1 | D + x1 + x2, reflevel="1", data=ml.d)  # fit the model

# coefficient names
c.names <- names(ml.fit$model)[- c(1, 5:6)]

# get marginal effects
ME.mnl <- sapply(c.names, function(x) 
  stats::effects(ml.fit, covariate=x, data=ml.d), 
  simplify=FALSE) 

# get AMEs
(AME.mnl <- t(sapply(ME.mnl, colMeans)))
#              1            2            3           4          5
# D  -0.03027080 -0.008806072 0.0015410569 0.017186531 0.02034928
# x1 -0.02913234 -0.015749598 0.0130577842 0.013240212 0.01858394
# x2 -0.02724650 -0.005482753 0.0008575982 0.005331181 0.02654047

Я знаю, что эти значения правильные. Однако я не смог получить правильные стандартные ошибки, просто выполнив стандартные отклонения столбцов:

# standard errors - WRONG!
(AME.mnl.se <- t(sapply(E.mnl, colSdColMeans)))

(Примечание: colSdColMeans() для колонок SD здесь.)

Соответственно, это также привело меня к неправильным t-значениям:

# t values - WRONG!
AME.mnl / AME.mnl.se
#             1          2          3         4         5
# D  -0.7110537 -0.1615635 0.04013228 0.4190057 0.8951484
# x1 -0.7170813 -0.2765212 0.33325968 0.3656893 0.8907836
# x2 -0.7084573 -0.1155825 0.02600653 0.1281190 0.8559794

Принимая во внимание, что я знаю правильные t-значения для этого случая:

# D  -9.26 -1.84  0.31 4.29 8.05   
# x1 -6.66 -2.48  1.60 1.50 3.22  
# x2 -2.95 -0.39  0.06 0.42 3.21 

Я узнал, что должен быть "дельта-метод", но я нашел только некоторый код для очень особого случая с взаимодействиями в Cross Validated.

Неудачные попытки

1.) Пакет margins кажется, не в состоянии справиться "mlogit" объекты:

library(margins)
summary(margins(ml.fit))

2.) Есть еще один пакет для млогитов, nnet,

library(nnet) 
ml.fit2 <- multinom(Y ~ D + x1 + x2, data=df1)
summary(ml.fit2)

но margins не может справиться с этим правильно либо:

> summary(margins(ml.fit2))
 factor     AME SE  z  p lower upper
      D -0.0303 NA NA NA    NA    NA
     x1 -0.0291 NA NA NA    NA    NA
     x2 -0.0272 NA NA NA    NA    NA

3.) Также существует пакет, в котором утверждается, что он рассчитывает "средние эффекты для моделей многочленной логистической регрессии",

library(DAMisc)
mnlChange2(ml.fit2, varnames="D", data=df1)

но я не смог получить из этого ни капли молока, так как функция ничего не дает (даже с примером функции).

Как теперь мы можем получить AME со стандартными ошибками / t-статистикой многочленной модели логита с R?

Данные

df1 <- structure(list(Y = c(3, 4, 1, 2, 3, 4, 1, 5, 2, 3, 4, 2, 1, 4, 
1, 5, 3, 3, 3, 5, 5, 4, 3, 5, 4, 2, 5, 4, 3, 2, 5, 3, 2, 5, 5, 
4, 5, 1, 2, 4, 3, 1, 2, 3, 1, 1, 3, 2, 4, 2, 2, 4, 1, 5, 3, 1, 
5, 2, 3, 4, 2, 4, 5, 2, 4, 1, 4, 2, 1, 5, 3, 2, 1, 4, 4, 1, 5, 
1, 1, 1, 4, 5, 5, 3, 2, 3, 3, 2, 4, 4, 5, 3, 5, 1, 2, 5, 5, 1, 
2, 3), D = c(12, 8, 6, 11, 5, 14, 0, 22, 15, 13, 18, 3, 5, 9, 
10, 28, 9, 16, 17, 14, 26, 18, 18, 23, 23, 12, 28, 14, 10, 15, 
26, 9, 2, 30, 18, 24, 27, 7, 6, 25, 13, 8, 4, 16, 1, 4, 5, 18, 
21, 1, 2, 19, 4, 2, 16, 17, 23, 15, 13, 21, 24, 14, 27, 6, 20, 
6, 19, 8, 7, 23, 11, 11, 1, 22, 21, 4, 27, 6, 2, 9, 18, 30, 26, 
22, 10, 1, 4, 7, 26, 15, 26, 18, 30, 1, 11, 29, 25, 3, 19, 15
), x1 = c(13, 12, 4, 3, 16, 16, 15, 13, 1, 15, 10, 16, 1, 17, 
7, 13, 12, 6, 8, 16, 16, 11, 7, 16, 5, 13, 12, 16, 17, 6, 16, 
9, 14, 16, 15, 5, 7, 2, 8, 2, 9, 9, 15, 13, 9, 4, 16, 2, 11, 
13, 11, 6, 4, 3, 7, 4, 12, 2, 16, 14, 3, 13, 10, 11, 10, 4, 11, 
16, 8, 12, 14, 9, 4, 16, 16, 12, 9, 10, 6, 1, 3, 8, 7, 7, 5, 
16, 17, 10, 4, 15, 10, 8, 3, 13, 9, 16, 12, 7, 4, 11), x2 = c(12, 
19, 18, 19, 15, 12, 15, 16, 15, 11, 12, 16, 17, 14, 12, 17, 17, 
16, 12, 20, 11, 11, 15, 14, 18, 10, 14, 13, 10, 14, 18, 18, 18, 
17, 18, 14, 16, 19, 18, 16, 18, 14, 17, 10, 16, 12, 16, 15, 11, 
18, 19, 15, 19, 11, 16, 10, 20, 14, 10, 12, 10, 15, 13, 15, 11, 
20, 11, 12, 16, 16, 11, 15, 11, 11, 10, 10, 16, 11, 20, 17, 20, 
17, 16, 11, 18, 19, 18, 14, 17, 11, 16, 11, 18, 14, 15, 16, 11, 
14, 11, 13)), class = "data.frame", row.names = c(NA, -100L))

3 ответа

Решение

Мы можем сделать что-то очень похожее на то, что сделано в вашем связанном ответе. В частности, во-первых, мы хотим функцию, которая вычисляла бы AME для данного вектора коэффициентов. Для этого мы можем определить

AME.fun <- function(betas) {
  tmp <- ml.fit
  tmp$coefficients <- betas
  ME.mnl <- sapply(c.names, function(x) 
    effects(tmp, covariate = x, data = ml.d), simplify = FALSE)
  c(sapply(ME.mnl, colMeans))
}

где вторая половина твоя, а в первой я использую трюк, чтобы взять то же самое ml.fit объект и изменить его коэффициенты. Далее мы находим якобиана с

require(numDeriv)
grad <- jacobian(AME.fun, ml.fit$coef)

и применить метод дельта. Квадратные корни диагонали grad %*% vcov(ml.fit) %*% t(grad) это то, что мы хотим. Следовательно,

(AME.mnl.se <- matrix(sqrt(diag(grad %*% vcov(ml.fit) %*% t(grad))), nrow = 3, byrow = TRUE))
#             [,1]        [,2]        [,3]        [,4]        [,5]
# [1,] 0.003269320 0.004788536 0.004995723 0.004009762 0.002527462
# [2,] 0.004375795 0.006348496 0.008168883 0.008844684 0.005763966
# [3,] 0.009233616 0.014048212 0.014713090 0.012702188 0.008261734
AME.mnl / AME.mnl.se
#            1          2          3         4        5
# D  -9.259050 -1.8389907 0.30847523 4.2861720 8.051269
# x1 -6.657611 -2.4808393 1.59847852 1.4969683 3.224159
# x2 -2.950794 -0.3902812 0.05828811 0.4197057 3.212458

что совпадает с результатами Stata.

Если вы используете vce="bootstraps" в функции маржи, то она предоставляет SE с доверительным интервалом, а также сводку (margins(ml.fit2,vce="bootstraps"))

Терминология «предельных эффектов» очень противоречива в разных дисциплинах. Поскольку вы ссылаетесь на пакет, я предполагаю, что вы используете выражение «средний предельный эффект» в том же значении, что иmarginsразработчики использовали его, что является результатом этой процедуры:

  1. Вычислите наклон результата относительноDдля каждой строки в исходном наборе данных (предельные эффекты на уровне единиц).
  2. Возьмите среднее значение наклонов на уровне единиц (средний предельный эффект)

В таких моделях, какnnet::multinom, наклоны будут разными для каждого уровня переменной результата. Таким образом, будет один средний предельный эффект на уровень, на регрессор.

Используяmarginaleffectspackage и предоставленные вами данные, получаем:

      library(nnet)
library(marginaleffects)

mod <- nnet::multinom(Y ~ D + x1*x2, data=df1, trace = FALSE)

marginaleffects(mod) |> summary()

       Group Term    Effect Std. Error z value   Pr(>|z|)      2.5 %    97.5 %
    1      1    D -0.027558   0.004183 -6.5878 4.4625e-11 -3.576e-02 -0.019359
    2      1   x1 -0.026789   0.003916 -6.8411 7.8596e-12 -3.446e-02 -0.019114
    3      1   x2 -0.026542   0.009812 -2.7051 0.00682871 -4.577e-02 -0.007311
    4      2    D -0.012115   0.004702 -2.5766 0.00997729 -2.133e-02 -0.002899
    5      2   x1 -0.018223   0.006017 -3.0287 0.00245619 -3.002e-02 -0.006430
    6      2   x2 -0.007045   0.013101 -0.5377 0.59078427 -3.272e-02  0.018633
    7      3    D  0.001536   0.005877  0.2614 0.79380433 -9.982e-03  0.013054
    8      3   x1  0.012451   0.008775  1.4189 0.15592516 -4.748e-03  0.029650
    9      3   x2  0.002193   0.015573  0.1408 0.88801728 -2.833e-02  0.032715
    10     4    D  0.016300   0.004325  3.7689 0.00016399  7.823e-03  0.024776
    11     4   x1  0.018111   0.008789  2.0606 0.03934167  8.845e-04  0.035338
    12     4   x2  0.013543   0.013266  1.0208 0.30733424 -1.246e-02  0.039544
    13     5    D  0.021837   0.003387  6.4479 1.1343e-10  1.520e-02  0.028475
    14     5   x1  0.014449   0.005402  2.6749 0.00747469  3.862e-03  0.025037
    15     5   x2  0.017851   0.009072  1.9677 0.04909878  7.048e-05  0.035631

    Model type:  multinom 
    Prediction type:  probs 
Другие вопросы по тегам