Librerias necesarias

library(readxl) # Importar datos de excel 
library(skimr) # Resumen estadísticos
library(readr) # Importar datos csv
library(caret) # Dividir en conjunto de entrenamiento y prueba 
library(partykit) # Arboles de decisión 
library(e1071) # Matriz de confusión 
library(ROCR) # Curva ROC
library(rpart) # Arbol de decision Particionamiento recursivo
library(rpart.plot) # Graficos para rpart
library(randomForest) # Para modelos de bosques aleatorios
library(dplyr) # Manipulacion de datos
library(ggplot2) # Visualizacion de datos
library(xgboost) #Para modelos xgboost

El obejetivo de este documento es cubrir la construcion y evaluacion de un modelo XGBoost. Para ello, es importante que cubramos algunos apsectos iportantes del modelo:

El modelo de aumento de gradiente extremo XGBoost (eXtreme Gradient Boosting) es un algoritmo de aprendizaje automático basado en árboles de decisión que es ampliamente utilizado por su velocidad, precisión y versatilidad. Este modelo es supervisado y se utiliza para tareas como clasificación, regresión y ranking, entre otras.

A continuación, te explico las diferencias principales de XGBoost respecto a otros modelos, junto con sus ventajas, desventajas y cuándo deberías usarlo:

XGBoost es una implementación optimizada del algoritmo de gradient boosting. Gradient boosting es una técnica de aprendizaje en la que se combinan múltiples modelos débiles (como árboles de decisión pequeños) para crear un modelo fuerte. XGBoost mejora esta técnica con optimizaciones adicionales en la eficiencia computacional y el manejo de datos.

¿Cuándo deberías usar XGBoost?

  • Competencias y casos de alta precisión:

Es ideal cuando necesitas maximizar la precisión en problemas complejos de aprendizaje supervisado.

  • Datos tabulares estructurados:

XGBoost es particularmente poderoso en datos tabulares (en contraposición a datos como imágenes o texto).

  • Problemas no lineales:

Útil cuando hay relaciones no lineales entre las variables y el resultado.

  • Conjuntos de datos de tamaño moderado a grande:

Funciona bien en datos que no sean extremadamente grandes (donde escalar se vuelva un problema).

  • Proyectos con tiempo suficiente para ajuste:

Si puedes invertir tiempo en ajustar los hiperparámetros y evaluar el rendimiento.

1) Descripcion de las variables y analisis exploratorio de los datos

Variable Ejemplo Descripción
ID 1 Identificador único de cada registro.
Program.Code HD Código granular que describe el destino y las actividades del viaje (por ejemplo, “HD” para un programa de historia).
FromGrade 8 El grado más bajo en la escuela de un participante en el programa.
ToGrade 8 El grado más alto en la escuela de un participante en el programa.
GroupState IN Abreviatura del estado donde se ubica la escuela de origen. “OTHER” se usa para geografías raras.
IsNonAnnual 1 Indica si el grupo de esta escuela típicamente salta un año entre programas.
Days 3 Número de días que el grupo estuvo en el programa con uno de los instructores.
TransportType A Modo de transporte desde la ubicación de origen al punto de inicio (A = Avión, B = Bus, T = Tren).
SpecialPay NA Indica si el maestro recauda todo el dinero para remitirlo a EduTravel en lugar de hacerlo individualmente.
Price 1174 Precio pagado por participante para asistir al programa.
FRP.Active 72 Número de participantes que compraron seguro de cancelación del viaje.
Income.Level P Indicador del nivel de ingresos de los padres (A = bajo, Q = alto, Z = no clasificado).
EZ.Pay 0.2286 Porcentaje de participantes que se inscriben en un plan de pago automático.
School.Sponsor 0 Indicador binario de si la escuela patrocinó oficialmente el viaje.
Product.Type East Coast Nivel de agrupación del tipo de programa turístico.
New.Existing EXISTING Indica si el grupo ha viajado previamente con EduTravel (“NEW” si no lo ha hecho antes).
FPP 105 Número total de participantes que pagaron completamente para asistir al programa.
Group.Revenue 125735.4 Monto total pagado por todos los participantes del grupo.
Meetings 0 Número de reuniones con los padres antes del viaje.
GradeLow Elementary Tipo de grado más bajo de la escuela.
GradeHigh Elementary Tipo de grado más alto de la escuela.
DepartureMonth January Mes de partida.
Poverty.Code A Código de pobreza del área de origen (A = bajo porcentaje bajo la línea de pobreza, D = alto).
CRM Segment 1 Tipo de segmento de cliente definido en el sistema CRM (números entre 1 y 11).
SchoolType PUBLIC Indica si la escuela es pública o privada.
Meeting.Flag 1 Indica si hubo una reunión con los padres, señalando compromiso con el viaje.
Low.Grade 7 Grado más bajo en la escuela de origen.
High.Grade 8 Grado más alto en la escuela de origen.
School.Enrollment 955 Total de estudiantes inscritos en la escuela.
MajorProgramCode H Agregación del código del programa; la primera letra del código granular del programa.
SingleGrade 1 Indicador de si el viaje incluye estudiantes del mismo grado.
FPP.enrollment 0.06346 Proporción de participantes en el programa respecto al total de la inscripción escolar.
FPP.PAX 0.93650794 Proporción de participantes que pagaron completamente en comparación con el total de pasajeros.
Size L Tamaño de la escuela (S, M, L, S-M, M-L) por quintiles de tamaño.
Retained.in.2020 1 Indicador de éxito (1/0): ¿el grupo volvió al año siguiente?

1.1) Transformacion de tipo variable

edutravel$Program.Code <- as.factor(edutravel$Program.Code)
edutravel$FromGrade <- as.factor(edutravel$FromGrade)
edutravel$ToGrade <- as.factor(edutravel$ToGrade)
edutravel$GroupState <- as.factor(edutravel$GroupState)
edutravel$IsNonAnnual <- as.factor(edutravel$IsNonAnnual)
edutravel$Days <- as.factor(edutravel$Days)
edutravel$TransportType <- as.factor(edutravel$TransportType)
edutravel$SpecialPay <- as.factor(edutravel$SpecialPay)
edutravel$Poverty.Code <- as.factor(edutravel$Poverty.Code)
edutravel$Region <- as.factor(edutravel$Region )
edutravel$CRMSegment <- as.factor(edutravel$CRMSegment)
edutravel$SchoolType <- as.factor(edutravel$SchoolType)
edutravel$Meeting.Flag <- as.factor(edutravel$Meeting.Flag)
edutravel$Income.Level <- as.factor(edutravel$Income.Level)
edutravel$Product.Type <- as.factor(edutravel$Product.Type)
edutravel$New.Existing <- as.factor(edutravel$New.Existing)
edutravel$GradeLow <- as.factor(edutravel$GradeLow)
edutravel$GradeHigh <- as.factor(edutravel$GradeHigh)
edutravel$DepartureMonth <- as.factor(edutravel$DepartureMonth)
edutravel$Meetings <- as.factor(edutravel$Meetings)
edutravel$AggregatedCode <- as.factor(edutravel$AggregatedCode)
edutravel$SingleGrade <- as.factor(edutravel$SingleGrade)
edutravel$Size <- as.factor(edutravel$Size)
edutravel$Low.Grade <- as.factor(edutravel$Low.Grade)
edutravel$Low.High <- as.factor(edutravel$High.Grade)
edutravel$Retained.in.2020 <- as.factor(edutravel$Retained.in.2020) 

1.2) Manejo de datos faltantes

# definimos funcion 
FillNAs<-function(data_frame){ 
  fill_number<-0 
  fill_factor<-"NA_filled" 
  fill_character<-"NA_filled"
  fill_date<-as.Date("1900-01-01")
  
  
  
  # Make a loop in the columns of the data frame and according to the 
  # data type, fill the respective value and create a surrogate column
  
  for (i in 1 : ncol(data_frame)){
    if (class(data_frame[,i]) %in% c("numeric","integer")) { 
      if (any(is.na(data_frame[,i]))){
        data_frame[,paste0(colnames(data_frame)[i],"_filledNA")]<- as.factor(ifelse(is.na(data_frame[,i]),"1","0"))
        data_frame[is.na(data_frame[,i]),i]<-fill_number
      }
    } else
      if (class(data_frame[,i]) %in% c("factor")) { 
        if (any(is.na(data_frame[,i]))){
          data_frame[,i]<-as.character(data_frame[,i]) 
          data_frame[,paste0(colnames(data_frame)[i],"_filledNA")]<-as.factor(ifelse(is.na(data_frame[,i]),"1","0")) 
          data_frame[is.na(data_frame[,i]),i]<-fill_factor
          data_frame[,i]<-as.factor(data_frame[,i])
          
        }
      } else {
        if (class(data_frame[,i]) %in% c("character")) { 
          if (any(is.na(data_frame[,i]))){
            data_frame[,paste0(colnames(data_frame)[i],"_filledNA")]<- as.factor(ifelse(is.na(data_frame[,i]),"1","0"))
            data_frame[is.na(data_frame[,i]),i]<-afill_character
          }
        } else {
          if (class(data_frame[,i]) %in% c("Date")) {
            if (any(is.na(data_frame[,i]))){ 
              data_frame[,paste0(colnames(data_frame)[i],"_filledNA")]<-as.factor(ifelse(is.na(data_frame[,i]),"1","0")) 
              data_frame[is.na(data_frame[,i]),i]<-fill_date
            }
          }
        }
      }
  }
  return(data_frame)
}



# aplicamos función
edutravelNA <-FillNAs(edutravel)

# combinamos categorías

1.3) Manejo de datos categoricos con pocas observaciones

El propósito de esta función, en un contexto práctico, es simplificar y mejorar la calidad de los análisis de datos categóricos, especialmente en situaciones donde:

Reducción de complejidad en las categorías:

En un dataset con muchas categorías, algunas pueden tener muy pocas observaciones, lo que hace que los análisis sean menos significativos y más complejos de interpretar. Combinar estas categorías poco representadas en una genérica llamada “Others” ayuda a reducir el ruido en los datos y enfocar los análisis en las categorías principales. Facilitar la visualización de datos:

Al crear gráficos (por ejemplo, gráficos de barras, de pastel o tablas resumen), un exceso de categorías hace que la visualización sea desordenada y difícil de leer. Agrupar las categorías con pocos datos bajo “Others” mejora la claridad visual y destaca las categorías más relevantes. Mejorar los modelos estadísticos o de machine learning:

En modelos de regresión, clasificación o cualquier algoritmo que utilice variables categóricas, demasiadas categorías con baja frecuencia pueden llevar a problemas de sobreajuste (overfitting) o resultados inestables. Agrupar las categorías pequeñas en “Others” permite que los modelos se centren en las categorías más significativas, mejorando su rendimiento. Normalización de los datos para reportes:

En informes o reportes donde se presenten resultados agrupados, es común agrupar valores menores en una categoría “Otros” para que los resultados sean más concisos y comprensibles. Análisis exploratorio de datos:

Durante el análisis inicial de un dataset, agrupar categorías poco representadas facilita la identificación de patrones significativos en las categorías principales sin distracciones innecesarias.

### Combining Categories

# Definimos funcion
CombineCategories <-function(data_frame,mincount){ 
  for (i in 1 : ncol(data_frame)){
    a<-data_frame[,i]
    replace <- names(which(table(a) < mincount))
    levels(a)[levels(a) %in%    replace]    <- paste("Others",colnames(data_frame)[i],sep=".")
    
    
    
    data_frame[,i]<-a } 
  return(data_frame) 
}

# aplicamos funcion
# dataframe with a mincount of 10
#head(CombineCategories(edutravelNA, 10))

2) Estructuramos modelo de bosque aleatorio

2.1) Separamos en conjunto de prueba y entrenamiento

# indicamos semilla para consistencia
set.seed(2021) 

# separamos datos (80% entrenamiento y 20% prueba)
Partition <- createDataPartition(y = edutravelNA$Retained.in.2020, 
                                 p = 0.8, # porcentaje de entrenamiento.
                                 list = FALSE)

# sepramos en objetos
training <- edutravelNA[ Partition,] 
testing <- edutravelNA[ -Partition,]

# En el modelo tomamos la variable dependiente de retención e independntes todas menos "GroupState" 

training.x <-model.matrix(Retained.in.2020~ .-GroupState # Indicamos las variables
                          , data = training  # Indicamos conjunto de datos 
                          )

testing.x <-model.matrix(Retained.in.2020~ .-GroupState, # Indicamos las variables
                         data = testing # Indicamos conjunto de datos 
                         )

Si observamos el conjunto de entrenamiento podemos observar como todas las variables han sido transformadas a variables dicotomicas

head(training.x,2)
##   (Intercept) Program.CodeCD Program.CodeCN Program.CodeCVP Program.CodeFN
## 1           1              0              0               0              0
## 2           1              0              0               0              0
##   Program.CodeHC Program.CodeHD Program.CodeHF Program.CodeHG Program.CodeHH
## 1              0              0              0              0              0
## 2              1              0              0              0              0
##   Program.CodeHIS Program.CodeHN Program.CodeHO Program.CodeHP Program.CodeHS
## 1               0              0              0              0              1
## 2               0              0              0              0              0
##   Program.CodeHVP Program.CodeHW Program.CodeHX Program.CodeHY Program.CodeHZ
## 1               0              0              0              0              0
## 2               0              0              0              0              0
##   Program.CodeIC Program.CodeIK Program.CodeSC Program.CodeSD Program.CodeSG
## 1              0              0              0              0              0
## 2              0              0              0              0              0
##   Program.CodeSK Program.CodeSM Program.CodeST FromGrade11 FromGrade12
## 1              0              0              0           0           0
## 2              0              0              0           0           0
##   FromGrade3 FromGrade4 FromGrade5 FromGrade6 FromGrade7 FromGrade8 FromGrade9
## 1          0          1          0          0          0          0          0
## 2          0          0          0          0          0          1          0
##   FromGradeNA_filled ToGrade11 ToGrade12 ToGrade3 ToGrade4 ToGrade5 ToGrade6
## 1                  0         0         0        0        1        0        0
## 2                  0         0         0        0        0        0        0
##   ToGrade7 ToGrade8 ToGrade9 ToGradeNA_filled IsNonAnnual1 Days2 Days3 Days4
## 1        0        0        0                0            0     0     0     0
## 2        0        1        0                0            0     0     0     0
##   Days5 Days6 Days7 Days8 Days9 Days10 Days11 Days12 TransportTypeB
## 1     0     0     0     0     0      0      0      0              0
## 2     0     0     1     0     0      0      0      0              0
##   TransportTypeN TransportTypeT SpecialPayFR SpecialPayNA_filled SpecialPaySA
## 1              0              0            0                   1            0
## 2              0              0            0                   0            0
##   Price FRP.Active FRP.Cancelled FRP.Percentage Cancelled.Pax Extra.Pax
## 1   424         25             3          0.424             3         4
## 2  2350          9             9          0.409            11         3
##   Poverty.CodeA Poverty.CodeB Poverty.CodeC Poverty.CodeD Poverty.CodeE
## 1             0             1             0             0             0
## 2             0             0             1             0             0
##   Poverty.CodeNA_filled RegionHouston RegionNorthern California RegionOther
## 1                     0             0                         0           0
## 2                     0             0                         0           1
##   RegionPacific Northwest RegionSouthern California CRMSegment10 CRMSegment11
## 1                       0                         1            0            0
## 2                       0                         0            1            0
##   CRMSegment2 CRMSegment3 CRMSegment4 CRMSegment5 CRMSegment6 CRMSegment7
## 1           0           0           1           0           0           0
## 2           0           0           0           0           0           0
##   CRMSegment8 CRMSegment9 CRMSegmentNA_filled SchoolTypeCHD
## 1           0           0                   0             0
## 2           0           0                   0             0
##   SchoolTypePrivate non-Christian SchoolTypePUBLIC Meeting.Flag1 Low.Grade10
## 1                               0                1             1           0
## 2                               0                1             1           0
##   Low.Grade2 Low.Grade3 Low.Grade4 Low.Grade5 Low.Grade6 Low.Grade7 Low.Grade8
## 1          0          0          0          0          0          0          0
## 2          0          0          0          0          0          1          0
##   Low.Grade9 Low.GradeK Low.GradeNA_filled Low.GradePK High.Grade
## 1          0          1                  0           0          5
## 2          0          0                  0           0          8
##   School.Enrollment Income.LevelB Income.LevelC Income.LevelD Income.LevelE
## 1               927             0             0             0             0
## 2               850             0             0             0             0
##   Income.LevelF Income.LevelG Income.LevelH Income.LevelI Income.LevelJ
## 1             0             0             0             0             0
## 2             0             0             0             0             0
##   Income.LevelK Income.LevelL Income.LevelM Income.LevelN Income.LevelNA_filled
## 1             0             0             0             0                     0
## 2             0             0             0             0                     0
##   Income.LevelO Income.LevelP Income.LevelP1 Income.LevelP3 Income.LevelP4
## 1             0             0              0              0              0
## 2             0             0              0              0              0
##   Income.LevelP5 Income.LevelQ Income.LevelZ EZ.Pay School.Sponsor
## 1              0             1             0  0.170              1
## 2              0             0             0  0.091              0
##   Product.TypeCosta Rica Product.TypeEast Coast Product.TypeIL History
## 1                      0                      0                      0
## 2                      0                      1                      0
##   Product.TypeInternational Product.TypeScience New.ExistingNEW FPP
## 1                         0                   0               0  59
## 2                         0                   0               0  22
##   Group.Revenue Meetings1 Meetings2 FirstMeeting LastMeeting GradeLowHigh
## 1           424         1         0          155         155            0
## 2          2350         0         1          423         140            0
##   GradeLowMiddle GradeLowUndefined GradeHighHigh GradeHighMiddle
## 1              0                 0             0               0
## 2              1                 0             0               1
##   GradeHighUndefined DepartureMonthFebruary DepartureMonthJanuary
## 1                  0                      0                     1
## 2                  0                      0                     1
##   DepartureMonthJune DepartureMonthMarch DepartureMonthMay AggregatedCodeH
## 1                  0                   0                 0               1
## 2                  0                   0                 0               1
##   AggregatedCodeI AggregatedCodeS SingleGrade1 FPP.Enrollment   FPP.Pax SizeM-L
## 1               0               0            1     0.06364617 0.9365079       0
## 2               0               0            1     0.02588235 0.8800000       0
##   SizeNA_filled SizeS SizeS-M Low.High10 Low.High11 Low.High12 Low.High2
## 1             0     0       0          0          0          0         0
## 2             0     0       0          0          0          0         0
##   Low.High3 Low.High4 Low.High5 Low.High6 Low.High7 Low.High8 Low.High9
## 1         0         0         1         0         0         0         0
## 2         0         0         0         0         0         1         0
##   Low.HighNA_filled FromGrade_filledNA1 ToGrade_filledNA1 SpecialPay_filledNA1
## 1                 0                   0                 0                    1
## 2                 0                   0                 0                    0
##   Poverty.Code_filledNA1 CRMSegment_filledNA1 Low.Grade_filledNA1
## 1                      0                    0                   0
## 2                      0                    0                   0
##   High.Grade_filledNA1 School.Enrollment_filledNA1 Income.Level_filledNA1
## 1                    0                           0                      0
## 2                    0                           0                      0
##   FirstMeeting_filledNA1 LastMeeting_filledNA1 FPP.Enrollment_filledNA1
## 1                      0                     0                        0
## 2                      0                     0                        0
##   Size_filledNA1 Low.High_filledNA1
## 1              0                  0
## 2              0                  0

2.2) Impleentamos modelo

Parámetros principales de XGBoost en R

1. data

  • Descripción: Es la matriz que contiene las características (features) del conjunto de entrenamiento.
  • Tipo: Matriz numérica o dispersa (data.matrix o dgCMatrix).

2. label

  • Descripción: Contiene las etiquetas o valores objetivo que el modelo debe predecir.
  • Tipo: Vector numérico o entero con las etiquetas correspondientes a cada fila de data.

3. eta (Tasa de aprendizaje)

  • Descripción: Controla la tasa de aprendizaje del modelo. Reduce el impacto de cada árbol en el modelo final, lo que permite un aprendizaje más lento pero más preciso.
  • Valores: Rango (0, 1). Valor predeterminado = 0.3.
  • Recomendación: Reducir eta requiere aumentar el número de iteraciones (nround).

4. max_depth (Profundidad máxima del árbol)

  • Descripción: Define la profundidad máxima de los árboles generados. Una profundidad mayor permite capturar patrones más complejos, pero aumenta el riesgo de sobreajuste.
  • Valores: Rango (1, infinito). Valor predeterminado = 6.

5. nround (Número de iteraciones)

  • Descripción: Especifica el número total de iteraciones (boosting rounds). Cada iteración agrega un nuevo árbol al modelo.
  • Valores: Valor predeterminado = 100.

6. objective (Función objetivo)

  • Descripción: Define la tarea de aprendizaje del modelo. Especifica cómo calcular el error durante el entrenamiento.
  • Opciones comunes:
    • "reg:linear": Regresión lineal.
    • "binary:logistic": Clasificación binaria que devuelve probabilidades.
    • "multi:softmax": Clasificación multiclase que devuelve etiquetas de clase.
    • "multi:softprob": Clasificación multiclase que devuelve probabilidades para cada clase.

7. gamma

  • Descripción: Controla la reducción mínima en la función objetivo necesaria para dividir un nodo. Ayuda a evitar divisiones innecesarias en los árboles.
  • Valores: Rango [0, infinito). Valor predeterminado = 0.

8. subsample

  • Descripción: Especifica la proporción de datos utilizados en cada iteración de boosting. Ayuda a prevenir el sobreajuste.
  • Valores: Rango (0, 1]. Valor predeterminado = 1.

9. colsample_bytree

  • Descripción: Especifica la proporción de características (columnas) seleccionadas al azar para construir cada árbol.
  • Valores: Rango (0, 1]. Valor predeterminado = 1.

10. lambda y alpha (Regularización)

  • lambda (Regularización L2): Penaliza pesos altos para evitar sobreajuste.
    • Valores: Rango [0, infinito). Valor predeterminado = 1.
  • alpha (Regularización L1): Penaliza el número de características seleccionadas.
    • Valores: Rango [0, infinito). Valor predeterminado = 0.
# Implementamos modelo 
model.XGB<-xgboost(data = data.matrix(training.x[,-1]), # Indicamos todas las filas y todas las columnas menos la primera (El intercepto)
                   label= as.numeric(as.character(training$Retained.in.2020)), # INdiccamos las ettiquetas de las variable dependite
                   eta = 0.2, # Parametro por defecto para la tasa de apredizaje 
                   max_depth = 5, # Prametro para defiir la profundidad del arbol (por defecto 6)
                   nround=50, # Parametro para el numero maximo de iteraciones 
                   objective = "binary:logistic" # Indicamos modelo logistico de clasificacio
                   )
## [1]  train-logloss:0.609544 
## [2]  train-logloss:0.552049 
## [3]  train-logloss:0.510557 
## [4]  train-logloss:0.480147 
## [5]  train-logloss:0.455290 
## [6]  train-logloss:0.435698 
## [7]  train-logloss:0.419243 
## [8]  train-logloss:0.401542 
## [9]  train-logloss:0.388883 
## [10] train-logloss:0.378889 
## [11] train-logloss:0.367400 
## [12] train-logloss:0.358583 
## [13] train-logloss:0.348847 
## [14] train-logloss:0.341961 
## [15] train-logloss:0.335725 
## [16] train-logloss:0.331436 
## [17] train-logloss:0.327514 
## [18] train-logloss:0.318423 
## [19] train-logloss:0.313637 
## [20] train-logloss:0.308587 
## [21] train-logloss:0.302375 
## [22] train-logloss:0.299103 
## [23] train-logloss:0.296640 
## [24] train-logloss:0.290020 
## [25] train-logloss:0.285271 
## [26] train-logloss:0.282510 
## [27] train-logloss:0.279795 
## [28] train-logloss:0.273876 
## [29] train-logloss:0.267571 
## [30] train-logloss:0.265960 
## [31] train-logloss:0.263775 
## [32] train-logloss:0.260317 
## [33] train-logloss:0.258807 
## [34] train-logloss:0.256492 
## [35] train-logloss:0.253918 
## [36] train-logloss:0.252900 
## [37] train-logloss:0.247089 
## [38] train-logloss:0.245864 
## [39] train-logloss:0.244026 
## [40] train-logloss:0.241112 
## [41] train-logloss:0.236192 
## [42] train-logloss:0.234098 
## [43] train-logloss:0.230730 
## [44] train-logloss:0.229527 
## [45] train-logloss:0.224364 
## [46] train-logloss:0.222045 
## [47] train-logloss:0.220630 
## [48] train-logloss:0.217125 
## [49] train-logloss:0.215884 
## [50] train-logloss:0.214483

3) Predecimos y evaluamos el modelo

3.1) Obtenemos el valor de corte para la evaluacion del modelo

Primero, identificamos el punto de corte. Para ello, calculamos el promedio de la tasa de retencion

edutravelNA %>% 
  mutate(Retained.in.2020 = as.numeric(as.character(Retained.in.2020))) %>% # Conversiond de variable
  summarise(media_retencion = mean(Retained.in.2020, na.rm = TRUE)) # calculamos el promedio
##   media_retencion
## 1       0.6073671

Obtenemos que la probabilidad media de ser retenido es 0.607, que es lo que usaremos como valor de corte

3.2) Evaluamos

# Predecimos y evaluamos el modelo 
prediction.XGB<-predict(model.XGB,   # Indicamos el modelo
                        newdata=testing.x[,-1],  # Excluimos la columna 1 (Ya que es el intercepto en los datos)
                        type="prob" # Indicamos la probabilidad 
                        )  

# Creamos matriz de confusion 
confusionMatrix(as.factor(ifelse(prediction.XGB>0.607,1,0)), # indicamos umbral para ceros y unos
                testing$Retained.in.2020, # Indicamos variable dependiente, en el cojunto de prueba
                positive = "1" # Indicamos cuales son los positivos 
                ) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 156  74
##          1  31 216
##                                         
##                Accuracy : 0.7799        
##                  95% CI : (0.74, 0.8163)
##     No Information Rate : 0.608         
##     P-Value [Acc > NIR] : 9.519e-16     
##                                         
##                   Kappa : 0.5563        
##                                         
##  Mcnemar's Test P-Value : 4.153e-05     
##                                         
##             Sensitivity : 0.7448        
##             Specificity : 0.8342        
##          Pos Pred Value : 0.8745        
##          Neg Pred Value : 0.6783        
##              Prevalence : 0.6080        
##          Detection Rate : 0.4528        
##    Detection Prevalence : 0.5178        
##       Balanced Accuracy : 0.7895        
##                                         
##        'Positive' Class : 1             
## 

Podemos observar coo el modelo tiene una efectividad del 77%.