16.2 Average Marginal Effect Algorithm

For one-sided derivative p(X,β)X in the probability scale

  1. Estimate your model
  2. For each observation i
    1. Calculate ˆYi0 which is the prediction in the probability scale using observed values

    2. 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

    3. Calculate ˆYi1 which is the prediction in the probability scale using new X and other variables’ observed vales.

    4. Calculate the difference between the two predictions as fraction of h: ˉYi1ˉYi0h

  3. Average numerical derivative is E[ˉYi1ˉYi0h]p(Y|X,β)X

Two-sided derivatives

  1. Estimate your model
  2. For each observation i
    1. Calculate ˆYi0 which is the prediction in the probability scale using observed values

    2. 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=Xh)

      • When X is continuous, h=(|ˉX|+0.001)×0.001 where ˉX is the mean value of X

      • When X is discrete, h=1

    3. Calculate ˆYi1 which is the prediction in the probability scale using new X1 and other variables’ observed vales.

    4. Calculate ˆYi2 which is the prediction in the probability scale using new X2 and other variables’ observed vales.

    5. Calculate the difference between the two predictions as fraction of h: ˉYi1ˉYi22h

  3. 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