Paso 1: preparación inicial y limpieza

Descargamos la base de datos

library(readr)

library(readr)
data1 <- read_csv("Student-mat.csv")
## Rows: 395 Columns: 33
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (17): school, sex, address, famsize, Pstatus, Mjob, Fjob, reason, guardi...
## dbl (16): age, Medu, Fedu, traveltime, studytime, failures, famrel, freetime...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
dim(data1)
## [1] 395  33
names(data1)
##  [1] "school"     "sex"        "age"        "address"    "famsize"   
##  [6] "Pstatus"    "Medu"       "Fedu"       "Mjob"       "Fjob"      
## [11] "reason"     "guardian"   "traveltime" "studytime"  "failures"  
## [16] "schoolsup"  "famsup"     "paid"       "activities" "nursery"   
## [21] "higher"     "internet"   "romantic"   "famrel"     "freetime"  
## [26] "goout"      "Dalc"       "Walc"       "health"     "absences"  
## [31] "G1"         "G2"         "G3"
head(data1$G3)
## [1]  6  6 10 15 10 15
length(data1$G3)
## [1] 395

Paso 2: dividir entrenamiento y prueba

Clasificar si el estudiante apruéba o no apreuba

data1$rendimiento <- ifelse(data1$G3 >= 10, "Aprueba", "Reprueba")
data1$rendimiento <- as.factor(data1$rendimiento)
table(data1$rendimiento)
## 
##  Aprueba Reprueba 
##      265      130

Vamos hacer division de entrenamiento y prueba:

set.seed(2025)
library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
folds <- createFolds(data1$rendimiento, k = 5)
entrenamiento <- data1[-folds[[5]], ]
prueba <- data1[folds[[5]], ]

Guardar cada etiqueta aparte:

entrenamiento_labels <- data1$rendimiento[-folds[[5]]]
prueba_labels <- data1$rendimiento[folds[[5]]]

Chequeamos cuantas observaciones nos quedan:

dim(entrenamiento)
## [1] 316  34
dim(prueba)
## [1] 79 34

Paso 3: aplicar naiveBayes()

library(e1071)
library(naivebayes)
## naivebayes 1.0.0 loaded
## For more information please visit:
## https://majkamichal.github.io/naivebayes/
modelo1 <- naiveBayes(rendimiento ~ . - G3, data = entrenamiento)
modelo1
## 
## Naive Bayes Classifier for Discrete Predictors
## 
## Call:
## naiveBayes.default(x = X, y = Y, laplace = laplace)
## 
## A-priori probabilities:
## Y
##   Aprueba  Reprueba 
## 0.6708861 0.3291139 
## 
## Conditional probabilities:
##           school
## Y                 GP        MS
##   Aprueba  0.8867925 0.1132075
##   Reprueba 0.8653846 0.1346154
## 
##           sex
## Y                  F         M
##   Aprueba  0.5235849 0.4764151
##   Reprueba 0.6153846 0.3846154
## 
##           age
## Y              [,1]     [,2]
##   Aprueba  16.55189 1.193246
##   Reprueba 17.02885 1.361444
## 
##           address
## Y                  R         U
##   Aprueba  0.2264151 0.7735849
##   Reprueba 0.2307692 0.7692308
## 
##           famsize
## Y                GT3       LE3
##   Aprueba  0.6886792 0.3113208
##   Reprueba 0.7307692 0.2692308
## 
##           Pstatus
## Y                   A          T
##   Aprueba  0.11320755 0.88679245
##   Reprueba 0.07692308 0.92307692
## 
##           Medu
## Y              [,1]     [,2]
##   Aprueba  2.849057 1.103999
##   Reprueba 2.509615 1.105987
## 
##           Fedu
## Y              [,1]     [,2]
##   Aprueba  2.603774 1.085704
##   Reprueba 2.375000 1.098874
## 
##           Mjob
## Y             at_home     health      other   services    teacher
##   Aprueba  0.15566038 0.09433962 0.32075472 0.26415094 0.16509434
##   Reprueba 0.19230769 0.06730769 0.39423077 0.21153846 0.13461538
## 
##           Fjob
## Y             at_home     health      other   services    teacher
##   Aprueba  0.04716981 0.03773585 0.56603774 0.26886792 0.08018868
##   Reprueba 0.07692308 0.04807692 0.50000000 0.30769231 0.06730769
## 
##           reason
## Y              course       home      other reputation
##   Aprueba  0.34433962 0.26415094 0.11320755 0.27830189
##   Reprueba 0.45192308 0.27884615 0.04807692 0.22115385
## 
##           guardian
## Y              father     mother      other
##   Aprueba  0.24056604 0.70283019 0.05660377
##   Reprueba 0.21153846 0.65384615 0.13461538
## 
##           traveltime
## Y              [,1]      [,2]
##   Aprueba  1.438679 0.6891262
##   Reprueba 1.480769 0.7238083
## 
##           studytime
## Y              [,1]      [,2]
##   Aprueba  2.061321 0.8767747
##   Reprueba 2.009615 0.7943391
## 
##           failures
## Y               [,1]      [,2]
##   Aprueba  0.1650943 0.5207618
##   Reprueba 0.6923077 0.9860869
## 
##           schoolsup
## Y                 no       yes
##   Aprueba  0.8962264 0.1037736
##   Reprueba 0.8365385 0.1634615
## 
##           famsup
## Y                 no       yes
##   Aprueba  0.4103774 0.5896226
##   Reprueba 0.3461538 0.6538462
## 
##           paid
## Y                 no       yes
##   Aprueba  0.4858491 0.5141509
##   Reprueba 0.6250000 0.3750000
## 
##           activities
## Y                 no       yes
##   Aprueba  0.5047170 0.4952830
##   Reprueba 0.4807692 0.5192308
## 
##           nursery
## Y                 no       yes
##   Aprueba  0.2216981 0.7783019
##   Reprueba 0.1826923 0.8173077
## 
##           higher
## Y                  no        yes
##   Aprueba  0.02830189 0.97169811
##   Reprueba 0.09615385 0.90384615
## 
##           internet
## Y                 no       yes
##   Aprueba  0.1367925 0.8632075
##   Reprueba 0.2019231 0.7980769
## 
##           romantic
## Y                 no       yes
##   Aprueba  0.6981132 0.3018868
##   Reprueba 0.5961538 0.4038462
## 
##           famrel
## Y              [,1]      [,2]
##   Aprueba  3.938679 0.9241438
##   Reprueba 3.903846 0.9086342
## 
##           freetime
## Y              [,1]      [,2]
##   Aprueba  3.212264 0.9915475
##   Reprueba 3.317308 0.9478071
## 
##           goout
## Y              [,1]     [,2]
##   Aprueba  2.962264 1.083478
##   Reprueba 3.403846 1.119286
## 
##           Dalc
## Y              [,1]      [,2]
##   Aprueba  1.443396 0.9089360
##   Reprueba 1.519231 0.8241591
## 
##           Walc
## Y              [,1]     [,2]
##   Aprueba  2.287736 1.297917
##   Reprueba 2.326923 1.295566
## 
##           health
## Y              [,1]     [,2]
##   Aprueba  3.481132 1.419105
##   Reprueba 3.682692 1.388332
## 
##           absences
## Y              [,1]     [,2]
##   Aprueba  5.051887 5.928655
##   Reprueba 5.500000 8.297853
## 
##           G1
## Y               [,1]     [,2]
##   Aprueba  12.452830 2.743824
##   Reprueba  7.740385 1.723595
## 
##           G2
## Y               [,1]     [,2]
##   Aprueba  12.608491 2.446106
##   Reprueba  6.769231 2.749160
pred1 <- predict(modelo1, prueba[, -which(names(prueba) %in% c("rendimiento","G3"))], type = "class")
table(pred1, prueba_labels)
##           prueba_labels
## pred1      Aprueba Reprueba
##   Aprueba       45        6
##   Reprueba       8       20

Paso 4: validar estabilidad del modelo

set.seed(2025)
train_control <- trainControl(method = "cv", number = 20, savePredictions = TRUE)

NBC_cv <- train(rendimiento ~ .,
                data = entrenamiento,
                method = "naive_bayes",
                trControl = train_control)

NBC_cv
## Naive Bayes 
## 
## 316 samples
##  33 predictor
##   2 classes: 'Aprueba', 'Reprueba' 
## 
## No pre-processing
## Resampling: Cross-Validated (20 fold) 
## Summary of sample sizes: 299, 301, 300, 300, 299, 300, ... 
## Resampling results across tuning parameters:
## 
##   usekernel  Accuracy   Kappa    
##   FALSE      0.8858701  0.7459361
##    TRUE      0.9050858  0.7625263
## 
## Tuning parameter 'laplace' was held constant at a value of 0
## Tuning
##  parameter 'adjust' was held constant at a value of 1
## Accuracy was used to select the optimal model using the largest value.
## The final values used for the model were laplace = 0, usekernel = TRUE
##  and adjust = 1.
confusionMatrix(NBC_cv$pred$pred, NBC_cv$pred$obs)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction Aprueba Reprueba
##   Aprueba      402       44
##   Reprueba      22      164
##                                           
##                Accuracy : 0.8956          
##                  95% CI : (0.8691, 0.9183)
##     No Information Rate : 0.6709          
##     P-Value [Acc > NIR] : < 2e-16         
##                                           
##                   Kappa : 0.757           
##                                           
##  Mcnemar's Test P-Value : 0.00974         
##                                           
##             Sensitivity : 0.9481          
##             Specificity : 0.7885          
##          Pos Pred Value : 0.9013          
##          Neg Pred Value : 0.8817          
##              Prevalence : 0.6709          
##          Detection Rate : 0.6361          
##    Detection Prevalence : 0.7057          
##       Balanced Accuracy : 0.8683          
##                                           
##        'Positive' Class : Aprueba         
## 

Paso 5: interpretación final

En resumen, nuestro objetivo fue crear un modelo de clasificación que pudiera predecir si un estudiante aprueba o no apruba una clase utilizando variables econoomicas, personales, académicas, etc. Para eso, se creó una variable categoríca que clasifica a los estudiantes en “Aprobado” y “Reprueba”

Utilizamos el modelo Naive Bayes en la que excluimos la variable G3 para ocultarle los resultados. Fue entrenado y evaluado con sus conjuntos de datos de prueba y entrenamiento, ademas de contar con una validacion cruzada de 20 folds para asegurar que el modelo tiene estabilidad.

Al final, el modelo arrojó una precisión de aproximadamente el 90% (con una confianza del 95%, se estima que la precisón del modelo se encuentra entre el 87% y el 92%) y un Kappa del 76%, lo que nos indica que el modelo no está sesgado hacia la clase más grande y puede ser utilizado con confianza para predecir si un estudiante aprueba o no aprueba. Por otro lado, nuestra sensibilidad es bastante alta (95%) lo que nos dice que se identifican bastante bien los estudiantes que aprueban aunque nuestra especificidad es menor (79 %), lo que indica que al modelo se le dificulta un poco más de detectar los que reprueban. También encontramos que el No Information Rate (67% en este caso) se refiere a la precisión del modelo si siempre predijera hacia la clase más grande y nuestra precisión es mayor al NIR, otro indicador de que nuestro modelo es confiable.

En definitiva, entendemos que nuestro modelo Naive Bayes es un predice de manera satisfactoria los estudiantes que aprueban y los que repruéban dependiendo de sus características academicas, económicas, personales y sociales.