10 Regresión Spline adaptativa multivariante (MARS)

Paquetes de esta sección

if(!require(ISLR)){install.packages("earth")}
if(!require(ISLR)){install.packages("caret")}
if(!require(ISLR)){install.packages("AmesHousing")}
  • En las clases pasadas hemos revisado extensiones de la regresión linear (nls, regresión polinómica, entre otras).

  • Existen otras variaciones como la regresión Ridge, LASSO y Elastic NET (algunas se verán en el módulo de Aprendizaje Automático).

10.1 Introducción

  • En estadística, MARS es una forma de regresión lineal introducida por Jorome Friedan en 1991.

  • MARS es una técnica de regresión no paramétrica y puede ser vista como una extensión de los modelos lineales que automáticamente no linealidades e interacciones entre variables.

  • El término MARS está protegido por derechos de autor y pertenece a Salford Systems.

  • Para evitar violentar esos derechos, las implementaciones abiertas de MARS se suelen llamar Earth (El paquete earth en R, por ejemplo).

  • La Regresión Spline adaptativa multivariante (Multivariate adaptive regression spline - MARS)

10.1.1 ¿Por qué usar modelos MARS?

  • MARS es ideal para usuarios que prefieren obtener resultados similares a la regresión tradicional mientras capturan no linealidades e interacciones necesarias.

  • MARS revela patrones importantes en los datos que otras técnicas suelen fallar en revelar.

  • MARS construye su modelo uniendo pedazos de líneas rectas que mantienen su propia pendiente.

  • Esto permite que se detecte cualquier patrón en los datos.

  • Se puede utilizar para cuando se tiene variables de respuesta cuantitativa y cualitativa.

  • MARS realiza (todo automático y con gran velocidad):

    • selección de variables.
    • transformación de variables.
    • detección de interacciones.
    • testeo

Áreas donde ha mostrado ser una técnica exitosa

  • Predicción de demanda de electricidad de companías generadoras.
  • Relacionar puntajes de satisfacción del cliente con las especificaciones técnicas del producto.
  • Modelización en sistemas de información geográfica.
Fuente: ESLII
Fuente: ESLII
  • MARS es una técnica de regresión muy versátil y es una herramienta necesaria en nuestra caja de herramientas en Analítica de Datos.

10.1.2 La estrucura de MARS

Fuente: Yaseena2018
Fuente: Yaseena2018

10.2 Ejemplo 1

Cargamos los datos:

library(earth)
load("~/Documents/Consultorias&Cursos/DataLectures/banckfull.RData")

Construimos el modelo basado en los datos:

mars <- earth(y~age+job+marital+education+default+balance+housing+
loan+contact+day+month+duration+campaign+pdays+previous+poutcome,
data=bankfull,pmethod="backward",nprune=20, nfold=10)

Notemos los argumentos usando en la función:

  • pmethod: Es el método para podar las variables regresoras. Las opciones son backward, forward, cv (se necesita especificar nfold), y exhaustive.
  • nprune: Numero máximo de funciones base que se usan.

En resumen, para plantear el modelo, necesitamos 3 elementos:

  1. Definir el modelo (como en cualquier regresión)
  2. Definir el método de testeo (pmethod)
  3. Número de funciones base (nprune) y de interacciones (degree)

Veamos el resumen:

summary(mars,digit=3)
## Call: earth(formula=y~age+job+marital+education+default+balance+housin...), data=bankfull,
##             pmethod="backward", nprune=20, nfold=10)
## 
##                  coefficients
## (Intercept)            0.7775
## housingyes            -0.0408
## loanyes               -0.0294
## contactunknown        -0.0713
## monthdec               0.1876
## monthjun               0.0519
## monthmar               0.3301
## monthoct               0.1916
## monthsep               0.1789
## poutcomesuccess        0.3809
## h(age-27)              0.0072
## h(54-age)              0.0087
## h(duration-375)        0.0003
## h(1080-duration)      -0.0004
## h(duration-1080)      -0.0004
## h(2-campaign)          0.0268
## h(pdays-53)           -0.0020
## h(349-pdays)          -0.0016
## h(pdays-349)           0.0061
## h(pdays-425)          -0.0044
## 
## Selected 20 of 22 terms, and 13 of 42 predictors (nprune=20)
## Termination condition: RSq changed by less than 0.001 at 22 terms
## Importance: duration, poutcomesuccess, monthmar, housingyes, monthoct, contactunknown, ...
## Number of terms at each degree of interaction: 1 19 (additive model)
## GCV 0.0707  RSS 3192  GRSq 0.315  RSq 0.316  CVRSq 0.315
## 
## Note: the cross-validation sd's below are standard deviations across folds
## 
## Cross validation:   nterms 22.50 sd 1.78    nvars 14.50 sd 1.84
## 
##      CVRSq    sd     ClassRate    sd     MaxErr   sd
##      0.315 0.021         0.901 0.004      -1.31 1.06

El gráfico de resultado:

plotd(mars)

El GCV (generalized cross validation) es

\[ GCV = \frac{RSS}{N\times (1-Num.Par.Efectivos/N)^2} \]

donde RSS es la suma de cuadrados de los residuos medidos en los datos de entrenamiento y N es el número de observaciones.

\[ Num.Par.Efectivos = NumeroTerminosMARS + Penalidad\times (NumeroTerminosMARS-1)/2 \]

La penalidad es alrededor de 2 o 3, pero se puede elegir la penalidad.

10.2.1 Output

El objeto de resultado es un earth.object que contiene mucha información (ver help(earth.object).

str(mars)
## List of 39
##  $ rss                      : num 3192
##  $ rsq                      : num 0.316
##  $ gcv                      : num 0.0707
##  $ grsq                     : num 0.315
##  $ bx                       : num [1:45211, 1:20] 1 1 1 1 1 1 1 1 1 1 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : NULL
##   .. ..$ : chr [1:20] "(Intercept)" "h(duration-1080)" "h(1080-duration)" "poutcomesuccess" ...
##  $ dirs                     : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:22] "(Intercept)" "h(duration-1080)" "h(1080-duration)" "poutcomesuccess" ...
##   .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##  $ cuts                     : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 54 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:22] "(Intercept)" "h(duration-1080)" "h(1080-duration)" "poutcomesuccess" ...
##   .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##  $ selected.terms           : num [1:20] 1 2 3 4 5 6 7 8 9 11 ...
##  $ prune.terms              : num [1:22, 1:22] 1 1 1 1 1 1 1 1 1 1 ...
##  $ fitted.values            : num [1:45211, 1] 0.0261 -0.0314 -0.074 -0.0597 0.0452 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : NULL
##   .. ..$ : chr "yes"
##  $ residuals                : num [1:45211, 1] -0.0261 0.0314 0.074 0.0597 -0.0452 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : NULL
##   .. ..$ : chr "yes"
##  $ coefficients             : num [1:20, 1] 0.777457 -0.000382 -0.000402 0.380944 0.330111 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:20] "(Intercept)" "h(duration-1080)" "h(1080-duration)" "poutcomesuccess" ...
##   .. ..$ : chr "yes"
##  $ rss.per.response         : num 3192
##  $ rsq.per.response         : num 0.316
##  $ gcv.per.response         : num 0.0707
##  $ grsq.per.response        : num 0.315
##  $ rss.per.subset           : num [1:22] 4670 3880 3497 3433 3378 ...
##  $ gcv.per.subset           : num [1:22] 0.1033 0.0858 0.0774 0.076 0.0747 ...
##  $ leverages                : num [1:45211] 0.000243 0.000165 0.000299 0.000194 0.00025 ...
##  $ pmethod                  : chr "backward"
##  $ nprune                   : num 20
##  $ penalty                  : num 2
##  $ nk                       : num 85
##  $ thresh                   : num 0.001
##  $ termcond                 : int 4
##  $ weights                  : NULL
##  $ call                     : language earth(formula = y ~ age + job + marital + education + default + balance + housing + loan +      contact + day + m| __truncated__ ...
##  $ namesx                   : chr [1:16] "age" "job" "marital" "education" ...
##  $ modvars                  : num [1:16, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:16] "age" "job" "marital" "education" ...
##   .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##  $ terms                    :Classes 'terms', 'formula'  language y ~ age + job + marital + education + default + balance + housing + loan + contact + day +      month + duration | __truncated__
##   .. ..- attr(*, "variables")= language list(y, age, job, marital, education, default, balance, housing, loan, contact, day, month,      duration, campai| __truncated__
##   .. ..- attr(*, "factors")= int [1:17, 1:16] 0 1 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:17] "y" "age" "job" "marital" ...
##   .. .. .. ..$ : chr [1:16] "age" "job" "marital" "education" ...
##   .. ..- attr(*, "term.labels")= chr [1:16] "age" "job" "marital" "education" ...
##   .. ..- attr(*, "order")= int [1:16] 1 1 1 1 1 1 1 1 1 1 ...
##   .. ..- attr(*, "intercept")= int 1
##   .. ..- attr(*, "response")= int 1
##   .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
##   .. ..- attr(*, "predvars")= language list(y, age, job, marital, education, default, balance, housing, loan, contact, day, month,      duration, campai| __truncated__
##   .. ..- attr(*, "dataClasses")= Named chr [1:17] "factor" "numeric" "factor" "factor" ...
##   .. .. ..- attr(*, "names")= chr [1:17] "y" "age" "job" "marital" ...
##  $ xlevels                  :List of 9
##   ..$ job      : chr [1:12] "admin." "blue-collar" "entrepreneur" "housemaid" ...
##   ..$ marital  : chr [1:3] "divorced" "married" "single"
##   ..$ education: chr [1:4] "primary" "secondary" "tertiary" "unknown"
##   ..$ default  : chr [1:2] "no" "yes"
##   ..$ housing  : chr [1:2] "no" "yes"
##   ..$ loan     : chr [1:2] "no" "yes"
##   ..$ contact  : chr [1:3] "cellular" "telephone" "unknown"
##   ..$ month    : chr [1:12] "apr" "aug" "dec" "feb" ...
##   ..$ poutcome : chr [1:4] "failure" "other" "success" "unknown"
##  $ levels                   : chr [1:2] "no" "yes"
##  $ cv.list                  :List of 10
##   ..$ fold1 :List of 29
##   .. ..$ rss              : num 2862
##   .. ..$ rsq              : num 0.319
##   .. ..$ gcv              : num 0.0705
##   .. ..$ grsq             : num 0.318
##   .. ..$ dirs             : num [1:25, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:25] "(Intercept)" "h(duration-1068)" "h(1068-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:25, 1:42] 0 0 0 0 0 0 0 0 0 55 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:25] "(Intercept)" "h(duration-1068)" "h(1068-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:23] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40715, 1] 0.0368 -0.0385 -0.0555 -0.047 0.03 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:23, 1] 0.988498 -0.000414 -0.000393 0.385273 0.310473 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1068)" "h(1068-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2862
##   .. ..$ rsq.per.response : num 0.319
##   .. ..$ gcv.per.response : num 0.0705
##   .. ..$ grsq.per.response: num 0.318
##   .. ..$ rss.per.subset   : num [1:25] 4204 3500 3147 3091 3043 ...
##   .. ..$ gcv.per.subset   : num [1:25] 0.1032 0.086 0.0773 0.0759 0.0748 ...
##   .. ..$ leverages        : num [1:40715] 0.000314 0.000188 0.000219 0.00023 0.000289 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 1
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold2 :List of 29
##   .. ..$ rss              : num 2865
##   .. ..$ rsq              : num 0.318
##   .. ..$ gcv              : num 0.0705
##   .. ..$ grsq             : num 0.317
##   .. ..$ dirs             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1134)" "h(1134-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 54 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1134)" "h(1134-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:21] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40702, 1] 0.0268 -0.0735 0.0436 -0.0231 -0.0119 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:21, 1] 0.509092 -0.000406 -0.000395 0.380106 -0.040944 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:21] "(Intercept)" "h(duration-1134)" "h(1134-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2865
##   .. ..$ rsq.per.response : num 0.318
##   .. ..$ gcv.per.response : num 0.0705
##   .. ..$ grsq.per.response: num 0.317
##   .. ..$ rss.per.subset   : num [1:22] 4203 3485 3141 3084 3036 ...
##   .. ..$ gcv.per.subset   : num [1:22] 0.1033 0.0856 0.0772 0.0758 0.0746 ...
##   .. ..$ leverages        : num [1:40702] 0.000273 0.00034 0.000286 0.000184 0.000344 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 2
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold3 :List of 29
##   .. ..$ rss              : num 2875
##   .. ..$ rsq              : num 0.316
##   .. ..$ gcv              : num 0.0708
##   .. ..$ grsq             : num 0.315
##   .. ..$ dirs             : num [1:24, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:24] "(Intercept)" "h(duration-1070)" "h(1070-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:24, 1:42] 0 0 0 0 0 0 0 0 0 55 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:24] "(Intercept)" "h(duration-1070)" "h(1070-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:23] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40710, 1] 0.0355 -0.0418 -0.0577 -0.0519 0.0324 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:23, 1] 1.046856 -0.000363 -0.000403 0.374318 -0.040932 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1070)" "h(1070-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2875
##   .. ..$ rsq.per.response : num 0.316
##   .. ..$ gcv.per.response : num 0.0708
##   .. ..$ grsq.per.response: num 0.315
##   .. ..$ rss.per.subset   : num [1:24] 4203 3497 3155 3097 3051 ...
##   .. ..$ gcv.per.subset   : num [1:24] 0.1033 0.0859 0.0775 0.0761 0.075 ...
##   .. ..$ leverages        : num [1:40710] 0.000331 0.000187 0.000218 0.000234 0.000288 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 3
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold4 :List of 29
##   .. ..$ rss              : num 2859
##   .. ..$ rsq              : num 0.32
##   .. ..$ gcv              : num 0.0705
##   .. ..$ grsq             : num 0.318
##   .. ..$ dirs             : num [1:27, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:27] "(Intercept)" "h(duration-1074)" "h(1074-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:27, 1:42] 0 0 0 0 0 0 0 0 0 53 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:27] "(Intercept)" "h(duration-1074)" "h(1074-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:25] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40677, 1] 0.022 -0.0408 -0.0688 0.0415 -0.0342 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:25, 1] 1.044955 -0.000344 -0.00041 0.382605 0.293441 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:25] "(Intercept)" "h(duration-1074)" "h(1074-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2859
##   .. ..$ rsq.per.response : num 0.32
##   .. ..$ gcv.per.response : num 0.0705
##   .. ..$ grsq.per.response: num 0.318
##   .. ..$ rss.per.subset   : num [1:27] 4203 3500 3154 3097 3046 ...
##   .. ..$ gcv.per.subset   : num [1:27] 0.1033 0.086 0.0776 0.0762 0.0749 ...
##   .. ..$ leverages        : num [1:40677] 0.00028 0.000194 0.00023 0.000303 0.000191 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 4
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold5 :List of 29
##   .. ..$ rss              : num 2866
##   .. ..$ rsq              : num 0.318
##   .. ..$ gcv              : num 0.0706
##   .. ..$ grsq             : num 0.317
##   .. ..$ dirs             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1078)" "h(1078-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 53 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1078)" "h(1078-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:21] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40651, 1] 0.0388 -0.0453 -0.0589 -0.0587 0.0309 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:21, 1] 0.922143 -0.000382 -0.00041 0.377295 -0.039785 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:21] "(Intercept)" "h(duration-1078)" "h(1078-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2866
##   .. ..$ rsq.per.response : num 0.318
##   .. ..$ gcv.per.response : num 0.0706
##   .. ..$ grsq.per.response: num 0.317
##   .. ..$ rss.per.subset   : num [1:23] 4203 3479 3141 3083 3033 ...
##   .. ..$ gcv.per.subset   : num [1:23] 0.1034 0.0856 0.0773 0.0759 0.0746 ...
##   .. ..$ leverages        : num [1:40651] 0.000314 0.00019 0.000217 0.000231 0.000288 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 5
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold6 :List of 29
##   .. ..$ rss              : num 2882
##   .. ..$ rsq              : num 0.314
##   .. ..$ gcv              : num 0.0709
##   .. ..$ grsq             : num 0.313
##   .. ..$ dirs             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1081)" "h(1081-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 55 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1081)" "h(1081-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:22] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40705, 1] 0.03446 -0.04183 -0.06149 -0.05137 0.00463 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:22, 1] 0.490563 -0.000367 -0.000399 0.38264 0.333366 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1081)" "h(1081-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2882
##   .. ..$ rsq.per.response : num 0.314
##   .. ..$ gcv.per.response : num 0.0709
##   .. ..$ grsq.per.response: num 0.313
##   .. ..$ rss.per.subset   : num [1:23] 4203 3502 3157 3099 3048 ...
##   .. ..$ gcv.per.subset   : num [1:23] 0.1033 0.086 0.0776 0.0762 0.0749 ...
##   .. ..$ leverages        : num [1:40705] 0.000317 0.000187 0.000224 0.000229 0.000219 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 6
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold7 :List of 29
##   .. ..$ rss              : num 2850
##   .. ..$ rsq              : num 0.322
##   .. ..$ gcv              : num 0.0702
##   .. ..$ grsq             : num 0.32
##   .. ..$ dirs             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1088)" "h(1088-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:23, 1:42] 0 0 0 0 0 0 0 0 0 55 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:23] "(Intercept)" "h(duration-1088)" "h(1088-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:22] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40690, 1] -0.033 -0.0503 -0.0601 0.0369 -0.0274 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:22, 1] 1.028487 -0.000414 -0.000401 0.373482 0.340176 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1088)" "h(1088-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2850
##   .. ..$ rsq.per.response : num 0.322
##   .. ..$ gcv.per.response : num 0.0702
##   .. ..$ grsq.per.response: num 0.32
##   .. ..$ rss.per.subset   : num [1:23] 4203 3485 3141 3079 3032 ...
##   .. ..$ gcv.per.subset   : num [1:23] 0.1033 0.0857 0.0772 0.0757 0.0745 ...
##   .. ..$ leverages        : num [1:40690] 0.000176 0.000209 0.000208 0.000277 0.000175 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 7
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold8 :List of 29
##   .. ..$ rss              : num 2863
##   .. ..$ rsq              : num 0.319
##   .. ..$ gcv              : num 0.0705
##   .. ..$ grsq             : num 0.317
##   .. ..$ dirs             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1130)" "h(1130-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 52 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1130)" "h(1130-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:21] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40704, 1] 0.0335 -0.0326 -0.0793 -0.0601 0.0389 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:21, 1] 0.441434 -0.000356 -0.000402 0.384205 0.328753 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:21] "(Intercept)" "h(duration-1130)" "h(1130-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2863
##   .. ..$ rsq.per.response : num 0.319
##   .. ..$ gcv.per.response : num 0.0705
##   .. ..$ grsq.per.response: num 0.317
##   .. ..$ rss.per.subset   : num [1:22] 4203 3488 3140 3083 3033 ...
##   .. ..$ gcv.per.subset   : num [1:22] 0.1033 0.0857 0.0772 0.0758 0.0745 ...
##   .. ..$ leverages        : num [1:40704] 0.000278 0.000186 0.000342 0.000224 0.000286 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 8
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold9 :List of 29
##   .. ..$ rss              : num 2855
##   .. ..$ rsq              : num 0.321
##   .. ..$ gcv              : num 0.0704
##   .. ..$ grsq             : num 0.319
##   .. ..$ dirs             : num [1:27, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:27] "(Intercept)" "h(duration-1084)" "h(1084-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:27, 1:42] 0 0 0 0 0 0 0 0 0 55 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:27] "(Intercept)" "h(duration-1084)" "h(1084-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:26] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40661, 1] 0.0381 -0.0372 -0.0564 -0.0456 0.0402 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:26, 1] 0.519938 -0.00041 -0.000384 0.376764 0.29529 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:26] "(Intercept)" "h(duration-1084)" "h(1084-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2855
##   .. ..$ rsq.per.response : num 0.321
##   .. ..$ gcv.per.response : num 0.0704
##   .. ..$ grsq.per.response: num 0.319
##   .. ..$ rss.per.subset   : num [1:27] 4203 3502 3154 3095 3045 ...
##   .. ..$ gcv.per.subset   : num [1:27] 0.1034 0.0861 0.0776 0.0761 0.0749 ...
##   .. ..$ leverages        : num [1:40661] 0.000327 0.00019 0.000225 0.000235 0.000305 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 9
##   .. ..- attr(*, "class")= chr "earth"
##   ..$ fold10:List of 29
##   .. ..$ rss              : num 2862
##   .. ..$ rsq              : num 0.319
##   .. ..$ gcv              : num 0.0705
##   .. ..$ grsq             : num 0.318
##   .. ..$ dirs             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 1 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1076)" "h(1076-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ cuts             : num [1:22, 1:42] 0 0 0 0 0 0 0 0 0 54 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:22] "(Intercept)" "h(duration-1076)" "h(1076-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ selected.terms   : num [1:21] 1 2 3 4 5 6 7 8 9 10 ...
##   .. ..$ fitted.values    : num [1:40684, 1] 0.0261 -0.0306 -0.0771 -0.0573 0.0396 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : NULL
##   .. .. .. ..$ : chr "yes"
##   .. ..$ coefficients     : num [1:21, 1] 0.44888 -0.000383 -0.000394 0.375859 0.345508 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:21] "(Intercept)" "h(duration-1076)" "h(1076-duration)" "poutcomesuccess" ...
##   .. .. .. ..$ : chr "yes"
##   .. ..$ rss.per.response : num 2862
##   .. ..$ rsq.per.response : num 0.319
##   .. ..$ gcv.per.response : num 0.0705
##   .. ..$ grsq.per.response: num 0.318
##   .. ..$ rss.per.subset   : num [1:22] 4204 3485 3145 3082 3033 ...
##   .. ..$ gcv.per.subset   : num [1:22] 0.1033 0.0857 0.0773 0.0758 0.0746 ...
##   .. ..$ leverages        : num [1:40684] 0.000272 0.000183 0.000339 0.000217 0.000285 ...
##   .. ..$ pmethod          : chr "backward"
##   .. ..$ nprune           : NULL
##   .. ..$ penalty          : num 2
##   .. ..$ nk               : num 85
##   .. ..$ thresh           : num 0.001
##   .. ..$ termcond         : int 4
##   .. ..$ weights          : NULL
##   .. ..$ call             : language earth(x = infold.x, y = infold.y, weights = infold.weights, wp = wp, subset = subset, pmethod = if (pmethod ==   | __truncated__ ...
##   .. ..$ namesx           : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ modvars          : num [1:42, 1:42] 1 0 0 0 0 0 0 0 0 0 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. .. .. ..$ : chr [1:42] "age" "jobblue-collar" "jobentrepreneur" "jobhousemaid" ...
##   .. ..$ levels           : num [1:2] 0 1
##   .. ..$ icross           : int 1
##   .. ..$ ifold            : int 10
##   .. ..- attr(*, "class")= chr "earth"
##  $ cv.nterms.selected.by.gcv: Named num [1:11] 23 21 23 25 21 22 22 21 26 21 ...
##   ..- attr(*, "names")= chr [1:11] "fold1" "fold2" "fold3" "fold4" ...
##  $ cv.nvars.selected.by.gcv : Named num [1:11] 16 13 14 18 14 13 14 13 17 13 ...
##   ..- attr(*, "names")= chr [1:11] "fold1" "fold2" "fold3" "fold4" ...
##  $ cv.groups                : int [1:45211, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : NULL
##   .. ..$ : chr [1:2] "cross" "fold"
##  $ cv.rsq.tab               : num [1:11, 1:2] 0.318 0.302 0.337 0.34 0.304 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:11] "fold1" "fold2" "fold3" "fold4" ...
##   .. ..$ : chr [1:2] "yes" "mean"
##  $ cv.maxerr.tab            : num [1:11, 1:2] -1.31 -1.12 -1.07 -1.03 1.05 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:11] "fold1" "fold2" "fold3" "fold4" ...
##   .. ..$ : chr [1:2] "yes" "max"
##  $ cv.class.rate.tab        : num [1:11, 1:2] 0.902 0.896 0.907 0.903 0.899 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : NULL
##   .. ..$ : chr [1:2] "yes" "mean"
##  - attr(*, "class")= chr "earth"

De todos este conjunto, vamos a destacar 3 elementos

  1. Importancia de las variables
  2. Funciones base (modelo resultado)
  3. Curvas y superficie (contribución)

Importancia de las variables

library(caret)
varImp( mars  ) 
##                    Overall
## duration        100.000000
## poutcomesuccess  68.109084
## monthmar         45.171762
## housingyes       40.087272
## monthoct         35.114270
## contactunknown   31.401977
## monthsep         27.823303
## age              24.185852
## monthjun         21.090675
## pdays            16.010587
## monthdec         14.461722
## campaign         12.631608
## loanyes           5.779968

Funciones Base

mars$coefficients
##                            yes
## (Intercept)       0.7774569240
## h(duration-1080) -0.0003818948
## h(1080-duration) -0.0004020631
## poutcomesuccess   0.3809444003
## monthmar          0.3301108826
## housingyes       -0.0407997273
## monthoct          0.1916481210
## contactunknown   -0.0712999709
## monthsep          0.1788583816
## h(54-age)         0.0087017318
## h(duration-375)   0.0003026388
## monthjun          0.0518693660
## h(2-campaign)     0.0268377535
## monthdec          0.1876019796
## h(pdays-349)      0.0061454449
## h(349-pdays)     -0.0015968138
## h(age-27)         0.0071639964
## h(pdays-53)      -0.0020353430
## h(pdays-425)     -0.0043865936
## loanyes          -0.0293712807

Curvas y superficie

plotmo( mars,  all1 = T   ) 
##  plotmo grid:    age         job marital education default balance housing loan  contact day
##                   39 blue-collar married secondary      no     448     yes   no cellular  16
##  month duration campaign pdays previous poutcome
##    may      180        2    -1        0  unknown

plot(mars$fitted.values~bankfull$duration)

10.2.2 Tu turno

Sobre los datos ames_train ajusta un modelo MARS que tenga como variable dependiente al precio de venta Sale_Price.

library(rsample)
# Create training (70%) and test (30%) sets for the AmesHousing::make_ames() data.
# Use set.seed for reproducibility

set.seed(123)
ames_split <- initial_split(AmesHousing::make_ames(), prop = .7, strata = "Sale_Price")
ames_train <- training(ames_split)
ames_test  <- testing(ames_split)