16.2 Average Marginal Effect Algorithm
For one-sided derivative ∂p(X,β)∂X in the probability scale
- Estimate your model
- For each observation i
Calculate ˆYi0 which is the prediction in the probability scale using observed values
Increase X (variable of interest) by a “small” amount h (Xnew=X+h)
When X is continuous, h=(|ˉX|+0.001)×0.001 where ˉX is the mean value of X
When X is discrete, h=1
Calculate ˆYi1 which is the prediction in the probability scale using new X and other variables’ observed vales.
Calculate the difference between the two predictions as fraction of h: ˉYi1−ˉYi0h
- Average numerical derivative is E[ˉYi1−ˉYi0h]≈∂p(Y|X,β)∂X
Two-sided derivatives
- Estimate your model
- For each observation i
Calculate ˆYi0 which is the prediction in the probability scale using observed values
Increase X (variable of interest) by a “small” amount h (X1=X+h) and decrease X (variable of interest) by a “small” amount h (X2=X−h)
When X is continuous, h=(|ˉX|+0.001)×0.001 where ˉX is the mean value of X
When X is discrete, h=1
Calculate ˆYi1 which is the prediction in the probability scale using new X1 and other variables’ observed vales.
Calculate ˆYi2 which is the prediction in the probability scale using new X2 and other variables’ observed vales.
Calculate the difference between the two predictions as fraction of h: ˉYi1−ˉYi22h
- Average numerical derivative is E[ˉYi1−ˉYi22h]≈∂p(Y|X,β)∂X
library(margins)
library(tidyverse)
data("mtcars")
mod <- lm(mpg ~ cyl * disp * hp, data = mtcars)
margins::margins(mod) %>% summary()
#> factor AME SE z p lower upper
#> cyl -4.0592 3.7619 -1.0790 0.2806 -11.4324 3.3141
#> disp -0.0350 0.0132 -2.6471 0.0081 -0.0610 -0.0091
#> hp -0.0284 0.0185 -1.5348 0.1248 -0.0647 0.0079
# function for variable
get_mae <- function(mod, var = "disp") {
data = mod$model
pred <- predict(mod)
if (class(mod$model[[{
{
var
}
}]]) == "numeric") {
h = (abs(mean(mod$model[[var]])) + 0.01) * 0.01
} else {
h = 1
}
data[[{
{
var
}
}]] <- data[[{
{
var
}
}]] - h
pred_new <- predict(mod, newdata = data)
mean(pred - pred_new) / h
}
get_mae(mod, var = "disp")
#> [1] -0.03504546