Está en la página 1de 61

TEMA 3.

BAGGING Y RANDOM FOREST


Máxima Formación

Contents
Introducción. 2

1. Modelo de Ensemble: Árboles de decisión Individuales. 7

2.Bagging: Bootstrap Aggregation. 10


2.1. Bagging: Ventajas e Inconvenientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2. Dataset: Churn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3. Random Forest. 13
3.1. Random Forest: Ventajas e Inconvenientes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2. Instalación de paquetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3. Parámetros función: randomForest() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4. Random Forest de Regresión: Librería randomForest . . . . . . . . . . . . . . . . . . . . . . . 14
3.5. Selección de parámetros: Librería randomForest . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.6. Random Forest de clasificación: Librería ranger. . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.7. Grid Search: Selección de Hiperparámetros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4. Modelos de Bagging: Librería H2o 39


4.1. Parámetros generales modelos H2o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.2. Parámetros generales modelo Random Forest Distribuido. . . . . . . . . . . . . . . . . . . . . 40
4.3. Caso de estudio: Home Credit Default Risk . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.4. Grid Search: Selección de Hiperparámetros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

1
Introducción.
Uno de los problemas que nos encontramos cuando utilizamos árboles de decisión es que tienen una gran
variabilidad, es decir, dependiendo de los datos que utilicemos el árbol se formará de una forma u otra. Para
ello vamos a tomar un ejemplo del tema anterior del conjunto de datos churn, sobre la tasa de abandono de
clientes en telecomunicaciones. Dividimos la base de datos de entrenamiento en tres partes y crearemos un
árbol para cada una de ellas para ver cómo se forman.

#Cargamos los datos.


churnTrain <- read.csv("Datasets/churnTrain.csv")
churnTest <- read.csv("Datasets/churnTest.csv")
#Dividimos los datos de entrenamiento en 3 partes.
train1_churn <- churnTrain[1:1111,]
train2_churn <- churnTrain[1112:2222,]
train3_churn <- churnTrain[2223:3333,]

Nos hemos quedado con 3 conjuntos de entrenamiento de 1.111 observaciones cada uno y un conjunto de
validación de 1.667 observaciones. Realizamos ahora un árbol para cada conjunto de datos con los parámetros
iniciales.

#Cargamos las librerías.


library(rpart)
library(rpart.plot)
#Arbol 1
tree_churn_1 <- rpart(churn ~., data = train1_churn, method = "class")
rpart.plot(tree_churn_1)

no
0.12
100%
yes total_day_minutes < 265 no

yes
0.51
7%
state = AK,AZ,CA,FL,HI,ID,IN,LA,MN,MS,NC,NM,PA,SD,TN,UT,VA,WA,WV

no
0.10
93%
number_customer_service_calls < 4

no yes
0.45 0.75
7% 4%
total_day_minutes >= 180 total_eve_minutes < 168

no
0.07
86%
international_plan = no

no yes
0.34 0.69
8% 4%
total_intl_minutes < 13 state = AL,CO,FL,HI,IA,LA,NY,OR,TX,VT,WI,WY

no
0.04
78%
total_day_minutes < 249

no
0.24
4%
state = AL,DC,DE,FL,GA,IA,IN,KY,ME,MN,MS,MT,NC,NE,NY,OR,RI,UT,VA,WV

no no
0.19 0.42
7% 2%
total_intl_calls >= 3 total_eve_minutes >= 209

no no yes no yes no
0.03 0.05 1.00 0.08 1.00 0.11
3% 6% 1% 1% 2% 1%

no yes yes no yes no yes


0.03 0.90 1.00 0.12 0.75 0.07 0.90
75% 1% 1% 3% 1% 2% 4%

2
#Arbol 2
tree_churn_2 <- rpart(churn ~., data = train2_churn, method = "class")
rpart.plot(tree_churn_2)

no
0.15
100%
yes total_day_minutes < 266 no

no yes
0.12 0.68
95% 5%
number_customer_service_calls < 4 voice_mail_plan = yes

no yes yes
0.09 0.52 0.84
87% 8% 4%
international_plan = no total_day_minutes >= 160 state = AZ,CO,CT,IL,MD,WV

no no no
0.05 0.41 0.21
79% 8% 4%
total_day_minutes < 222 total_intl_calls >= 3 state = AZ,CA,CO,DC,FL,ID,IN,KY,ME,MI,MN,ND,NE,NJ,OK,RI,SC,TX,VA,VT,WI,WY

no no
0.18 0.25
12% 6%
total_eve_minutes < 240 total_intl_minutes < 13

yes
0.55
3%
state = DE,GA,HI,KS,NV,VT,WA,WI

no no no yes no yes yes no yes yes no no yes


0.03 0.07 0.00 0.82 0.05 1.00 1.00 0.00 0.62 0.92 0.08 0.36 1.00
67% 9% 1% 2% 5% 1% 2% 3% 1% 3% 1% 1% 3%

#Arbol 3
tree_churn_3 <- rpart(churn ~., data = train3_churn, method = "class")
rpart.plot(tree_churn_3)

3
no
0.16
100%
yes total_day_minutes < 264 no

no yes
0.12 0.67
93% 7%
number_customer_service_calls < 4 voice_mail_plan = yes

no yes yes
0.08 0.54 0.83
85% 8% 5%
international_plan = no total_day_minutes >= 179 total_eve_minutes < 180

no no no yes
0.05 0.38 0.21 0.84
77% 8% 4% 4%
total_day_minutes < 224 total_intl_calls >= 3 state = AL,CA,CT,DE,GA,HI,IA,ID,MD,MO,NE,NM,OK,OR,SC,TN,VA,VT,WV state = GA,HI,IL,IN,MA

no no
0.22 0.21
11% 6%
total_eve_minutes < 266 total_intl_minutes < 13

no
0.12
10%
state = AK,AL,AZ,DC,DE,FL,HI,IA,IL,IN,KS,KY,MA,ME,MN,MO,MS,MT,NH,NY,OH,PA,RI,SD,TN,TX,UT,VA,VT,WI,WV,WY

no
0.35
3%
total_night_minutes < 173

no
0.50
2%
total_day_minutes < 240

no no no no yes yes no yes yes no yes no yes no no yes


0.03 0.01 0.00 0.21 0.90 0.88 0.02 1.00 1.00 0.00 0.60 0.33 0.97 0.06 0.41 1.00
66% 7% 1% 1% 1% 1% 5% 1% 2% 2% 1% 1% 3% 1% 2% 4%

Como podemos ver para cada conjunto de entrenamiento se ha realizado un árbol de decisión distinto. Vamos
a predecir para cada uno de los árboles en el conjunto de validación y así ver cómo se comportan cada uno
de ellos frente a nuevos datos.

#Árbol 1 - Predicción
tree_churn_predict_1 <- predict(tree_churn_1, newdata = churnTest, type = "class")
table(tree_churn_predict_1, churnTest$churn)

##
## tree_churn_predict_1 no yes
## no 1421 113
## yes 22 111

#Árbol 2 - Predicción
tree_churn_predict_2 <- predict(tree_churn_2, newdata = churnTest, type = "class")
table(tree_churn_predict_2, churnTest$churn)

##
## tree_churn_predict_2 no yes
## no 1398 70
## yes 45 154

#Árbol 3 - Predicción
tree_churn_predict_3 <- predict(tree_churn_3, newdata = churnTest, type = "class")
table(tree_churn_predict_3, churnTest$churn)

4
##
## tree_churn_predict_3 no yes
## no 1400 84
## yes 43 140

Cada uno de los modelos creados tienen una tasa de acierto diferente:

• tree_churn_1 tiene una tasa de acierto de 91.90%.


• tree_churn_2 tiene una tasa de acierto de 93.10%.
• tree_churn_3 tiene una tasa de acierto de 92.38%.

Podríamos pensar que un árbol entrenado con el total del conjunto de datos de entrenamiento podría obtener
mejor resultado. Vamos a comprobarlo:

tree_churn_total <- rpart(churn ~., data = churnTrain, method = "class")


rpart.plot(tree_churn_total)

no
0.14
100%
yes total_day_minutes < 264 no

no yes
0.11 0.60
94% 6%
number_customer_service_calls < 4 voice_mail_plan = yes

no yes yes
0.08 0.51 0.77
86% 8% 5%
international_plan = no total_day_minutes >= 160 total_eve_minutes < 188

no no no no
0.05 0.38 0.26 0.44
78% 8% 4% 2%
total_day_minutes < 223 total_intl_calls >= 3 state = AL,AZ,CA,CO,DC,DE,FL,GA,HI,ID,IN,LA,MA,MD,NC,ND,NE,NM,OK,RI,SC,VA,VT,WI,WV,WY state = AK,AR,AZ,CO,CT,FL,HI,IL,IN,KS,LA,MD,ND,NM,NV,NY,OH,UT,WA,WI,WV

no no no
0.18 0.23 0.48
11% 6% 2%
total_eve_minutes < 260 total_intl_minutes < 13 total_eve_minutes >= 200

yes
0.67
2%
voice_mail_plan = yes

no no no yes no yes yes no no yes yes no no yes yes


0.03 0.10 0.00 0.85 0.04 1.00 1.00 0.09 0.21 0.71 0.87 0.11 0.21 0.94 0.95
67% 10% 0% 1% 5% 1% 2% 3% 1% 1% 3% 2% 1% 1% 3%

En la representación gráfica del modelo observamos que no es igual que los anteriores modelos y que difiere
en su estructura. Predecimos con el modelo para comprobar su tasa de acierto.

#Árbol Total - Predicción


tree_churn_predict_total <- predict(tree_churn_total, newdata = churnTest, type = "class")
table(tree_churn_predict_total, churnTest$churn)

5
##
## tree_churn_predict_total no yes
## no 1409 83
## yes 34 141

La tasa de acierto de nuestro modelo entrenado con todos los datos es de 92.98%, que no difiere de los modelos
individuales. Queda demostrado que aún con tasas de acierto parecidas, estas no son iguales, debido a la
sensibilidad a los datos con los que entrenemos el modelo. Además, vemos que, aunque hemos aumentado
el número de casos con los que entrenamos el modelo, el poder predictivo de este no difiere del resto de los
modelos que hemos realizado.

6
1. Modelo de Ensemble: Árboles de decisión Individuales.
Una forma de mejorar el poder predictivo de los árboles de decisión y reducir su varianza es por medio de
técnicas de ensemble, que consisten en dividir el conjunto de entrenamiento en varios subconjuntos, creando
un árbol para cada uno de estos subconjuntos. Cada árbol es entrenado sobre el conjunto de datos aportando
una predicción. La predicción final será la media de las predicciones de cada árbol en el caso de los problemas
de regresión, y en los problemas de clasificación será la categoría más frecuente. Cuanto más diferentes sean
cada uno de los modelos que promediamos más mejorará la predicción final conjunta.
Seguimos nuestro ejemplo para ver cómo funciona estas técnicas. Tenemos los tres árboles con estructura
distinta y predicciones con tasa de acierto diferente.

par(mfrow=c(1,3))
rpart.plot(tree_churn_1)
rpart.plot(tree_churn_2)
rpart.plot(tree_churn_3)

no no
0.12
no 0.16
100% 0.15 100%
yes total_day_minutes < 265 no
100% yes total_day_minutes < 264 no

yes total_day_minutes < 266 no

yes
0.67
7%
voice_mail_plan = yes

no

yes 0.12

0.68 93%
number_customer_service_calls < 4
5%
yes voice_mail_plan = yes
0.51
7% no
state = AK,AZ,CA,FL,HI,ID,IN,LA,MN,MS,NC,NM,PA,SD,TN,UT,VA,WA,WV
0.12
95%
no
0.10
number_customer_service_calls < 4
93% yes yes
number_customer_service_calls < 4
0.54 0.83
8% 5%
total_day_minutes >= 179 total_eve_minutes < 180

no
0.08
85%
international_plan = no

yes yes
0.52 0.84
8% 4%
total_day_minutes >= 160 state = AZ,CO,CT,IL,MD,WV
no no yes
0.38 0.84
0.09 8% 4%
87% total_intl_calls >= 3 state = GA,HI,IL,IN,MA
no yes
0.45 0.75 international_plan = no no no
7% 4%
total_day_minutes >= 180 total_eve_minutes < 168 0.05 0.21
77% 4%
total_day_minutes < 224 state = AL,CA,CT,DE,GA,HI,IA,ID,MD,MO,NE,NM,OK,OR,SC,TN,VA,VT,WV
no
0.07
86%
international_plan = no

no no
0.41 0.22
8% 11%
total_eve_minutes < 266

total_intl_calls >= 3
no
no no 0.21
0.05 0.21 6%
total_intl_minutes < 13
79% 4%
total_day_minutes < 222 state = AZ,CA,CO,DC,FL,ID,IN,KY,ME,MI,MN,ND,NE,NJ,OK,RI,SC,TX,VA,VT,WI,WY

no yes
0.34 0.69
8% 4%
total_intl_minutes < 13 state = AL,CO,FL,HI,IA,LA,NY,OR,TX,VT,WI,WY

no
0.04
78%
total_day_minutes < 249
no no

0.18 0.12

12% 10%
state = AK,AL,AZ,DC,DE,FL,HI,IA,IL,IN,KS,KY,MA,ME,MN,MO,MS,MT,NH,NY,OH,PA,RI,SD,TN,TX,UT,VA,VT,WI,WV,WY

total_eve_minutes < 240


no
0.25
6%
total_intl_minutes < 13
no
0.35
3%
total_night_minutes < 173

no
0.24
4%
state = AL,DC,DE,FL,GA,IA,IN,KY,ME,MN,MS,MT,NC,NE,NY,OR,RI,UT,VA,WV
yes
no no
0.55
0.19 0.42 3%
7% 2%
total_intl_calls >= 3 total_eve_minutes >= 209 state = DE,GA,HI,KS,NV,VT,WA,WI

no
0.50
2%
total_day_minutes < 240

no yes yes no yes no


0.07 0.82 1.00 0.00 0.92 0.36
no no yes no yes no
9% 2% 1% 3% 3% 1% no no yes yes no no no yes
0.03 0.05 1.00 0.08 1.00 0.11 0.01 0.21 0.88 1.00 0.00 0.33 0.06 1.00
3% 6% 1% 1% 2% 1% 7% 1% 1% 1% 2% 1% 1% 4%

no yes yes no yes no yes


no no no yes yes no yes no no yes no yes yes yes no
0.03 0.90 1.00 0.12 0.75 0.07 0.90
0.03 0.00 0.05 1.00 0.62 0.08 1.00 0.03 0.00 0.90 0.02 1.00 0.60 0.97 0.41
75% 1% 1% 3% 1% 2% 4% 67% 1% 5% 2% 1% 1% 3% 66% 1% 1% 5% 2% 1% 3% 2%

Creamos un dataframe con las tres predicciones de cada árbol. Cada columna es la predicción que ha
realizado cada modelo sobre el conjunto de validación.

#Creamos el dataframe.
predict_datos <- data.frame(tree_churn_predict_1,tree_churn_predict_2, tree_churn_predict_3)
#Visualizamos los 10 primeros casos.
head(predict_datos,10)

## tree_churn_predict_1 tree_churn_predict_2 tree_churn_predict_3

7
## 1 no no no
## 2 no yes no
## 3 yes no no
## 4 no no no
## 5 no no no
## 6 no no no
## 7 no no no
## 8 no no no
## 9 no no no
## 10 no no no

Como nuestro problema es de clasificación vamos a crear una cuarta columna denominada final que nos
indique la respuesta cuya frecuencia es mayor de cada observación.

#Sumamos el número de columnas con "yes".


predict_datos$yes <- rowSums(predict_datos[,1:3] == "yes")
#Sumamos el número de columnas con "no"
predict_datos$no <- rowSums(predict_datos[,1:3] == "no")
#Creamos predicción final y transformamos la variable a factor.
predict_datos$final <- as.factor(ifelse(predict_datos$yes> predict_datos$no, "yes","no"))
#Visualizamos la predicción final.
head(predict_datos[, c(1,2,3,6)])

## tree_churn_predict_1 tree_churn_predict_2 tree_churn_predict_3 final


## 1 no no no no
## 2 no yes no no
## 3 yes no no no
## 4 no no no no
## 5 no no no no
## 6 no no no no

Obtenemos la tasa de acierto de la nueva predicción conjunta. Utilizamos el paquete Caret que nos permite
con la función confusionMatrix() analizar la precisión de nuestro modelo.

library(caret)
confusionMatrix(predict_datos$final,churnTest$churn)

## Confusion Matrix and Statistics


##
## Reference
## Prediction no yes
## no 1429 89
## yes 14 135
##
## Accuracy : 0.9382
## 95% CI : (0.9256, 0.9493)
## No Information Rate : 0.8656
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.6907
##
## Mcnemar's Test P-Value : 0.0000000000003067

8
##
## Sensitivity : 0.9903
## Specificity : 0.6027
## Pos Pred Value : 0.9414
## Neg Pred Value : 0.9060
## Prevalence : 0.8656
## Detection Rate : 0.8572
## Detection Prevalence : 0.9106
## Balanced Accuracy : 0.7965
##
## 'Positive' Class : no
##

Nuestro nivel de predicción ha mejorado hasta el 93.82% cuando nuestro mejor modelo tenía una tasa de
acierto de 93.10%. Hemos creado como ejemplo tres modelos diferentes para 3 conjuntos de entrenamiento
y hemos unido sus predicciones individuales sobre el conjunto de validación, en función de la clase más
frecuente mejorando la tasa de acierto final de cada modelo individual.

9
2.Bagging: Bootstrap Aggregation.
Los métodos de bagging, random forests y boosting (tema 4) nos permiten mejorar sustancialmente el
rendimiento predictivo de modelos basados en árboles, aunque con el inconveniente de una considerable
reducción en la facilidad de interpretación del modelo final. Estos métodos también se conocen como métodos
de ensemble o métodos combinados, que son los que utilizan múltiples algoritmos de aprendizaje para obtener
predicciones que mejoren las que se podrían obtener por medio de cualquiera de los algoritmos individuales.
Son aplicables a muchos métodos de aprendizaje estadísticos (no solo árboles de decisión) para regresión o
clasificación.
Los árboles individuales, como ya hemos comentado, sufren de alta variabilidad y escaso poder predictivo.
Uno de los métodos que ayuda a mejorar el poder predictivo y a reducir la varianza es el Bagging que veremos
en este tema.
Este método consiste en crear subconjuntos de datos del conjunto de datos original manteniendo la misma
distribución de los datos. Después para cada subconjunto de datos creados se entrena un árbol de decisión
individual sin podar creando un bosque de árboles en paralelo. Cada modelo se construye con el 2/3 (63.2%)
de los datos, dejando 1/3 para predecir las observaciones de out of bag (OOB), es decir, sobre datos con los que
no ha sido entrenado el modelo y que sirve como estimación del error del test. Cuantos más árboles creemos
menor varianza tenemos y por tanto menor error. Por último, se promedia las predicciones individuales de
cada árbol si nos enfrentamos a un problema de regresión o se elige la clase con más frecuencia para los
problemas de clasificación.
Este tipo de método se puede aplicar a cualquier algoritmo de clasificación o regresión, pero es más efectivo
en aquellos modelos que tienen varianza alta, así modelos de regresión múltiple tienden a no mejorar su
poder predictivo.

2.1. Bagging: Ventajas e Inconvenientes

Las ventajas del Bagging son:

• Mayor poder predictivo que los árboles de decisión individuales.


• Se reduce la varianza con respecto a los árboles individuales.
• Nos indica las variables principales o que más influyen en el modelo.

Los inconvenientes del Bagging son:

• Crea modelos más complicados que son difíciles de interpretar.


• Utiliza todas las variables para crear los modelos por lo que, si hay una variable muy influyente sobre
el resto, se utilizará en todos los modelos y sus predicciones serán muy parecidas (alta correlación de
las predicciones).
• No podemos obtener una visión gráfica del modelo.

2.2. Dataset: Churn

Continuamos con nuestro ejemplo para aplicar el método Bagging. Para ello vamos a utilizar dos librerías
como son ipred y más adelante utilizaremos la librería randomForest.

#install.packages(c("ipred","randomForest"))
library(ipred)
library(randomForest)

10
En el ejemplo que hemos utilizado dividíamos nuestro conjunto de entrenamiento es subconjuntos para
entrenar nuestros modelos, en este caso el algoritmo se encarga en subdividirlo y realizar un modelo para
cada subconjunto.

model_bagging <- bagging(churn ~ .,


data = churnTrain,
coob = TRUE,
nbagg = 25) #Número de árboles. Por defecto 25.
model_bagging

##
## Bagging classification trees with 25 bootstrap replications
##
## Call: bagging.data.frame(formula = churn ~ ., data = churnTrain, coob = TRUE,
## nbagg = 25)
##
## Out-of-bag estimate of misclassification error: 0.0678

Como vemos nuestra tasa de error estimada es de 0.06, cuando utilizamos 25 árboles individuales.
Predecimos con nuestro modelo sobre el conjunto de datos de validación.

predict_bagging <- predict(model_bagging, newdata = churnTest, type = "class")


confusionMatrix(predict_bagging, churnTest$churn)

## Confusion Matrix and Statistics


##
## Reference
## Prediction no yes
## no 1425 71
## yes 18 153
##
## Accuracy : 0.9466
## 95% CI : (0.9347, 0.9569)
## No Information Rate : 0.8656
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.745
##
## Mcnemar's Test P-Value : 0.00000003548
##
## Sensitivity : 0.9875
## Specificity : 0.6830
## Pos Pred Value : 0.9525
## Neg Pred Value : 0.8947
## Prevalence : 0.8656
## Detection Rate : 0.8548
## Detection Prevalence : 0.8974
## Balanced Accuracy : 0.8353
##
## 'Positive' Class : no
##

11
Nuestra tasa de acierto es del 94% con nuestro modelo con 25 árboles. En nuestro ejemplo, que hemos
realizado con 3 árboles, obtuvo una tasa de acierto de 93.82% y, los modelos individuales con los distintos
conjuntos de datos, no superaron la tasa de error de 93.10%.
Obtenemos las variables más importantes por medio de la función varImp(), que calcula la precisión (accu-
racy) sobre los datos out of bag permutando cada variable. La diferencia entre las dos predicciones (con la
variable y sin la variable) nos da la contribución de la variable al modelo.

varImp(model_bagging)

## Overall
## account_length 69.46909
## area_code 26.99618
## international_plan 165.52447
## number_customer_service_calls 163.17795
## number_vmail_messages 87.87472
## state 374.75612
## total_day_calls 69.96440
## total_day_charge 310.69971
## total_day_minutes 332.12971
## total_eve_calls 52.92322
## total_eve_charge 200.78803
## total_eve_minutes 217.77038
## total_intl_calls 106.85502
## total_intl_charge 112.92944
## total_intl_minutes 124.53310
## total_night_calls 55.30516
## total_night_charge 71.99520
## total_night_minutes 89.71903
## voice_mail_plan 73.21337

Obtenemos que las variables más importantes son: state, total_day_minutes y total_day_charge.

12
3. Random Forest.
El random forest es un caso particular dentro del método bagging para reducir la varianza. Los modelos
bagging se basan en crear con todas las variables árboles en paralelo construyendo bosques, cuyo fin es
reducir la varianza de los árboles individuales y aumentar el poder predictivo por medio del promedio o
la frecuencia de las predicciones individuales. Como ya hemos comentado, uno de los problemas que nos
encontramos cuando hay una variable/s muy influyentes es que serán utilizadas en los primeros nodos en la
construcción del árbol, lo que hará que nuestros árboles individuales tengan una estructura parecida y sus
predicciones estén correlacionadas unas con otras.
El modelo de random forest soluciona este problema. Cuando se crea cada modelo solo se le deja elegir
entre los m predictores elegidos aleatoriamente de todos los predictores considerados. No permite elegir
entre todas las variables independientes, sino que solo puede elegir entre un número establecido y elegidas
aleatoriamente, no seleccionando siempre la/s variable/s más influyentes, descorrelacionando las predicciones
y mejorando el poder predictivo del modelo.
Para establecer el número de variables independientes que se utilizan en cada árbol de forma aleatoria se

suele tomar para problemas, de clasificación como m = p y para problemas de regresión m = p3 donde p
es el número de predictores. Si m = p estaríamos realizando un modelo de bagging puro. También podemos
elegirlos manualmente al crear el modelo.

3.1. Random Forest: Ventajas e Inconvenientes.

Las ventajas de los Random Forest son:

• Alto poder predictivo. Mejoran las predicciones de los árboles individuales.


• Nos sirve tanto para problemas de regresión como de clasificación.
• Robusto a valores atípicos.
• Nos da una aproximación del error (out of bag) al entrenar el modelo (es una aproximación, no el error
que vamos a acometer al predecir).
• Se pueden realizar modelos con alto poder predictivo sin tener que ajustar parámetros.
• Se puede utilizar como herramienta de selección de predictores.

Los inconvenientes del Random Forest son:

• No son fáciles de interpretar ni de representar.


• Con grandes conjuntos de datos el modelo se vuelve lento.
• Aunque durante mucho tiempo fue uno de los modelos con mayor poder predictivo, actualmente ha
sido superado por otros modelos (xgboost, Catboost. . . ).

3.2. Instalación de paquetes.

Como comentábamos en el Tema 2, en R hay varios paquetes para realizar los mismos modelos. Para realizar
Random Forest y Bagging podemos encontrar aproximadamente 20 paquetes que realizan dichos algoritmos
y que difieren en tiempo de computación, estructura del modelo, optimización. . . Nosotros utilizaremos dos:
randomForest y ranger para la creación de estos modelos. Más adelante utilizaremos el paquete H2O para
realizar Random Forest Distribuido.

#install.packages(c("randomForest","ranger"))

13
3.3. Parámetros función: randomForest()

Los parámetros que podemos utilizar con la función randomForest() de la librería randomForest son los
siguientes:

• Formula: Variable dependiente en función de las variables respuesta, separadas por ” ∼ ”. Si después
de ” ∼ ” ponemos un “.” indica que utilizaremos todas las variables del dataset excepto la variable
dependiente.
• data: Conjunto de datos con los que entrenaremos el modelo.
• ntree: Número de árboles que realiza el modelo.
• mtry: Número de variables que utiliza.
• nodesize: Tamaño mínimo de los nodos terminales.
• maxnodes: Número máximo de nodos terminales que pueden tener los árboles.
• importance: Igual a TRUE, calcula la importancia de los predictores.

Los parámetros que podemos utilizar con la función ranger() de la librería ranger son los siguientes:

• Formula: Variable dependiente en función de las variables respuesta.


• num.trees: Número de árboles.
• Mtry: Número de variables a utilizar.
• min.node.size: Tamaño mínimo del nodo.

Recordar que el algoritmo tiene un alto poder predictivo incluso con los parámetros configurados por defecto.

3.4. Random Forest de Regresión: Librería randomForest

Utilizaremos el dataset de las casas de Boston que utilizamos en el tema anterior, para realizar un ejemplo
práctico de como entrenar un modelo de Random Forest. El dataset consistía en predecir el valor de las
casas (medv) en los años 1970, y por tanto es un problema de regresión.

#Cargamos la librería y los datos.


library(MASS)
data(Boston)

Dividimos los datos en un conjunto de entrenamiento con el 80% de los datos y un conjunto de validación
con el 20% de los datos

index <- sample(1:nrow(Boston), size = 0.8 * nrow(Boston))


train_house <- Boston[index,]
test_house <- Boston[-index,]

Creamos el modelo con la librería randomForest().

library(randomForest)
set.seed(123)
model_random_1 <- randomForest(medv ~ .,
data = train_house)
model_random_1

14
##
## Call:
## randomForest(formula = medv ~ ., data = train_house)
## Type of random forest: regression
## Number of trees: 500
## No. of variables tried at each split: 4
##
## Mean of squared residuals: 10.69312
## % Var explained: 87.43

Nos indica que se ha realizado un modelo de regresión, con 500 árboles y 4 variables, con una media de los
residuos al cuadrado de 10,6 y una varianza explicada del 87%
Dibujamos el error en función del número de árboles.

plot(model_random_1)

model_random_1
50
40
Error

30
20
10

0 100 200 300 400 500

trees

El error disminuye según aumentan los árboles, estabilizándose en 200 árboles, aunque sigue reduciéndose de
una forma más lenta hasta aproximadamente 290 árboles.1 La tasa de error se basa en el error OOB (out of
bag) por lo que podemos encontrar el número de árboles que minimiza el error OOB. Si quisiéramos obtener
el error OOB para cada uno de los árboles podemos solicitarlo con model_random_1$mse.

1 Enla última actualización de la librería realiza tres líneas: Negra que indica el error global del modelo OOB, roja que
indica el error de la clase 0 y verde el error de la clase 1.

15
#Seleccionamos el óptimo de árboles.
(min <- which.min(model_random_1$mse))

## [1] 249

El número de árboles que minimiza el error en nuestro modelo es de 249 árboles. Podemos calcular el error
con el óptimo del número de árboles.

(rmse_min <- sqrt(model_random_1$mse[which.min(model_random_1$mse)]))

## [1] 3.26885

Nuestro modelo sin optimizar y con los parámetros por defecto ha reducido considerablemente el error.

3.5. Selección de parámetros: Librería randomForest

Uno de los problemas cuando queremos utilizar un modelo de Random Forest es el número de variables que
puede elegir el modelo. Este problema no lo tenemos en los modelos de Bagging ya que utilizan todas las
variables. No utilizar todas las variables reduce la correlación entre los distintos árboles, ya que no siempre
se utilizarán las mismas y por tanto si hay una variable independiente más influyente que las otras no se
escogerá en todos los modelos. Una forma de seleccionar el número de variables es por medio de la función
tuneRF.

set.seed(123)
(tune_rf <- tuneRF(x = train_house[,1:13], #Variables predictoras.
y = train_house[,14], #Variable a predecir.
ntreeTry = 500, #Número de árboles.
mtryStart = 2, #Variables de inicio
improve = 0.01, #Mínimo de mejora.
trace = F)) #No enseñar el progreso.

## -0.5677806 0.01
## 0.1902622 0.01
## 0.1140009 0.01
## 0.04830294 0.01

16
22
20
18
OOB Error

16
14
12
10

1 2 4 8 13

mtry

## mtry OOBError
## 1 1 21.516848
## 2 2 13.724400
## 4 4 11.113166
## 8 8 9.846255
## 13 13 9.370652

El error de OOB es mínimo con 13 variables. Creamos nuestro modelo con las variables óptimas.

set.seed(123)
model_random_2 <- randomForest(medv ~ ., #Formula.
data = train_house, #Conjunto de entrenamiento.
ntree = 500, #Número de árboles.
mtry = 13, #Número predictores elegidos aleatoriamente
importance = TRUE) #Calculo de la importancia de cada variable
model_random_2

##
## Call:
## randomForest(formula = medv ~ ., data = train_house, ntree = 500, mtry = 13, importance = TRUE)
## Type of random forest: regression
## Number of trees: 500
## No. of variables tried at each split: 13
##
## Mean of squared residuals: 9.645644
## % Var explained: 88.66

17
La varianza explicada se ha incrementado con respecto al modelo inicial. Comprobamos el error en función
de los árboles.

plot(model_random_2)

model_random_2
20
18
16
Error

14
12
10

0 100 200 300 400 500

trees

Con el óptimo de variables mtry = 13 el error se estabiliza aproximadamente en 300 árboles. Buscamos el
mínimo.

#Obtenemos el error de OOB para cada uno de los árboles


model_random_2$mse

## [1] 19.189273 20.654708 16.048146 14.548861 13.786902 15.931200 17.271518


## [8] 16.311639 15.611429 13.382800 12.884020 12.359352 12.891450 13.384528
## [15] 12.682362 12.077771 11.893112 11.578910 11.623028 11.683614 11.444277
## [22] 11.679320 11.428557 10.986236 11.078504 11.188399 10.903115 11.106258
## [29] 10.927103 11.174204 11.142955 11.298600 11.105976 11.231833 11.110160
## [36] 11.063927 11.190438 11.372075 11.388493 11.365828 11.581260 11.571200
## [43] 11.525189 11.395894 11.301617 11.354820 11.286660 11.322432 11.235607
## [50] 11.388408 11.382410 11.414143 11.372163 11.326715 11.373884 11.383333
## [57] 11.346927 11.270455 11.126617 11.182855 11.093286 11.067626 11.068640
## [64] 10.987295 11.031658 11.116309 11.139265 11.027536 11.042498 11.031957
## [71] 10.988185 11.004361 11.005691 10.970352 10.901567 10.881102 10.725027
## [78] 10.740946 10.718871 10.615814 10.628817 10.671138 10.673974 10.535109
## [85] 10.475618 10.565214 10.628492 10.693465 10.716083 10.741710 10.676927
## [92] 10.686778 10.749981 10.735202 10.750893 10.701192 10.700721 10.613943
## [99] 10.571512 10.563564 10.458639 10.496995 10.507117 10.518471 10.546015

18
## [106] 10.535995 10.517744 10.454158 10.477301 10.473686 10.512463 10.501394
## [113] 10.517423 10.509940 10.499833 10.499495 10.516793 10.575282 10.632895
## [120] 10.631284 10.636115 10.583239 10.532387 10.502325 10.507064 10.471751
## [127] 10.460281 10.463511 10.422441 10.406874 10.344841 10.360697 10.297996
## [134] 10.338551 10.317708 10.423165 10.372248 10.344523 10.352118 10.368975
## [141] 10.326531 10.330662 10.313735 10.303345 10.275764 10.307695 10.276756
## [148] 10.267286 10.248177 10.237881 10.241199 10.242356 10.242318 10.196168
## [155] 10.208961 10.180312 10.141706 10.153664 10.181512 10.200457 10.171844
## [162] 10.159700 10.145375 10.142022 10.081236 10.051059 10.031369 10.000928
## [169] 9.975130 9.950535 9.913156 9.943505 9.993993 9.973278 9.990210
## [176] 9.997526 9.980812 9.973031 9.946072 9.915233 9.908680 9.880781
## [183] 9.872560 9.893628 9.860905 9.851544 9.802638 9.773026 9.743244
## [190] 9.711674 9.702361 9.725380 9.710230 9.744808 9.788131 9.801992
## [197] 9.811543 9.834187 9.840875 9.830505 9.830268 9.828822 9.821627
## [204] 9.819719 9.785760 9.763372 9.784959 9.760149 9.793150 9.782022
## [211] 9.748005 9.761391 9.771464 9.760008 9.791148 9.818477 9.815372
## [218] 9.838771 9.847020 9.813044 9.828861 9.826618 9.812170 9.803019
## [225] 9.794500 9.768198 9.766962 9.766412 9.795714 9.784599 9.806575
## [232] 9.806677 9.820239 9.833863 9.848529 9.865868 9.866821 9.850049
## [239] 9.880254 9.888107 9.920367 9.931812 9.923784 9.928158 9.922011
## [246] 9.942450 9.950347 9.937336 9.919378 9.958561 9.945796 9.934685
## [253] 9.934714 9.919036 9.924952 9.925716 9.923029 9.916695 9.916137
## [260] 9.931406 9.935059 9.928419 9.930418 9.957187 9.941531 9.938523
## [267] 9.929896 9.928629 9.909707 9.884132 9.897819 9.900221 9.913247
## [274] 9.891742 9.916962 9.899528 9.890205 9.893793 9.913483 9.930554
## [281] 9.942606 9.957545 9.946817 9.930840 9.923876 9.910735 9.890890
## [288] 9.897650 9.879022 9.884084 9.889067 9.886596 9.895726 9.900435
## [295] 9.882693 9.875511 9.869443 9.854507 9.859872 9.892791 9.903939
## [302] 9.907444 9.898653 9.898199 9.869460 9.832908 9.844375 9.854126
## [309] 9.845664 9.875382 9.876027 9.867421 9.851654 9.844063 9.851923
## [316] 9.844449 9.842656 9.827431 9.811131 9.814751 9.812108 9.792956
## [323] 9.783116 9.778174 9.769390 9.759730 9.771865 9.764224 9.779168
## [330] 9.793199 9.783614 9.780290 9.787718 9.783947 9.782750 9.781873
## [337] 9.805151 9.794428 9.783297 9.760536 9.747902 9.742411 9.749233
## [344] 9.743751 9.752893 9.740999 9.744860 9.742497 9.742579 9.746176
## [351] 9.738108 9.744324 9.755610 9.772880 9.772541 9.765055 9.777095
## [358] 9.762231 9.752260 9.756107 9.722929 9.719952 9.722010 9.724900
## [365] 9.720183 9.710613 9.724989 9.731665 9.737838 9.735678 9.712006
## [372] 9.707442 9.705609 9.716513 9.713573 9.710332 9.720987 9.724838
## [379] 9.734186 9.736097 9.737860 9.735490 9.741870 9.738350 9.744345
## [386] 9.755369 9.766160 9.780204 9.778562 9.761369 9.756947 9.758303
## [393] 9.752703 9.745286 9.746535 9.740141 9.733864 9.733592 9.742779
## [400] 9.734415 9.731436 9.727791 9.720434 9.705199 9.703970 9.712368
## [407] 9.709954 9.715881 9.732924 9.735791 9.764745 9.753667 9.742767
## [414] 9.744917 9.732356 9.731394 9.736319 9.733356 9.733120 9.736521
## [421] 9.739653 9.723374 9.716834 9.715205 9.705921 9.712427 9.712733
## [428] 9.709763 9.700650 9.717662 9.717326 9.708778 9.703152 9.711760
## [435] 9.721270 9.708835 9.707529 9.707277 9.699039 9.698223 9.711588
## [442] 9.703481 9.693735 9.689248 9.693065 9.693946 9.690689 9.682133
## [449] 9.686308 9.684831 9.666035 9.653241 9.646994 9.634656 9.630157
## [456] 9.636125 9.629435 9.626992 9.628336 9.635265 9.638373 9.637127
## [463] 9.621067 9.622169 9.618504 9.627914 9.625295 9.626203 9.629480
## [470] 9.634431 9.645307 9.664689 9.665558 9.660694 9.665207 9.659802
## [477] 9.652951 9.654192 9.665067 9.662461 9.656223 9.649137 9.665775

19
## [484] 9.656073 9.657471 9.658318 9.652995 9.644449 9.643244 9.642529
## [491] 9.642159 9.640948 9.643831 9.648336 9.643274 9.636786 9.640734
## [498] 9.657655 9.652868 9.645644

#Selecionamos el óptimo de árboles.


(min_2 <- which.min(model_random_2$mse))

## [1] 465

Obtenemos el RMSE del modelo con 465 árboles.

(rmse_min_2 <- sqrt(model_random_2$mse[which.min(model_random_2$mse)]))

## [1] 3.101371

Nuestro error inicial de OOB ha pasado de 3.2688503 a 3.1013712 con las variaciones de variables y árboles
óptimos.
Le pedimos que nos muestre las variables más importantes por medio de la función varImpPlot(), que calcula
para cada variable cuanto reduce el MSE (Error cuadrático medio) del modelo, donde valores mayores del
%IncMSE son mejores.

varImpPlot(model_random_2, type = 1)

model_random_2

rm
lstat
dis
nox
ptratio
age
crim
tax
indus
black
rad
zn
chas

0 10 20 30 40 50

%IncMSE

Como podemos ver, que la variable más importante es rm, que reduce más del 40% del error residual.

20
Creamos nuestro modelo con 13 variables y modificamos los árboles a 465. Después predecimos sobre el
conjunto de datos de validación.

set.seed(123)
model_random_3 <- randomForest(medv ~ .,
data = train_house,
ntree = min_2,
mtry = 13)
model_random_3

##
## Call:
## randomForest(formula = medv ~ ., data = train_house, ntree = min_2, mtry = 13)
## Type of random forest: regression
## Number of trees: 465
## No. of variables tried at each split: 13
##
## Mean of squared residuals: 9.804759
## % Var explained: 88.47

La varianza explicada y el error OOB se han mantenido en este caso muy similar. Predecimos con nuestro
modelo en nuestro conjunto de validación.

predict_random <- predict(model_random_3, newdata = test_house)


(sqrt(mean((predict_random-test_house$medv)^2)))

## [1] 3.53384

Uno de las desventajas de los modelos de Random Forest y Bagging es que son muy difíciles de representar.
Podemos realizar un gráfico de dependencia parcial que nos indica como varía cada variable independiente
con respecto a nuestra variable respuesta y que podemos ver como se relacionan ambas variables.

Var_indep <- c("crim","zn","indus","chas","nox","rm",


"age","dis","rad","tax","ptratio","black","lstat")
for(i in 1:length(Var_indep)){
partialPlot(model_random_3, x.var = Var_indep[i], pred.data = test_house,
main = paste("medv ~",Var_indep[i]),
xlab = Var_indep[i], ylab = "medv" )
}

21
medv ~ crim
24.4
24.2
medv

24.0
23.8

0 20 40 60

crim

22
medv

23.455 23.465 23.475 23.485

0
20
40

23
zn
medv ~ zn

60
80
medv ~ indus
23.8
medv

23.6
23.4

5 10 15 20 25

indus

24
medv ~ chas
23.54
medv

23.50
23.46

0.0 0.2 0.4 0.6 0.8 1.0

chas

25
medv ~ nox
24.0
23.6
medv

23.2
22.8

0.4 0.5 0.6 0.7 0.8

nox

26
medv ~ rm
35
30
medv

25
20

5.5 6.0 6.5 7.0 7.5 8.0 8.5

rm

27
medv ~ age
23.8
23.6
medv

23.4
23.2

20 40 60 80 100

age

28
medv ~ dis
27
26
medv

25
24

2 4 6 8 10

dis

29
medv ~ rad
23.7
23.5
medv

23.3
23.1

5 10 15 20

rad

30
medv ~ tax
25.5
25.0
24.5
medv

24.0
23.5

200 300 400 500 600

tax

31
medv ~ ptratio
24.0
23.6
medv

23.2
22.8

14 16 18 20 22

ptratio

32
medv ~ black
23.6
23.4
medv

23.2
23.0

100 200 300 400

black

33
medv ~ lstat
30
28
26
medv

24
22
20

5 10 15 20 25 30

lstat

Como vemos las relaciones entre las variables independientes y la dependiente no son lineales, y por tanto
es más adecuado utilizar este tipo de modelos que las regresiones lineales.

3.6. Random Forest de clasificación: Librería ranger.

En R hay varios paquetes que incluyen el algoritmo de random forest, cuyo paquete más antiguo y conocido
es randomForest, con el cual hemos visto un ejemplo de regresión. El problema que tiene esta librería es que
según aumenta el tamaño, el procesamiento de los datos se hace muy lento. Para solucionar este problema
podemos utilizar el paquete ranger, el cual se estima que es 6 veces más rápido.
Para poder comparar con los anteriores métodos vamos a utilizar el mismo dataset de churn, para clasificar
clientes de una compañía de telecomunicaciones que abandonan o no la compañía. Realizamos el modelo
directamente ya que los datos los tenemos cargados en nuestro espacio de trabajo.

library(ranger)
set.seed(123)
model_ranger_1 <- ranger(churn~., #Formula.
data = churnTrain, #Datos de entrenamiento.
num.trees = 500, #Número de árboles.
mtry = sqrt(19), #Número de variables a utilizar.
importance = "impurity" )

model_ranger_1

## Ranger result

34
##
## Call:
## ranger(churn ~ ., data = churnTrain, num.trees = 500, mtry = sqrt(19), importance = "impurity")
##
## Type: Classification
## Number of trees: 500
## Sample size: 3333
## Number of independent variables: 19
## Mtry: 4
## Target node size: 1
## Variable importance mode: impurity
## Splitrule: gini
## OOB prediction error: 4.74 %

Como vemos, el modelo nos indica el error de predicción (OOB), el número de variables tanto independientes,
método de división de los nodos y cálculo de importancia de las variables.
Obtenemos las variables más importantes al añadir el parámetro al modelo importance = “impurity”, que
nos indica las variables que reducen la impureza del nodo, es decir, la variable que más reduce el MSE se
considera más importante.

importance(model_ranger_1)

## state account_length
## 19.656033 24.386257
## area_code international_plan
## 6.219624 66.912667
## voice_mail_plan number_vmail_messages
## 18.764154 23.271507
## total_day_minutes total_day_calls
## 112.138702 25.297557
## total_day_charge total_eve_minutes
## 114.912695 52.399039
## total_eve_calls total_eve_charge
## 21.580369 52.640699
## total_night_minutes total_night_calls
## 28.864131 23.918752
## total_night_charge total_intl_minutes
## 29.198996 33.915965
## total_intl_calls total_intl_charge
## 41.416569 33.503036
## number_customer_service_calls
## 97.518807

Predecimos con nuestro modelo.

#Predecimos con el modelo.


predict_ranger <- predict(model_ranger_1, data = churnTest)
confusionMatrix(predict_ranger$predictions, churnTest$churn)

## Confusion Matrix and Statistics


##
## Reference

35
## Prediction no yes
## no 1440 58
## yes 3 166
##
## Accuracy : 0.9634
## 95% CI : (0.9532, 0.9719)
## No Information Rate : 0.8656
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.8245
##
## Mcnemar's Test P-Value : 0.000000000004712
##
## Sensitivity : 0.9979
## Specificity : 0.7411
## Pos Pred Value : 0.9613
## Neg Pred Value : 0.9822
## Prevalence : 0.8656
## Detection Rate : 0.8638
## Detection Prevalence : 0.8986
## Balanced Accuracy : 0.8695
##
## 'Positive' Class : no
##

Nuestro modelo con los datos de validación consigue clasificar correctamente el 96% de los clientes.

3.7. Grid Search: Selección de Hiperparámetros.

Como en los modelos de árboles individuales podemos utilizar la librería e1071, para encontrar los mejores
parámetros para nuestros modelos de bagging. En este caso utilizamos la función tune.randomForest() que
nos permitirá seleccionar los mejores hiperparámetros para los modelos de bagging y randomForest.
Realizamos con los datos de churn, una búsqueda de los mejores parámetros para el algoritmo de random-
Forest en el que buscamos el número de variables, el número de árboles óptimo y el tamaño mínimo del
nodo. Las opciones que damos a cada uno de los parámetros se eligen por prueba y error.
Como comentamos en el tema anterior, hay que tener cuidado porque el coste computacional de crear los
distintos modelos es alto.

#Cargamos la librería.
library(e1071)

## Warning: package 'e1071' was built under R version 3.6.3

set.seed(123)
#Realizamos modelo con las distintas posibilidades.
model_tune_churn_ran <- tune.randomForest(churn~.,
data = churnTrain,
mtry = c(5,7,10), #Número de variables
ntree = c(100,150), #Número de árboles.
nodesize = c(100,200)) #Tamaño mínimo del nodo
model_tune_churn_ran

36
##
## Parameter tuning of 'randomForest':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## nodesize mtry ntree
## 100 10 150
##
## - best performance: 0.06841452

Con los parámetros que le hemos indicado, el modelo identifica que los mejores son 10 variables, con 150
árboles y con un tamaño mínimo de 100 observaciones por nodo. Si queremos ver más detalladamente los
modelos que ha realizado podemos solicitarlo con la función summary()

summary(model_tune_churn_ran)

##
## Parameter tuning of 'randomForest':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## nodesize mtry ntree
## 100 10 150
##
## - best performance: 0.06841452
##
## - Detailed performance results:
## nodesize mtry ntree error dispersion
## 1 100 5 100 0.09302027 0.02666691
## 2 200 5 100 0.13322184 0.02265244
## 3 100 7 100 0.07831994 0.02138750
## 4 200 7 100 0.13172574 0.02578207
## 5 100 10 100 0.06901063 0.01757936
## 6 200 10 100 0.13892845 0.02703225
## 7 100 5 150 0.09301847 0.02290354
## 8 200 5 150 0.13142454 0.02754582
## 9 100 7 150 0.08012084 0.02215167
## 10 200 7 150 0.13563054 0.03040824
## 11 100 10 150 0.06841452 0.01752552
## 12 200 10 150 0.14012426 0.02309704

Por medio del mismo método que hemos utilizado para obtener los hiperparámetros de los modelos random-
Forest, podemos buscar para el modelo de bagging, solo tenemos que igualar mtry=19, es decir al total de
las variables predictoras.

set.seed(123)
#Realizamos modelo con las distintas posibilidades.
model_tune_churn_bagg <- tune.randomForest(churn~.,
data = churnTrain,
mtry = 19, #Número de variables
ntree = c(100,150,200), #Número de árboles.

37
nodesize = c(100,200,300)) #Tamaño mínimo del nodo
model_tune_churn_bagg

##
## Parameter tuning of 'randomForest':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## nodesize mtry ntree
## 100 19 100
##
## - best performance: 0.06691032

Obtenemos que para mtry= 19, lo mejores hiperparámetros son 100 árboles y con un nodo mínimo de 100
observaciones.
Vemos que el error en bagging es de 0.0669103 y el error del randomForest era de 0.0684145.

38
4. Modelos de Bagging: Librería H2o
La librería H2o nos permite realizar modelos de Machine Learning de forma distribuida, lo que nos permite
optimizar los recursos del ordenador o del clúster en el que trabajemos, disminuyendo el tiempo de ejecución.
La librería H2o está escrita en Java pero se puede utilizar con lenguajes como R, Python y Scala. Una de las
ventajas que tiene es la rapidez con la que trabaja con grandes volúmenes de datos que le da ventaja sobre
otras librerías.
Aunque la misma librería nos daría para hacer un curso entero sobre ella, vamos a desarrollar los conceptos
necesarios para implementar un modelo de random forest y bagging distribuido. Lo primero que vamos a
hacer es instalar la librería, cargarla e iniciar el clúster.

#install.packages("h2o")
library(h2o)

##
## ----------------------------------------------------------------------
##
## Your next step is to start H2O:
## > h2o.init()
##
## For H2O package documentation, ask for help:
## > ??h2o
##
## After starting H2O, you can use the Web UI at http://localhost:54321
## For more information visit https://docs.h2o.ai
##
## ----------------------------------------------------------------------

##
## Attaching package: 'h2o'

## The following objects are masked from 'package:stats':


##
## cor, sd, var

## The following objects are masked from 'package:base':


##
## %*%, %in%, &&, ||, apply, as.factor, as.numeric, colnames,
## colnames<-, ifelse, is.character, is.factor, is.numeric, log,
## log10, log1p, log2, round, signif, trunc

h2o.init(nthreads = -1)

##
## H2O is not running yet, starting it now...
##
## Note: In case of errors look at the following log files:
## C:\Users\miste\AppData\Local\Temp\Rtmp2DtrB1\file189d06a8f5bf3/h2o_miste_started_from_r.out
## C:\Users\miste\AppData\Local\Temp\Rtmp2DtrB1\file189d0161e3564/h2o_miste_started_from_r.err
##
##

39
## Starting H2O JVM and connecting: ... Connection successful!
##
## R is connected to the H2O cluster:
## H2O cluster uptime: 23 seconds 253 milliseconds
## H2O cluster timezone: Europe/Paris
## H2O data parsing timezone: UTC
## H2O cluster version: 3.32.0.1
## H2O cluster version age: 2 months and 17 days
## H2O cluster name: H2O_started_from_R_miste_vds138
## H2O cluster total nodes: 1
## H2O cluster total memory: 3.31 GB
## H2O cluster total cores: 4
## H2O cluster allowed cores: 4
## H2O cluster healthy: TRUE
## H2O Connection ip: localhost
## H2O Connection port: 54321
## H2O Connection proxy: NA
## H2O Internal Security: FALSE
## H2O API Extensions: Amazon S3, Algos, AutoML, Core V3, TargetEncoder, Core V4
## R Version: R version 3.6.1 (2019-07-05)

h2o.no_progress()

Con el parámetro nthreads=-1 le indicamos que inicie el clúster con todos los cores disponibles, que en este
caso son 4. Nos indica el tiempo que lleva el clúster activado, la versión de la librería y de R, el número
de nodos, y la posibilidad de conectarnos a la interfaz gráfica en el puerto 54321 y desde donde podemos
realizar los algoritmos sin necesidad de programar. Con la función h2o.no_progress() le indicamos que no
nos muestre el progreso al entrenar los distintos algoritmos.

4.1. Parámetros generales modelos H2o.

Cuando construimos un modelo con la librería H2o, podemos indicarle una serie de parámetros comunes que
nos servirán tanto para el modelo de Random Forest Distribuido como los restantes modelos que nos permite
realizar la librería: Cox Proportional Hazards (CoxPH), Deep Learning (Neural Networks), Generalized
Linear Model (GLM), Gradient Boosting Machine (GBM), Naïve Bayes Classifier, Stacked Ensembles y
XGBoost.
Los parámetros principales que podemos definir y que luego veremos con más detalle son:

• stopping_metric: Métricas del modelo.


• nfolds: Número de repeticiones de validación cruzada.
• balance_classes: Si los datos no están balanceados y hay una clase con pocos datos.
• ignore_const_cols: Elimina aquellas columnas para las que sus valores son iguales.
• categorical_encoding: Por defecto se transformas las variables categóricas en dummys.

Hay más de 20 parámetros generales que se pueden consultar en la documentación oficial de la librería H2o

4.2. Parámetros generales modelo Random Forest Distribuido.

Además de los parámetros comunes que podemos aplicar a la mayoría de los modelos que se realizan con la
librería H2o, el modelo de Random Forest Distribuido tiene los suyos propios. Algunos de esto parámetros
son comunes a los utilizados con la librería randomForest.

40
• ntrees: Número de árboles.
• max_depth: Profundidad de los árboles.
• mtries: Número de variables a considerar. Recuerda que para problemas de clasificación es igual a

m = p y para problemas de regresión m = p3 . Si m = p estaríamos realizando un modelo de bagging.
• min_rows: Número de observaciones en la hoja para que se pueda dividir.
• sample_rate: indica que cada árbol está entrenado con el 63.2% de los datos de entrenamiento. Por
defecto es 0.632.
• min_split_improvement: Controla el mínimo error que se reduce para que se divida el nodo.

4.3. Caso de estudio: Home Credit Default Risk

Utilizamos el dataset de que se encuentra en la página de Kaggle de Home Credit Default Risk, en el que se
nos solicita realizar un modelo para predecir si nos devolverán un préstamo o no (variable objetivo:TARGET),
en función de una serie de variables, para poner en práctica nuestro modelo de Random Forest Distribuido.
Sólo vamos a utilizar 10.000 observaciones del dataset original.
Cargamos los datos directamente en el clúster h2o y obtenemos las dimensiones del dataset, para ello uti-
lizamos la función h2o.importFile donde le indicamos la ruta donde se encuentran los datos.

#Carga de datos.
homeCredit <- h2o.importFile("Datasets/Home.csv",
header = T)
h2o.dim(homeCredit)

## [1] 10000 121

Hemos cargado 10.000 observaciones con 121 columnas mucho más rápido que si lo hubiéramos hecho con la
función read.csv() y además, tenemos ya cargados los datos en nuestro clúster local.
Realizamos una primera exploración de los datos.

#Estadísticos básicos.
h2o.describe(homeCredit)

## Label Type Missing Zeros PosInf NegInf


## 1 TARGET int 0 9225 0 0
## 2 NAME_CONTRACT_TYPE enum 0 9005 0 0
## 3 CODE_GENDER enum 0 6589 0 0
## 4 FLAG_OWN_CAR enum 0 6662 0 0
## 5 FLAG_OWN_REALTY enum 0 3025 0 0
## 6 CNT_CHILDREN int 0 7006 0 0
## 7 AMT_INCOME_TOTAL real 4 0 0 0
## 8 AMT_CREDIT real 204 0 0 0
## 9 AMT_ANNUITY real 0 0 0 0
## 10 AMT_GOODS_PRICE real 510 0 0 0
## 11 NAME_TYPE_SUITE enum 41 107 0 0
## 12 NAME_INCOME_TYPE enum 0 2304 0 0
## 13 NAME_EDUCATION_TYPE enum 0 8 0 0
## 14 NAME_FAMILY_STATUS enum 0 931 0 0
## 15 NAME_HOUSING_TYPE enum 0 46 0 0
## 16 REGION_POPULATION_RELATIVE real 0 0 0 0
## 17 DAYS_BIRTH int 0 0 0 0
## 18 DAYS_EMPLOYED int 0 0 0 0

41
## 19 DAYS_REGISTRATION int 0 1 0 0
## 20 DAYS_ID_PUBLISH int 0 1 0 0
## 21 OWN_CAR_AGE int 6662 73 0 0
## 22 FLAG_MOBIL int 0 0 0 0
## 23 FLAG_EMP_PHONE int 0 1775 0 0
## 24 FLAG_WORK_PHONE int 0 7987 0 0
## 25 FLAG_CONT_MOBILE int 0 18 0 0
## 26 FLAG_PHONE int 0 7179 0 0
## 27 FLAG_EMAIL int 0 9455 0 0
## 28 OCCUPATION_TYPE enum 3089 327 0 0
## 29 CNT_FAM_MEMBERS int 0 0 0 0
## 30 REGION_RATING_CLIENT int 0 0 0 0
## 31 REGION_RATING_CLIENT_W_CITY int 0 0 0 0
## 32 WEEKDAY_APPR_PROCESS_START enum 0 1640 0 0
## 33 HOUR_APPR_PROCESS_START int 0 0 0 0
## 34 REG_REGION_NOT_LIVE_REGION int 0 9836 0 0
## 35 REG_REGION_NOT_WORK_REGION int 0 9506 0 0
## 36 LIVE_REGION_NOT_WORK_REGION int 0 9619 0 0
## 37 REG_CITY_NOT_LIVE_CITY int 0 9196 0 0
## 38 REG_CITY_NOT_WORK_CITY int 0 7646 0 0
## 39 LIVE_CITY_NOT_WORK_CITY int 0 8197 0 0
## 40 ORGANIZATION_TYPE enum 0 13 0 0
## 41 EXT_SOURCE_1 real 5647 0 0 0
## 42 EXT_SOURCE_2 real 27 0 0 0
## 43 EXT_SOURCE_3 real 1995 0 0 0
## 44 APARTMENTS_AVG real 5065 21 0 0
## 45 BASEMENTAREA_AVG enum 0 462 0 0
## 46 YEARS_BEGINEXPLUATATION_AVG real 4880 9 0 0
## 47 YEARS_BUILD_AVG real 6640 1 0 0
## 48 COMMONAREA_AVG enum 0 288 0 0
## 49 ELEVATORS_AVG real 5309 2850 0 0
## 50 ENTRANCES_AVG real 5006 15 0 0
## 51 FLOORSMAX_AVG real 4943 98 0 0
## 52 FLOORSMIN_AVG real 6795 68 0 0
## 53 LANDAREA_AVG enum 0 507 0 0
## 54 LIVINGAPARTMENTS_AVG enum 0 14 0 0
## 55 LIVINGAREA_AVG enum 0 7 0 0
## 56 NONLIVINGAPARTMENTS_AVG enum 0 1798 0 0
## 57 NONLIVINGAREA_AVG enum 0 1900 0 0
## 58 APARTMENTS_MODE real 5065 29 0 0
## 59 BASEMENTAREA_MODE enum 0 524 0 0
## 60 YEARS_BEGINEXPLUATATION_MODE real 4892 5 0 0
## 61 YEARS_BUILD_MODE real 6640 2 0 0
## 62 COMMONAREA_MODE enum 0 336 0 0
## 63 ELEVATORS_MODE real 5309 2979 0 0
## 64 ENTRANCES_MODE real 5006 15 0 0
## 65 FLOORSMAX_MODE real 4943 110 0 0
## 66 FLOORSMIN_MODE real 6795 75 0 0
## 67 LANDAREA_MODE enum 0 560 0 0
## 68 LIVINGAPARTMENTS_MODE enum 0 17 0 0
## 69 LIVINGAREA_MODE enum 0 16 0 0
## 70 NONLIVINGAPARTMENTS_MODE real 6942 1965 0 0
## 71 NONLIVINGAREA_MODE enum 0 2173 0 0
## 72 APARTMENTS_MEDI real 5065 22 0 0

42
## 73 BASEMENTAREA_MEDI enum 0 474 0 0
## 74 YEARS_BEGINEXPLUATATION_MEDI real 4880 11 0 0
## 75 YEARS_BUILD_MEDI real 6640 2 0 0
## 76 COMMONAREA_MEDI enum 0 298 0 0
## 77 ELEVATORS_MEDI real 5309 2885 0 0
## 78 ENTRANCES_MEDI real 5006 15 0 0
## 79 FLOORSMAX_MEDI real 4943 99 0 0
## 80 FLOORSMIN_MEDI real 6795 69 0 0
## 81 LANDAREA_MEDI enum 0 516 0 0
## 82 LIVINGAPARTMENTS_MEDI enum 0 15 0 0
## 83 LIVINGAREA_MEDI enum 0 8 0 0
## 84 NONLIVINGAPARTMENTS_MEDI real 6942 1847 0 0
## 85 NONLIVINGAREA_MEDI enum 0 1973 0 0
## 86 FONDKAPREMONT_MODE enum 6857 172 0 0
## 87 HOUSETYPE_MODE enum 5005 4913 0 0
## 88 TOTALAREA_MODE real 4819 13 0 0
## 89 WALLSMATERIAL_MODE enum 5089 322 0 0
## 90 EMERGENCYSTATE_MODE enum 4725 5197 0 0
## 91 OBS_30_CNT_SOCIAL_CIRCLE int 42 5376 0 0
## 92 DEF_30_CNT_SOCIAL_CIRCLE int 42 8794 0 0
## 93 OBS_60_CNT_SOCIAL_CIRCLE int 42 5395 0 0
## 94 DEF_60_CNT_SOCIAL_CIRCLE int 42 9101 0 0
## 95 DAYS_LAST_PHONE_CHANGE int 0 1263 0 0
## 96 FLAG_DOCUMENT_2 int 0 10000 0 0
## 97 FLAG_DOCUMENT_3 int 0 2893 0 0
## 98 FLAG_DOCUMENT_4 int 0 9998 0 0
## 99 FLAG_DOCUMENT_5 int 0 9840 0 0
## 100 FLAG_DOCUMENT_6 int 0 9144 0 0
## 101 FLAG_DOCUMENT_7 int 0 10000 0 0
## 102 FLAG_DOCUMENT_8 int 0 9232 0 0
## 103 FLAG_DOCUMENT_9 int 0 9965 0 0
## 104 FLAG_DOCUMENT_10 int 0 10000 0 0
## 105 FLAG_DOCUMENT_11 int 0 9964 0 0
## 106 FLAG_DOCUMENT_12 int 0 10000 0 0
## 107 FLAG_DOCUMENT_13 int 0 9976 0 0
## 108 FLAG_DOCUMENT_14 int 0 9974 0 0
## 109 FLAG_DOCUMENT_15 int 0 9994 0 0
## 110 FLAG_DOCUMENT_16 int 0 9901 0 0
## 111 FLAG_DOCUMENT_17 int 0 9998 0 0
## 112 FLAG_DOCUMENT_18 int 0 9931 0 0
## 113 FLAG_DOCUMENT_19 int 0 9996 0 0
## 114 FLAG_DOCUMENT_20 int 0 9995 0 0
## 115 FLAG_DOCUMENT_21 int 0 9997 0 0
## 116 AMT_REQ_CREDIT_BUREAU_HOUR int 1366 8573 0 0
## 117 AMT_REQ_CREDIT_BUREAU_DAY int 1366 8579 0 0
## 118 AMT_REQ_CREDIT_BUREAU_WEEK int 1366 8368 0 0
## 119 AMT_REQ_CREDIT_BUREAU_MON int 1366 7184 0 0
## 120 AMT_REQ_CREDIT_BUREAU_QRT int 1366 6945 0 0
## 121 AMT_REQ_CREDIT_BUREAU_YEAR int 1366 2318 0 0
## Min Max Mean Sigma
## 1 0.0000000000 1.0000000 0.077500000 0.26739652
## 2 0.0000000000 1.0000000 0.099500000 0.29934714
## 3 0.0000000000 1.0000000 0.341100000 0.47410259
## 4 0.0000000000 1.0000000 0.333800000 0.47159283

43
## 5 0.0000000000 1.0000000 0.697500000 0.45936353
## 6 0.0000000000 7.0000000 0.416300000 0.72225098
## 7 25650.0000000000 1935000.0000000 167298.291716687 93645.67600037
## 8 45000.0000000000 2961000.0000000 594521.309105757 405098.97745567
## 9 2596.5000000000 135936.0000000 27088.010550000 14384.94615376
## 10 45000.0000000000 2961000.0000000 521324.353213910 370993.07913779
## 11 0.0000000000 6.0000000 NA NA
## 12 0.0000000000 4.0000000 NA NA
## 13 0.0000000000 4.0000000 NA NA
## 14 0.0000000000 4.0000000 NA NA
## 15 0.0000000000 5.0000000 NA NA
## 16 0.0009380000 0.0725080 0.020897881 0.01390888
## 17 -25160.0000000000 -7705.0000000 -16025.273100000 4340.52882757
## 18 -15632.0000000000 365243.0000000 62821.784800000 140464.31593960
## 19 -20981.0000000000 0.0000000 -4986.483900000 3540.59193145
## 20 -6228.0000000000 0.0000000 -2983.380800000 1512.51078028
## 21 0.0000000000 65.0000000 11.918514080 11.85267970
## 22 1.0000000000 1.0000000 1.000000000 0.00000000
## 23 0.0000000000 1.0000000 0.822500000 0.38211039
## 24 0.0000000000 1.0000000 0.201300000 0.40099176
## 25 0.0000000000 1.0000000 0.998200000 0.04239033
## 26 0.0000000000 1.0000000 0.282100000 0.45004427
## 27 0.0000000000 1.0000000 0.054500000 0.22701300
## 28 0.0000000000 17.0000000 NA NA
## 29 1.0000000000 9.0000000 2.156400000 0.90610217
## 30 1.0000000000 3.0000000 2.047200000 0.50990015
## 31 1.0000000000 3.0000000 2.026600000 0.50489398
## 32 0.0000000000 6.0000000 NA NA
## 33 1.0000000000 23.0000000 12.074600000 3.21851996
## 34 0.0000000000 1.0000000 0.016400000 0.12701438
## 35 0.0000000000 1.0000000 0.049400000 0.21671257
## 36 0.0000000000 1.0000000 0.038100000 0.19144726
## 37 0.0000000000 1.0000000 0.080400000 0.27192505
## 38 0.0000000000 1.0000000 0.235400000 0.42426977
## 39 0.0000000000 1.0000000 0.180300000 0.38445636
## 40 0.0000000000 57.0000000 NA NA
## 41 0.0244174741 0.9293940 0.504267657 0.20981840
## 42 0.0002555764 0.8549997 0.515560288 0.18946116
## 43 0.0005272652 0.8854884 0.511553920 0.19643882
## 44 0.0000000000 1.0000000 0.117371185 0.10755907
## 45 0.0000000000 1678.0000000 NA NA
## 46 0.0000000000 1.0000000 0.979008145 0.04642944
## 47 0.0000000000 1.0000000 0.751310119 0.11284289
## 48 0.0000000000 1044.0000000 NA NA
## 49 0.0000000000 1.0000000 0.077176124 0.13357656
## 50 0.0000000000 1.0000000 0.150640489 0.10055829
## 51 0.0000000000 1.0000000 0.225850089 0.14691816
## 52 0.0000000000 1.0000000 0.231931669 0.16063294
## 53 0.0000000000 1509.0000000 NA NA
## 54 0.0000000000 582.0000000 NA NA
## 55 0.0000000000 2112.0000000 NA NA
## 56 0.0000000000 101.0000000 NA NA
## 57 0.0000000000 1003.0000000 NA NA
## 58 0.0000000000 1.0000000 0.113656717 0.10620728

44
## 59 0.0000000000 1656.0000000 NA NA
## 60 0.0000000000 1.0000000 0.980287040 0.03188784
## 61 0.0000000000 1.0000000 0.757949464 0.11059793
## 62 0.0000000000 1014.0000000 NA NA
## 63 0.0000000000 1.0000000 0.072631528 0.13040010
## 64 0.0000000000 1.0000000 0.146033000 0.10113894
## 65 0.0000000000 1.0000000 0.221740063 0.14590384
## 66 0.0000000000 1.0000000 0.227933697 0.16049311
## 67 0.0000000000 1483.0000000 NA NA
## 68 0.0000000000 394.0000000 NA NA
## 69 0.0000000000 2084.0000000 NA NA
## 70 0.0000000000 1.0000000 0.007741759 0.04467898
## 71 0.0000000000 965.0000000 NA NA
## 72 0.0000000000 1.0000000 0.118077508 0.10881313
## 73 0.0000000000 1675.0000000 NA NA
## 74 0.0000000000 1.0000000 0.979013809 0.04819329
## 75 0.0000000000 1.0000000 0.754662560 0.11196338
## 76 0.0000000000 1040.0000000 NA NA
## 77 0.0000000000 1.0000000 0.076810915 0.13405811
## 78 0.0000000000 1.0000000 0.150379055 0.10088353
## 79 0.0000000000 1.0000000 0.225550307 0.14735506
## 80 0.0000000000 1.0000000 0.231775445 0.16114780
## 81 0.0000000000 1509.0000000 NA NA
## 82 0.0000000000 491.0000000 NA NA
## 83 0.0000000000 2141.0000000 NA NA
## 84 0.0000000000 1.0000000 0.008350327 0.04526635
## 85 0.0000000000 1011.0000000 NA NA
## 86 0.0000000000 3.0000000 NA NA
## 87 0.0000000000 2.0000000 NA NA
## 88 0.0000000000 1.0000000 0.101662903 0.10559520
## 89 0.0000000000 6.0000000 NA NA
## 90 0.0000000000 1.0000000 0.014786730 0.12070975
## 91 0.0000000000 25.0000000 1.409821249 2.27995707
## 92 0.0000000000 5.0000000 0.149025909 0.45383943
## 93 0.0000000000 25.0000000 1.394456718 2.25982670
## 94 0.0000000000 5.0000000 0.104438642 0.37247140
## 95 -3882.0000000000 0.0000000 -960.207000000 826.77776814
## 96 0.0000000000 0.0000000 0.000000000 0.00000000
## 97 0.0000000000 1.0000000 0.710700000 0.45346011
## 98 0.0000000000 1.0000000 0.000200000 0.01414143
## 99 0.0000000000 1.0000000 0.016000000 0.12548137
## 100 0.0000000000 1.0000000 0.085600000 0.27978647
## 101 0.0000000000 0.0000000 0.000000000 0.00000000
## 102 0.0000000000 1.0000000 0.076800000 0.26628716
## 103 0.0000000000 1.0000000 0.003500000 0.05906013
## 104 0.0000000000 0.0000000 0.000000000 0.00000000
## 105 0.0000000000 1.0000000 0.003600000 0.05989490
## 106 0.0000000000 0.0000000 0.000000000 0.00000000
## 107 0.0000000000 1.0000000 0.002400000 0.04893342
## 108 0.0000000000 1.0000000 0.002600000 0.05092641
## 109 0.0000000000 1.0000000 0.000600000 0.02448877
## 110 0.0000000000 1.0000000 0.009900000 0.09900995
## 111 0.0000000000 1.0000000 0.000200000 0.01414143
## 112 0.0000000000 1.0000000 0.006900000 0.08278330

45
## 113 0.0000000000 1.0000000 0.000400000 0.01999700
## 114 0.0000000000 1.0000000 0.000500000 0.02235621
## 115 0.0000000000 1.0000000 0.000300000 0.01731878
## 116 0.0000000000 2.0000000 0.007296734 0.08779333
## 117 0.0000000000 4.0000000 0.008107482 0.11761978
## 118 0.0000000000 4.0000000 0.032893213 0.19332614
## 119 0.0000000000 16.0000000 0.274611999 0.92633172
## 120 0.0000000000 8.0000000 0.269747510 0.61495683
## 121 0.0000000000 13.0000000 1.889738244 1.85701780
## Cardinality
## 1 NA
## 2 2
## 3 2
## 4 2
## 5 2
## 6 NA
## 7 NA
## 8 NA
## 9 NA
## 10 NA
## 11 7
## 12 5
## 13 5
## 14 5
## 15 6
## 16 NA
## 17 NA
## 18 NA
## 19 NA
## 20 NA
## 21 NA
## 22 NA
## 23 NA
## 24 NA
## 25 NA
## 26 NA
## 27 NA
## 28 18
## 29 NA
## 30 NA
## 31 NA
## 32 7
## 33 NA
## 34 NA
## 35 NA
## 36 NA
## 37 NA
## 38 NA
## 39 NA
## 40 58
## 41 NA
## 42 NA
## 43 NA
## 44 NA

46
## 45 1679
## 46 NA
## 47 NA
## 48 1045
## 49 NA
## 50 NA
## 51 NA
## 52 NA
## 53 1510
## 54 583
## 55 2113
## 56 102
## 57 1004
## 58 NA
## 59 1657
## 60 NA
## 61 NA
## 62 1015
## 63 NA
## 64 NA
## 65 NA
## 66 NA
## 67 1484
## 68 395
## 69 2085
## 70 NA
## 71 966
## 72 NA
## 73 1676
## 74 NA
## 75 NA
## 76 1041
## 77 NA
## 78 NA
## 79 NA
## 80 NA
## 81 1510
## 82 492
## 83 2142
## 84 NA
## 85 1012
## 86 4
## 87 3
## 88 NA
## 89 7
## 90 2
## 91 NA
## 92 NA
## 93 NA
## 94 NA
## 95 NA
## 96 NA
## 97 NA
## 98 NA

47
## 99 NA
## 100 NA
## 101 NA
## 102 NA
## 103 NA
## 104 NA
## 105 NA
## 106 NA
## 107 NA
## 108 NA
## 109 NA
## 110 NA
## 111 NA
## 112 NA
## 113 NA
## 114 NA
## 115 NA
## 116 NA
## 117 NA
## 118 NA
## 119 NA
## 120 NA
## 121 NA

#Cinco primeras observaciones.


h2o.head(homeCredit,5)

## TARGET NAME_CONTRACT_TYPE CODE_GENDER FLAG_OWN_CAR FLAG_OWN_REALTY


## 1 1 Cash loans M N Y
## 2 0 Cash loans F N N
## 3 0 Revolving loans M Y Y
## 4 0 Cash loans F N Y
## 5 0 Cash loans M N Y
## CNT_CHILDREN AMT_INCOME_TOTAL AMT_CREDIT AMT_ANNUITY AMT_GOODS_PRICE
## 1 0 202500 406597.5 24700.5 351000
## 2 0 270000 1293502.5 35698.5 1129500
## 3 0 67500 135000.0 6750.0 135000
## 4 0 135000 312682.5 29686.5 297000
## 5 0 121500 513000.0 21865.5 513000
## NAME_TYPE_SUITE NAME_INCOME_TYPE NAME_EDUCATION_TYPE
## 1 Unaccompanied Working Secondary / secondary special
## 2 Family State servant Higher education
## 3 Unaccompanied Working Secondary / secondary special
## 4 Unaccompanied Working Secondary / secondary special
## 5 Unaccompanied Working Secondary / secondary special
## NAME_FAMILY_STATUS NAME_HOUSING_TYPE REGION_POPULATION_RELATIVE DAYS_BIRTH
## 1 Single / not married House / apartment 0.018801 -9461
## 2 Married House / apartment 0.003541 -16765
## 3 Single / not married House / apartment 0.010032 -19046
## 4 Civil marriage House / apartment 0.008019 -19005
## 5 Single / not married House / apartment 0.028663 -19932
## DAYS_EMPLOYED DAYS_REGISTRATION DAYS_ID_PUBLISH OWN_CAR_AGE FLAG_MOBIL
## 1 -637 -3648 -2120 NaN 1
## 2 -1188 -1186 -291 NaN 1

48
## 3 -225 -4260 -2531 26 1
## 4 -3039 -9833 -2437 NaN 1
## 5 -3038 -4311 -3458 NaN 1
## FLAG_EMP_PHONE FLAG_WORK_PHONE FLAG_CONT_MOBILE FLAG_PHONE FLAG_EMAIL
## 1 1 0 1 1 0
## 2 1 0 1 1 0
## 3 1 1 1 1 0
## 4 1 0 1 0 0
## 5 1 0 1 0 0
## OCCUPATION_TYPE CNT_FAM_MEMBERS REGION_RATING_CLIENT
## 1 Laborers 1 2
## 2 Core staff 2 1
## 3 Laborers 1 2
## 4 Laborers 2 2
## 5 Core staff 1 2
## REGION_RATING_CLIENT_W_CITY WEEKDAY_APPR_PROCESS_START
## 1 2 WEDNESDAY
## 2 1 MONDAY
## 3 2 MONDAY
## 4 2 WEDNESDAY
## 5 2 THURSDAY
## HOUR_APPR_PROCESS_START REG_REGION_NOT_LIVE_REGION REG_REGION_NOT_WORK_REGION
## 1 10 0 0
## 2 11 0 0
## 3 9 0 0
## 4 17 0 0
## 5 11 0 0
## LIVE_REGION_NOT_WORK_REGION REG_CITY_NOT_LIVE_CITY REG_CITY_NOT_WORK_CITY
## 1 0 0 0
## 2 0 0 0
## 3 0 0 0
## 4 0 0 0
## 5 0 0 1
## LIVE_CITY_NOT_WORK_CITY ORGANIZATION_TYPE EXT_SOURCE_1 EXT_SOURCE_2
## 1 0 Business Entity Type 3 0.08303697 0.2629486
## 2 0 School 0.31126731 0.6222458
## 3 0 Government NaN 0.5559121
## 4 0 Business Entity Type 3 NaN 0.6504417
## 5 1 Religion NaN 0.3227383
## EXT_SOURCE_3 APARTMENTS_AVG BASEMENTAREA_AVG YEARS_BEGINEXPLUATATION_AVG
## 1 0.1393758 0.0247 0.0369 0.9722
## 2 NaN 0.0959 0.0529 0.9851
## 3 0.7295667 NaN NA NaN
## 4 NaN NaN NA NaN
## 5 NaN NaN NA NaN
## YEARS_BUILD_AVG COMMONAREA_AVG ELEVATORS_AVG ENTRANCES_AVG FLOORSMAX_AVG
## 1 0.6192 0.0143 0.00 0.0690 0.0833
## 2 0.7960 0.0605 0.08 0.0345 0.2917
## 3 NaN NA NaN NaN NaN
## 4 NaN NA NaN NaN NaN
## 5 NaN NA NaN NaN NaN
## FLOORSMIN_AVG LANDAREA_AVG LIVINGAPARTMENTS_AVG LIVINGAREA_AVG
## 1 0.1250 0.0369 0.0202 0.019
## 2 0.3333 0.013 0.0773 0.0549

49
## 3 NaN NA NA NA
## 4 NaN NA NA NA
## 5 NaN NA NA NA
## NONLIVINGAPARTMENTS_AVG NONLIVINGAREA_AVG APARTMENTS_MODE BASEMENTAREA_MODE
## 1 0 0 0.0252 0.0383
## 2 0.0039 0.0098 0.0924 0.0538
## 3 NA NA NaN NA
## 4 NA NA NaN NA
## 5 NA NA NaN NA
## YEARS_BEGINEXPLUATATION_MODE YEARS_BUILD_MODE COMMONAREA_MODE ELEVATORS_MODE
## 1 0.9722 0.6341 0.0144 0.0000
## 2 0.9851 0.8040 0.0497 0.0806
## 3 NaN NaN NA NaN
## 4 NaN NaN NA NaN
## 5 NaN NaN NA NaN
## ENTRANCES_MODE FLOORSMAX_MODE FLOORSMIN_MODE LANDAREA_MODE
## 1 0.0690 0.0833 0.1250 0.0377
## 2 0.0345 0.2917 0.3333 0.0128
## 3 NaN NaN NaN NA
## 4 NaN NaN NaN NA
## 5 NaN NaN NaN NA
## LIVINGAPARTMENTS_MODE LIVINGAREA_MODE NONLIVINGAPARTMENTS_MODE
## 1 0.022 0.0198 0
## 2 0.079 0.0554 0
## 3 NA NA NaN
## 4 NA NA NaN
## 5 NA NA NaN
## NONLIVINGAREA_MODE APARTMENTS_MEDI BASEMENTAREA_MEDI
## 1 0 0.0250 0.0369
## 2 0 0.0968 0.0529
## 3 NA NaN NA
## 4 NA NaN NA
## 5 NA NaN NA
## YEARS_BEGINEXPLUATATION_MEDI YEARS_BUILD_MEDI COMMONAREA_MEDI ELEVATORS_MEDI
## 1 0.9722 0.6243 0.0144 0.00
## 2 0.9851 0.7987 0.0608 0.08
## 3 NaN NaN NA NaN
## 4 NaN NaN NA NaN
## 5 NaN NaN NA NaN
## ENTRANCES_MEDI FLOORSMAX_MEDI FLOORSMIN_MEDI LANDAREA_MEDI
## 1 0.0690 0.0833 0.1250 0.0375
## 2 0.0345 0.2917 0.3333 0.0132
## 3 NaN NaN NaN NA
## 4 NaN NaN NaN NA
## 5 NaN NaN NaN NA
## LIVINGAPARTMENTS_MEDI LIVINGAREA_MEDI NONLIVINGAPARTMENTS_MEDI
## 1 0.0205 0.0193 0.0000
## 2 0.0787 0.0558 0.0039
## 3 NA NA NaN
## 4 NA NA NaN
## 5 NA NA NaN
## NONLIVINGAREA_MEDI FONDKAPREMONT_MODE HOUSETYPE_MODE TOTALAREA_MODE
## 1 0 reg oper account block of flats 0.0149
## 2 0.01 reg oper account block of flats 0.0714

50
## 3 NA <NA> <NA> NaN
## 4 NA <NA> <NA> NaN
## 5 NA <NA> <NA> NaN
## WALLSMATERIAL_MODE EMERGENCYSTATE_MODE OBS_30_CNT_SOCIAL_CIRCLE
## 1 Stone, brick No 2
## 2 Block No 1
## 3 <NA> <NA> 0
## 4 <NA> <NA> 2
## 5 <NA> <NA> 0
## DEF_30_CNT_SOCIAL_CIRCLE OBS_60_CNT_SOCIAL_CIRCLE DEF_60_CNT_SOCIAL_CIRCLE
## 1 2 2 2
## 2 0 1 0
## 3 0 0 0
## 4 0 2 0
## 5 0 0 0
## DAYS_LAST_PHONE_CHANGE FLAG_DOCUMENT_2 FLAG_DOCUMENT_3 FLAG_DOCUMENT_4
## 1 -1134 0 1 0
## 2 -828 0 1 0
## 3 -815 0 0 0
## 4 -617 0 1 0
## 5 -1106 0 0 0
## FLAG_DOCUMENT_5 FLAG_DOCUMENT_6 FLAG_DOCUMENT_7 FLAG_DOCUMENT_8
## 1 0 0 0 0
## 2 0 0 0 0
## 3 0 0 0 0
## 4 0 0 0 0
## 5 0 0 0 1
## FLAG_DOCUMENT_9 FLAG_DOCUMENT_10 FLAG_DOCUMENT_11 FLAG_DOCUMENT_12
## 1 0 0 0 0
## 2 0 0 0 0
## 3 0 0 0 0
## 4 0 0 0 0
## 5 0 0 0 0
## FLAG_DOCUMENT_13 FLAG_DOCUMENT_14 FLAG_DOCUMENT_15 FLAG_DOCUMENT_16
## 1 0 0 0 0
## 2 0 0 0 0
## 3 0 0 0 0
## 4 0 0 0 0
## 5 0 0 0 0
## FLAG_DOCUMENT_17 FLAG_DOCUMENT_18 FLAG_DOCUMENT_19 FLAG_DOCUMENT_20
## 1 0 0 0 0
## 2 0 0 0 0
## 3 0 0 0 0
## 4 0 0 0 0
## 5 0 0 0 0
## FLAG_DOCUMENT_21 AMT_REQ_CREDIT_BUREAU_HOUR AMT_REQ_CREDIT_BUREAU_DAY
## 1 0 0 0
## 2 0 0 0
## 3 0 0 0
## 4 0 NaN NaN
## 5 0 0 0
## AMT_REQ_CREDIT_BUREAU_WEEK AMT_REQ_CREDIT_BUREAU_MON
## 1 0 0
## 2 0 0

51
## 3 0 0
## 4 NaN NaN
## 5 0 0
## AMT_REQ_CREDIT_BUREAU_QRT AMT_REQ_CREDIT_BUREAU_YEAR
## 1 0 1
## 2 0 0
## 3 0 0
## 4 NaN NaN
## 5 0 0

Nuestra variable objetivo es TARGET que puede tomar dos valores, si es “0” el cliente no ha tenido retrasos
en el pago de las cuotas y si es “1” indica que si ha tenido retrasos. Transformamos nuestra variable en
factor y comprobamos si nuestro conjunto de datos esta balanceado.

#Transformamos nuestra variable objetivo en factor.


homeCredit[,"TARGET"] <- as.factor(homeCredit[,"TARGET"])
#Tabla de casos TARGET
h2o.table(homeCredit$TARGET)

## TARGET Count
## 1 0 9225
## 2 1 775
##
## [2 rows x 2 columns]

Vemos que hay muchos más casos en los cuales no ha habido retrasos en el pago de las cuotas (9.225
observaciones), que los que sí han tenido retrasos (775), estando desbalanceados las clases. Comprobaremos
si mejora el modelo indicándole que los datos no están balanceados o tiene suficientes casos para que el
modelo pueda aprender.
Dividimos nuestro conjunto de datos en un conjunto de entrenamiento y otro de validación, pero esta vez lo
realizamos dentro del clúster con la función de la propia librería h2o.splitFrame().

split <- h2o.splitFrame(data = homeCredit, ratios = 0.8)


train_h2o <- h2o.assign(data = split[[1]],key = "train_h2o")
test_h2o <- h2o.assign(data = split[[2]], key = "test_h2o")

Ahora que tenemos dividido el conjunto de datos le podemos pedir, otra vez, las dimensiones de cada uno
de los conjuntos creados.

#Dimensiones train_h2o.
h2o.dim(train_h2o)

## [1] 8062 121

#Dimensiones test_h2o
h2o.dim(test_h2o)

## [1] 1938 121

Realizamos nuestro primer modelo de random forest con la función h2o.randomForest().

52
set.seed(123)
model_h2o_random1 <- h2o.randomForest(x = 2:121, #Variables predictoras
y = "TARGET", #Variable dependiente
training_frame = train_h2o, #Conjunto de datos.
nfolds = 5, #Validación Cruzada.
seed = 1979)
model_h2o_random1

## Model Details:
## ==============
##
## H2OBinomialModel: drf
## Model ID: DRF_model_R_1608927403343_1
## Model Summary:
## number_of_trees number_of_internal_trees model_size_in_bytes min_depth
## 1 50 50 360473 18
## max_depth mean_depth min_leaves max_leaves mean_leaves
## 1 20 19.96000 131 431 316.56000
##
##
## H2OBinomialMetrics: drf
## ** Reported on training data. **
## ** Metrics reported on Out-Of-Bag training samples **
##
## MSE: 0.06725873
## RMSE: 0.2593429
## LogLoss: 0.3615044
## Mean Per-Class Error: 0.3791116
## AUC: 0.7210057
## AUCPR: 0.1996172
## Gini: 0.4420113
## R^2: 0.05534995
##
## Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
## 0 1 Error Rate
## 0 6703 737 0.099059 =737/7440
## 1 410 212 0.659164 =410/622
## Totals 7113 949 0.142272 =1147/8062
##
## Maximum Metrics: Maximum metrics at their respective thresholds
## metric threshold value idx
## 1 max f1 0.164434 0.269892 165
## 2 max f2 0.100020 0.393633 238
## 3 max f0point5 0.249051 0.269122 98
## 4 max accuracy 0.715682 0.923096 1
## 5 max precision 0.750000 1.000000 0
## 6 max recall 0.000009 1.000000 399
## 7 max specificity 0.750000 1.000000 0
## 8 max absolute_mcc 0.103084 0.210548 234
## 9 max min_per_class_accuracy 0.074303 0.664919 274
## 10 max mean_per_class_accuracy 0.100020 0.673580 238
## 11 max tns 0.750000 7440.000000 0
## 12 max fns 0.750000 621.000000 0

53
## 13 max fps 0.000009 7440.000000 399
## 14 max tps 0.000009 622.000000 399
## 15 max tnr 0.750000 1.000000 0
## 16 max fnr 0.750000 0.998392 0
## 17 max fpr 0.000009 1.000000 399
## 18 max tpr 0.000009 1.000000 399
##
## Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F
##
## H2OBinomialMetrics: drf
## ** Reported on cross-validation data. **
## ** 5-fold cross-validation on training data (Metrics computed for combined holdout predictions) **
##
## MSE: 0.07001764
## RMSE: 0.2646085
## LogLoss: 0.3769249
## Mean Per-Class Error: 0.3900814
## AUC: 0.6462258
## AUCPR: 0.1433515
## Gini: 0.2924515
## R^2: 0.01660111
##
## Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
## 0 1 Error Rate
## 0 6468 972 0.130645 =972/7440
## 1 404 218 0.649518 =404/622
## Totals 6872 1190 0.170677 =1376/8062
##
## Maximum Metrics: Maximum metrics at their respective thresholds
## metric threshold value idx
## 1 max f1 0.135559 0.240618 167
## 2 max f2 0.060016 0.338389 280
## 3 max f0point5 0.162186 0.211612 138
## 4 max accuracy 0.540000 0.922724 0
## 5 max precision 0.231501 0.226974 82
## 6 max recall 0.000005 1.000000 399
## 7 max specificity 0.540000 0.999866 0
## 8 max absolute_mcc 0.135559 0.165374 167
## 9 max min_per_class_accuracy 0.064485 0.616398 271
## 10 max mean_per_class_accuracy 0.072635 0.621906 256
## 11 max tns 0.540000 7439.000000 0
## 12 max fns 0.540000 622.000000 0
## 13 max fps 0.000005 7440.000000 399
## 14 max tps 0.000005 622.000000 399
## 15 max tnr 0.540000 0.999866 0
## 16 max fnr 0.540000 1.000000 0
## 17 max fpr 0.000005 1.000000 399
## 18 max tpr 0.000005 1.000000 399
##
## Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F
## Cross-Validation Metrics Summary:
## mean sd cv_1_valid cv_2_valid cv_3_valid cv_4_valid
## accuracy 0.8243599 0.072625406 0.7013382 0.8263509 0.8697759 0.8393846
## auc 0.6472039 0.024801826 0.62074816 0.66444504 0.62726516 0.679681

54
## aucpr 0.14908388 0.016446771 0.12833357 0.16968621 0.13821124 0.14969459
## err 0.1756401 0.072625406 0.2986618 0.17364906 0.13022411 0.16061538
## err_count 285.0 123.16859 491.0 286.0 215.0 261.0
## cv_5_valid
## accuracy 0.8849498
## auc 0.6438804
## aucpr 0.1594938
## err 0.11505017
## err_count 172.0
##
## ---
## mean sd cv_1_valid cv_2_valid cv_3_valid
## pr_auc 0.14908388 0.016446771 0.12833357 0.16968621 0.13821124
## precision 0.20141649 0.044126444 0.13849287 0.20212767 0.19310345
## r2 0.017034728 0.014152898 -0.004846903 0.03045428 0.01117484
## recall 0.37382933 0.11950391 0.5 0.48305085 0.22222222
## rmse 0.26442853 0.008405346 0.27613297 0.25394243 0.2640176
## specificity 0.8617284 0.08585724 0.719496 0.852845 0.9232787
## cv_4_valid cv_5_valid
## pr_auc 0.14969459 0.1594938
## precision 0.21145375 0.26190478
## r2 0.022547945 0.025843477
## recall 0.36923078 0.29464287
## rmse 0.2682172 0.25983238
## specificity 0.88026756 0.9327549

El modelo nos indica los parámetros que ha utilizado para entrenar el modelo que son: número de variables,
profundidad, número de árboles, número de hojas mínimo, máximo y media. Además, ya nos indica distintas
métricas primero para el Out-Of-Bag y luego las obtenidas con validación cruzada que nos sirven para valorar
la consistencia del modelo.
Si nos fijamos vemos que el AUC que indica en el primer momento es el obtenido en el Out-Of-Bag, para
luego indicar el obtenido por validación cruzada que es inferior al inicial.
Obtenemos las variables más importantes con las que se ha construido el Random Forest Distribuido.

h2o.varimp_plot(model_h2o_random1)

55
Variable Importance: DRF

COMMONAREA_MODE
ORGANIZATION_TYPE
NONLIVINGAREA_MODE
NONLIVINGAREA_AVG
NONLIVINGAREA_MEDI
EXT_SOURCE_3
LIVINGAPARTMENTS_AVG
EXT_SOURCE_2
LIVINGAPARTMENTS_MEDI
OCCUPATION_TYPE 0.0

0.2

0.4

0.6

0.8

1.0
Calculamos sobre el conjunto de validación el rendimiento de nuestro modelo. Las métricas son inferiores a
Obenidas con el erro OBB del modelo pero más similares a las obtenidas con validación cruzada, lo que nos
demuestra que debemos fijarnos en las métricas de validación cruzada para obtener resultado más parecidos
a los reales.

h2o.performance(model_h2o_random1,test_h2o)

## H2OBinomialMetrics: drf
##
## MSE: 0.07021118
## RMSE: 0.2649739
## LogLoss: 0.3959229
## Mean Per-Class Error: 0.3772176
## AUC: 0.6538438
## AUCPR: 0.1832866
## Gini: 0.3076875
## R^2: 0.03442915
##
## Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
## 0 1 Error Rate
## 0 1570 215 0.120448 =215/1785
## 1 97 56 0.633987 =97/153
## Totals 1667 271 0.160991 =312/1938
##
## Maximum Metrics: Maximum metrics at their respective thresholds
## metric threshold value idx

56
## 1 max f1 0.138823 0.264151 134
## 2 max f2 0.067124 0.347695 243
## 3 max f0point5 0.266235 0.307692 30
## 4 max accuracy 0.440000 0.921569 0
## 5 max precision 0.440000 1.000000 0
## 6 max recall 0.000002 1.000000 399
## 7 max specificity 0.440000 1.000000 0
## 8 max absolute_mcc 0.266235 0.215723 30
## 9 max min_per_class_accuracy 0.064312 0.607843 249
## 10 max mean_per_class_accuracy 0.067124 0.627264 243
## 11 max tns 0.440000 1785.000000 0
## 12 max fns 0.440000 152.000000 0
## 13 max fps 0.000002 1785.000000 399
## 14 max tps 0.000002 153.000000 399
## 15 max tnr 0.440000 1.000000 0
## 16 max fnr 0.440000 0.993464 0
## 17 max fpr 0.000002 1.000000 399
## 18 max tpr 0.000002 1.000000 399
##
## Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F

4.4. Grid Search: Selección de Hiperparámetros.

Una de las ventajas que tiene el paquete h2o es que podemos realizar con él la selección de los parámetros más
adecuados para nuestro modelo de una forma sencilla. Vamos a modificar el parámetro de balance_classes
para ver si mejora nuestro modelo balanceando los datos.

set.seed(123)
hyper_params <- list( balance_classes = c(TRUE, FALSE))
grid <- h2o.grid(x = 2:121,
y = "TARGET",
training_frame = train_h2o,
algorithm = "randomForest",
hyper_params = hyper_params,
seed = 1979)

grid

## H2O Grid Details


## ================
##
## Grid ID: Grid_DRF_train_h2o_model_R_1608927403343_174
## Used hyper parameters:
## - balance_classes
## Number of models: 2
## Number of failed models: 0
##
## Hyper-Parameter Search Summary: ordered by increasing logloss
## balance_classes model_ids
## 1 true Grid_DRF_train_h2o_model_R_1608927403343_174_model_1
## 2 false Grid_DRF_train_h2o_model_R_1608927403343_174_model_2
## logloss
## 1 0.35956014669312475

57
## 2 0.36150438921774103

Observamos que el logloss (métrica que mide la incertidumbre de las probabilidades de un modelo comparán-
dolas con las etiquetas verdaderas) se reduce, por lo que balancear los datos mejora el modelo. Podríamos
seguir añadiendo parámetros, pero el tiempo de computación sería muy largo y costoso para estos casos
podemos realizarlo de otra forma llamada RandomDiscrete.
RandomDiscrete se utiliza cuando tenemos muchos parámetros que optimizar y utilizar el anterior método
sería muy costoso por todas las combinaciones que tendría que realizar. Lo que hace RandomDiscrete es que
salta de una combinación aleatoria a otra. Necesitamos indicarle los siguientes parámetros, aunque no todos
son obligatorios:

• max_runtime_secs: Número de segundos en los que hará modelos aleatorios y se parará.


• max_models: número máximo de modelos que hará.
• stopping_metric: métrica que utilizará; AUTO: por defecto logloss para clasificación, de-
viance para regresión, deviance, logloss, MSE, RMSE, MAE, RMSLE, AUC, misclassification,
mean_per_class_error.
• stopping_tolerance: mejora que se solicita de la métrica.
• stopping_rounds: indica el número de modelos que hará antes de parar si no mejoran la stopping
_tolerance del mejor modelo.

Realizamos un máximo de 50 modelos para la estimación de hiperparámetros siguientes: número de árboles,


profundidad, mínimo de observaciones para dividir y número de variables. Utilizamos la métrica de AUC.

search_criteria <- list(strategy = "RandomDiscrete",


max_models= 50,
stopping_metric = "auc",
stopping_tolerance = 0.001,
stopping_rounds = 5,
seed = 1979)
hyper_params <- list(ntrees = c(100:300), #Número de árboles.
mtries = c(10:100), #Número de variables.
max_depth = c(20, 40, 60,80), #Máxima profundad.
min_rows = c(1:2000) #Mínimo de observaciones para dividir.
)
grid <- h2o.grid(x = 2:121,
y = "TARGET",
training_frame = train_h2o,
algorithm = "randomForest",
hyper_params = hyper_params,
search_criteria = search_criteria,
grid_id = "grid_id",
seed = 1979)

grid

## H2O Grid Details


## ================
##
## Grid ID: grid_id
## Used hyper parameters:
## - max_depth
## - min_rows

58
## - mtries
## - ntrees
## Number of models: 50
## Number of failed models: 0
##
## Hyper-Parameter Search Summary: ordered by increasing logloss
## max_depth min_rows mtries ntrees model_ids logloss
## 1 20 236.0 48 225 grid_id_model_43 0.22461969123169867
## 2 20 189.0 40 160 grid_id_model_30 0.2265103363436277
## 3 60 279.0 54 103 grid_id_model_44 0.22731916637852073
## 4 20 380.0 32 224 grid_id_model_48 0.2278592254434241
## 5 80 227.0 52 134 grid_id_model_10 0.2294795404606077
##
## ---
## max_depth min_rows mtries ntrees model_ids logloss
## 45 40 1727.0 26 248 grid_id_model_22 0.2568862532178928
## 46 40 1671.0 28 139 grid_id_model_42 0.2569011280639156
## 47 60 1226.0 10 190 grid_id_model_6 0.25795342837134616
## 48 80 1295.0 99 183 grid_id_model_34 0.2583397521264164
## 49 40 1739.0 18 294 grid_id_model_40 0.25953800890748213
## 50 80 2.0 45 102 grid_id_model_41 0.3745023701043175

Con los modelos que hemos creado, obtenemos un lista con los 5 mejores modelos en función del logloss y
los 6 últimos modelos en función de la misma métrica.
Capturamos el mejor modelo obtenido con grid y obtenemos el rendimiento sobre los datos test.

#Capturamos el mejor modelo.


model_H2o_grid <- h2o.getModel(grid@model_ids[[1]])
model_H2o_grid

## Model Details:
## ==============
##
## H2OBinomialModel: drf
## Model ID: grid_id_model_43
## Model Summary:
## number_of_trees number_of_internal_trees model_size_in_bytes min_depth
## 1 225 225 159191 3
## max_depth mean_depth min_leaves max_leaves mean_leaves
## 1 12 8.37778 5 18 14.27556
##
##
## H2OBinomialMetrics: drf
## ** Reported on training data. **
## ** Metrics reported on Out-Of-Bag training samples **
##
## MSE: 0.06208413
## RMSE: 0.2491669
## LogLoss: 0.2246197
## Mean Per-Class Error: 0.3241698
## AUC: 0.8125215
## AUCPR: 0.3606443
## Gini: 0.625043

59
## R^2: 0.1280274
##
## Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
## 0 1 Error Rate
## 0 7066 374 0.050269 =374/7440
## 1 372 250 0.598071 =372/622
## Totals 7438 624 0.092533 =746/8062
##
## Maximum Metrics: Maximum metrics at their respective thresholds
## metric threshold value idx
## 1 max f1 0.178103 0.401284 109
## 2 max f2 0.124688 0.468828 171
## 3 max f0point5 0.196182 0.408121 92
## 4 max accuracy 0.323082 0.928182 23
## 5 max precision 0.444543 1.000000 0
## 6 max recall 0.001021 1.000000 397
## 7 max specificity 0.444543 1.000000 0
## 8 max absolute_mcc 0.178103 0.351144 109
## 9 max min_per_class_accuracy 0.089627 0.731511 219
## 10 max mean_per_class_accuracy 0.090071 0.734239 218
## 11 max tns 0.444543 7440.000000 0
## 12 max fns 0.444543 620.000000 0
## 13 max fps 0.000250 7440.000000 399
## 14 max tps 0.001021 622.000000 397
## 15 max tnr 0.444543 1.000000 0
## 16 max fnr 0.444543 0.996785 0
## 17 max fpr 0.000250 1.000000 399
## 18 max tpr 0.001021 1.000000 397
##
## Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F

#Calculamos el rendimiento sobre los datos de validación.


(perf_h2o <- h2o.performance(model_H2o_grid, test_h2o))

## H2OBinomialMetrics: drf
##
## MSE: 0.07084721
## RMSE: 0.2661714
## LogLoss: 0.2717191
## Mean Per-Class Error: 0.3892624
## AUC: 0.6734186
## AUCPR: 0.1437305
## Gini: 0.3468373
## R^2: 0.02568211
##
## Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
## 0 1 Error Rate
## 0 1597 188 0.105322 =188/1785
## 1 103 50 0.673203 =103/153
## Totals 1700 238 0.150155 =291/1938
##
## Maximum Metrics: Maximum metrics at their respective thresholds
## metric threshold value idx
## 1 max f1 0.145195 0.255754 116

60
## 2 max f2 0.087991 0.356537 198
## 3 max f0point5 0.153872 0.227503 106
## 4 max accuracy 0.430472 0.920537 0
## 5 max precision 0.155755 0.216080 103
## 6 max recall 0.000182 1.000000 399
## 7 max specificity 0.430472 0.999440 0
## 8 max absolute_mcc 0.145195 0.181960 116
## 9 max min_per_class_accuracy 0.073684 0.620915 231
## 10 max mean_per_class_accuracy 0.101103 0.640336 176
## 11 max tns 0.430472 1784.000000 0
## 12 max fns 0.430472 153.000000 0
## 13 max fps 0.000182 1785.000000 399
## 14 max tps 0.000182 153.000000 399
## 15 max tnr 0.430472 0.999440 0
## 16 max fnr 0.430472 1.000000 0
## 17 max fpr 0.000182 1.000000 399
## 18 max tpr 0.000182 1.000000 399
##
## Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F

Con los nuevos parámetros, hemos mejorado las métricas.


Una vez que tenemos nuestro modelo vamos a predecir sobre los datos de test_h2o.

(predic_h2o <- h2o.predict(model_H2o_grid, newdata = test_h2o))

## predict p0 p1
## 1 0 0.9129918 0.08700816
## 2 0 0.9535218 0.04647822
## 3 0 0.9172949 0.08270512
## 4 0 0.9618850 0.03811499
## 5 0 0.9761414 0.02385861
## 6 0 0.9354156 0.06458442
##
## [1938 rows x 3 columns]

Por último, para apagar nuestro clúster realizamos:

#Eliminamos datos del clúster (opcional).


#h2o.removeAll()
#Apagamos el clúster.
#h2o.shutdown()

61

También podría gustarte