MARS models via the earth package

Function Works
tidypredict_fit(), tidypredict_sql(), parse_model()
tidypredict_to_column()
tidypredict_test()
tidypredict_interval(), tidypredict_sql_interval()
parsnip

tidypredict_ functions

library(earth)
data("etitanic", package = "earth")

model <- earth(age ~ sibsp + parch, data = etitanic, degree = 3)

GLM models

tidypredict supports the glm argument as well:

model <- earth(survived ~ .,
               data = etitanic,
               glm = list(family = binomial), degree = 2)

tidypredict_fit(model)
#> 1 - 1/(1 + exp(0.961709503833137 + (ifelse(age > 32, age - 32, 
#>     0) * -0.00471937845111412) + (ifelse(pclass == "2nd", 1, 
#>     0) * ifelse(sex == "male", 1, 0) * -0.265689204831234) + 
#>     (ifelse(pclass == "3rd", 1, 0) * -0.815453520799443) + (ifelse(pclass == 
#>     "3rd", 1, 0) * ifelse(sibsp < 4, 4 - sibsp, 0) * 0.102221808806423) + 
#>     (ifelse(pclass == "3rd", 1, 0) * ifelse(sex == "male", 1, 
#>         0) * 0.19310203418243) + (ifelse(sex == "male", 1, 0) * 
#>     -0.570034960114421) + (ifelse(sex == "male", 1, 0) * ifelse(age < 
#>     16, 16 - age, 0) * 0.0450523226133542)))

The spec sets the is_glm entry to 1, as well as the family and link entries.

str(parse_model(model), 2)
#> List of 2
#>  $ general:List of 6
#>   ..$ model  : chr "earth"
#>   ..$ type   : chr "tree"
#>   ..$ version: num 2
#>   ..$ is_glm : num 1
#>   ..$ family : chr "binomial"
#>   ..$ link   : chr "logit"
#>  $ terms  :List of 8
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>  - attr(*, "class")= chr [1:3] "parsed_model" "pm_tree" "list"

parsnip

parsnip fitted models are also supported by tidypredict:

library(parsnip)

p_model <- mars(mode = "regression", prod_degree = 3) %>%
  set_engine("earth") %>%
  fit(age ~ sibsp + parch, data = etitanic)

tidypredict_fit(p_model)
#> 22.2918960405403 + (ifelse(parch < 2, 2 - parch, 0) * 4.85356462114366) + 
#>     (ifelse(parch > 2, parch - 2, 0) * 13.0493891423277) + (ifelse(parch > 
#>     4, parch - 4, 0) * -18.8998708031826) + (ifelse(sibsp > 1, 
#>     sibsp - 1, 0) * -7.71566779782023) + (ifelse(sibsp > 1, sibsp - 
#>     1, 0) * ifelse(parch < 1, 1 - parch, 0) * 7.40395975552272) + 
#>     (ifelse(sibsp > 1, sibsp - 1, 0) * ifelse(parch > 1, parch - 
#>         1, 0) * 4.41874354843212)

Parse model spec

Here is an example of the model spec:

pm <- parse_model(model)
str(pm, 2)
#> List of 2
#>  $ general:List of 6
#>   ..$ model  : chr "earth"
#>   ..$ type   : chr "tree"
#>   ..$ version: num 2
#>   ..$ is_glm : num 1
#>   ..$ family : chr "binomial"
#>   ..$ link   : chr "logit"
#>  $ terms  :List of 8
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>  - attr(*, "class")= chr [1:3] "parsed_model" "pm_tree" "list"
str(pm$terms[1:2])
#> List of 2
#>  $ :List of 4
#>   ..$ label       : chr "(Intercept)"
#>   ..$ coef        : num 0.962
#>   ..$ is_intercept: num 1
#>   ..$ fields      :List of 1
#>   .. ..$ : list()
#>  $ :List of 4
#>   ..$ label       : chr "h(age-32)"
#>   ..$ coef        : num -0.00472
#>   ..$ is_intercept: num 0
#>   ..$ fields      :List of 1
#>   .. ..$ :List of 4
#>   .. .. ..$ type: chr "operation"
#>   .. .. ..$ col : chr "age"
#>   .. .. ..$ val : num 32
#>   .. .. ..$ op  : chr "morethan"