Introducción:

Aplicamos Machine Learning para predecir la supervivencia de los pasajeros del Titanic usando regresión logística, un algoritmo supervisado adecuado para problemas de clasificación binaria.

El flujo de trabajo de Machine Learning que seguimos incluye:

  1. Exploración y limpieza de datos
  2. Selección de variables relevantes
  3. División en datos de entrenamiento y prueba
  4. Entrenamiento del modelo
  5. Evaluación del modelo con métricas de desempeño
  6. Visualización de resultados (curvas ROC y AUC)

1.Exploración y limpieza de datos

Carga de datos:

rm(list = ls())
library(readr)

data_titanic <- read_csv("../Datas/Libro1-titanic.csv")
View(data_titanic)
class(data_titanic) # Debe ser data.frame
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"

Exploración y limpieza:

El Machine Learning requiere datos limpios. Primero revisamos si hay valores faltantes (NA) y los eliminamos.

library(VIM)

# Visualizamos los NA
aggr(data_titanic, numbers = TRUE)

# Eliminamos pasajeros sin edad registrada
No_NA_titanic <- subset(data_titanic, !is.na(data_titanic$age))

2.Selección de variables relevantes

Seleccionamos las variables que creemos predictoras de la supervivencia:

survived → variable objetivo (0 = muerto, 1 = vivo)

sex, age, sibsp, class, alone → variables predictoras

library(dplyr)

Base_depurada <- No_NA_titanic %>% 
  select(survived, sex, age, sibsp, class, alone)

# Proporción de sobrevivientes
(prop.table(table(Base_depurada$survived))) * 100
## 
##        0        1 
## 59.38375 40.61625

En Machine Learning, es importante conocer la distribución de la variable objetivo para evitar problemas de clases desbalanceadas.

Interpretación

El 59% de los pasajeros no sobrevivieron El 41% de los pasajeros sobrevivieron

Esto significa que las clases no están perfectamente balanceadas, pero tampoco están extremadamente desbalanceadas.

Balance perfecto sería ~50%-50% Desbalance muy fuerte sería, por ejemplo, 90%-10%

Con ~59%-41%, el desbalance es moderado, así que un modelo como regresión logística funcionará razonablemente bien.

3. Division de datos: Entrenamiento y Prueba

Un principio clave de ML: entrenar el modelo con datos que no veremos en la evaluación, y validarlo con datos nuevos. En Machine Learning es fundamental separar los datos en dos conjuntos:

Entrenamiento (train) → donde el modelo aprende los patrones de los datos.

Prueba (test) → donde el modelo se evalúa con datos que no ha visto antes, simulando su desempeño en situaciones reales.

Esta separación evita que el modelo se sobreajuste y nos da una medida realista de su capacidad predictiva.

library(caTools)
set.seed(123)  # Fija la semilla para reproducibilidad

# Dividimos los datos: 70% entrenamiento, 30% prueba
data_70_30 <- sample.split(Base_depurada$survived, SplitRatio = 0.70)

data_train <- subset(Base_depurada, data_70_30 == TRUE)
data_test  <- subset(Base_depurada, data_70_30 == FALSE)

# Revisión rápida de estructura de los conjuntos
str(data_train)
## tibble [500 × 6] (S3: tbl_df/tbl/data.frame)
##  $ survived: num [1:500] 0 1 1 0 1 1 0 0 1 0 ...
##  $ sex     : chr [1:500] "male" "female" "female" "male" ...
##  $ age     : num [1:500] 22 26 35 54 27 14 39 14 55 31 ...
##  $ sibsp   : num [1:500] 1 0 1 0 0 1 1 0 0 1 ...
##  $ class   : chr [1:500] "Third" "Third" "First" "First" ...
##  $ alone   : logi [1:500] FALSE TRUE FALSE TRUE FALSE FALSE ...
str(data_test)
## tibble [214 × 6] (S3: tbl_df/tbl/data.frame)
##  $ survived: num [1:214] 1 0 0 1 1 0 0 1 0 0 ...
##  $ sex     : chr [1:214] "female" "male" "male" "female" ...
##  $ age     : num [1:214] 38 35 2 4 58 20 2 15 8 42 ...
##  $ sibsp   : num [1:214] 1 0 3 1 0 0 4 0 3 1 ...
##  $ class   : chr [1:214] "First" "Third" "Third" "Third" ...
##  $ alone   : logi [1:214] FALSE TRUE FALSE FALSE TRUE TRUE ...

Distribución de la variable objetivo (sobrevivientes)

Es importante mantener la proporción de clases (balance) en ambos conjuntos, para que el modelo aprenda patrones representativos y no se sesgue hacia la clase mayoritaria.

# Porcentaje de sobrevivientes en entrenamiento
(prop.table(table(data_train$survived))) * 100
## 
##    0    1 
## 59.4 40.6
# Porcentaje de sobrevivientes en prueba
(prop.table(table(data_test$survived))) * 100
## 
##        0        1 
## 59.34579 40.65421

Mantener la proporción de clases en entrenamiento y prueba ayuda a que el modelo aprenda correctamente y funcione bien con datos nuevos.

4. Entrenamiento del modelo: Regresion Logistica

Modelo de Regresión Logística con glm

En Machine Learning supervisado, cuando nuestra variable objetivo es binaria (0/1), como survived en el Titanic, usamos la regresión logística para predecir la probabilidad de que ocurra un evento.

En R, se hace usando la función glm() (Generalized Linear Model), que permite:

Antes de entrenar el modelo, es importante asegurarnos de que las variables categóricas estén correctamente definidas como factores, ya que R las trata de forma diferente a las numéricas:

# Convertimos la variable categórica "alone" a factor
data_train$alone <- as.factor(data_train$alone) #En train
data_test$alone  <- as.factor(data_test$alone) # En Test

Luego, ajustamos el modelo usando todas las demás variables como predictores (“.” significa “todas las columnas excepto la variable dependiente survived):

# Ajuste del modelo de regresión logística (GLM)
modelo_glm <- glm(
  survived ~ .,                  # Variable objetivo: survived
  family = binomial(link = "logit"),  # Modelo logístico
  data = data_train              # Usamos solo datos de entrenamiento
)

# Resumen de los coeficientes y su significancia
summary(modelo_glm)
## 
## Call:
## glm(formula = survived ~ ., family = binomial(link = "logit"), 
##     data = data_train)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  4.485111   0.547241   8.196 2.49e-16 ***
## sexmale     -2.560870   0.261078  -9.809  < 2e-16 ***
## age         -0.046672   0.009765  -4.780 1.76e-06 ***
## sibsp       -0.609121   0.196763  -3.096 0.001963 ** 
## classSecond -1.189615   0.341920  -3.479 0.000503 ***
## classThird  -2.302076   0.338226  -6.806 1.00e-11 ***
## aloneTRUE   -0.462332   0.318970  -1.449 0.147211    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 675.37  on 499  degrees of freedom
## Residual deviance: 447.75  on 493  degrees of freedom
## AIC: 461.75
## 
## Number of Fisher Scoring iterations: 5

Entrenar un modelo significa encontrar los coeficientes \((\beta_0, \beta_1, \dots, \beta_k)\) que mejor predicen la variable objetivo (survived) usando los datos de entrenamiento. Estos coeficientes representan cómo cada variable independiente (edad, sexo, clase, etc.) afecta la probabilidad de supervivencia.

5. Evaluacion del Modelo con metricas de desenpeño.

Una vez que tenemos nuestro modelo de regresión logística, necesitamos evaluar qué tan bien funciona. En Machine Learning esto se hace usando datos que el modelo ya vio (entrenamiento) y datos que nunca vio (prueba/test).

Paso 1: Predicciones en entrenamiento

 # Predicciones de probabilidad para el conjunto de entrenamiento
ypred_prob_train <- predict(modelo_glm, newdata = data_train[,-1], type = "response")

# Convertimos probabilidades a clases (0 = no sobrevivió, 1 = sobrevivió)
ypred_train <- as.numeric(ypred_prob_train >= 0.5)

# Valores reales de la variable objetivo
ytrue_train <- data_train$survived

# Calculamos la exactitud (accuracy)
accuracy_train <- 1 - mean(ytrue_train != ypred_train)
accuracy_train
## [1] 0.798

Paso 2: Predicciones en prueba (test)

# Predicciones de probabilidad para el conjunto de prueba
ypred_prob_test <- predict(modelo_glm, newdata = data_test[,-1], type = "response")

# Convertimos a clases
ypred_test <- as.numeric(ypred_prob_test >= 0.5)

# Valores reales de la variable objetivo
ytrue_test <- data_test$survived

# Exactitud en el conjunto de prueba
accuracy_test <- 1 - mean(ytrue_test != ypred_test)
accuracy_test
## [1] 0.8037383

Conceptos clave de Machine Learning:

Métricas de Desempeño para Modelos de Clasificación

En problemas de Machine Learning supervisado, evaluamos nuestros modelos usando métricas derivadas de la matriz de confusión:

Predicción Positiva (1) Predicción Negativa (0)
Real Positivo (1) VP (Verdaderos Positivos) FN (Falsos Negativos)
Real Negativo (0) FP (Falsos Positivos) VN (Verdaderos Negativos)
  1. Exactitud (Accuracy)

Definición: Proporción de predicciones correctas sobre el total de observaciones.

Fórmula:

\[ \text{Accuracy} = \frac{VP + VN}{VP + VN + FP + FN} \]

Indica qué tan bien el modelo acierta en general.

  1. Sensibilidad (Recall o True Positive Rate)

Definición: Proporción de casos positivos correctamente identificados por el modelo.

Fórmula:

\[ \text{Sensibilidad} = \frac{VP}{VP + FN} \]

También se llama recall. Es importante cuando nos interesa no perder positivos reales, como sobrevivientes en Titanic.

  1. Especificidad (Specificity o True Negative Rate)

Definición: Proporción de casos negativos correctamente identificados por el modelo.

Fórmula:

\[ \text{Especificidad} = \frac{VN}{VN + FP} \]

Evalúa la capacidad del modelo para identificar correctamente los negativos.

  1. Precisión (Precision)

Definición: Proporción de predicciones positivas que realmente son positivas.

Fórmula:

\[ \text{Precisión} = \frac{VP}{VP + FP} \]

Útil cuando queremos que las predicciones positivas sean confiables.

Matriz de Confusión

La matriz de confusión muestra verdaderos positivos, falsos positivos, verdaderos negativos y falsos negativos, métricas clave en ML

library(caret) #Este paquete incluye muchas herramientas para machine learning, entre ellas la matriz de confusión y métricas de desempeño.

# Para data Training
ypred_train_factor <- as.factor(ypred_train)
data_train$survived <- as.factor(data_train$survived)
confusionMatrix(ypred_train_factor, data_train$survived, positive = "1")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 252  56
##          1  45 147
##                                           
##                Accuracy : 0.798           
##                  95% CI : (0.7601, 0.8323)
##     No Information Rate : 0.594           
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.5776          
##                                           
##  Mcnemar's Test P-Value : 0.3197          
##                                           
##             Sensitivity : 0.7241          
##             Specificity : 0.8485          
##          Pos Pred Value : 0.7656          
##          Neg Pred Value : 0.8182          
##              Prevalence : 0.4060          
##          Detection Rate : 0.2940          
##    Detection Prevalence : 0.3840          
##       Balanced Accuracy : 0.7863          
##                                           
##        'Positive' Class : 1               
## 
# Para data Test
ypred_test_factor <- as.factor(ypred_test)
data_test$survived <- as.factor(data_test$survived)
confusionMatrix(ypred_test_factor, data_test$survived, positive = "1")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 110  25
##          1  17  62
##                                           
##                Accuracy : 0.8037          
##                  95% CI : (0.7441, 0.8547)
##     No Information Rate : 0.5935          
##     P-Value [Acc > NIR] : 4.456e-11       
##                                           
##                   Kappa : 0.5873          
##                                           
##  Mcnemar's Test P-Value : 0.2801          
##                                           
##             Sensitivity : 0.7126          
##             Specificity : 0.8661          
##          Pos Pred Value : 0.7848          
##          Neg Pred Value : 0.8148          
##              Prevalence : 0.4065          
##          Detection Rate : 0.2897          
##    Detection Prevalence : 0.3692          
##       Balanced Accuracy : 0.7894          
##                                           
##        'Positive' Class : 1               
## 

La matriz de confusión permite evaluar precisión, sensibilidad y especificidad, esenciales para medir el desempeño de modelos de ML.

6. Visualización de resultados (curvas ROC y AUC)

Curva ROC y Área Bajo la Curva (AUC)

En problemas de clasificación binaria, además de medir la exactitud (accuracy), es muy útil analizar la capacidad del modelo para distinguir entre clases. Para esto usamos la Curva ROC (Receiver Operating Characteristic) y el AUC (Area Under the Curve).

Curva ROC

Área Bajo la Curva (AUC)

library(ROCR)

# Para data Training
#Convertimos a numérico para ROC
pred_area_train <- prediction(as.numeric(ypred_train), as.numeric(ytrue_train))
#Calculamos el área bajo la curva
auc_train <- as.numeric(performance(pred_area_train, "auc")@y.values)
#Curva ROC
pred_curva_train <- performance(pred_area_train, "tpr", "fpr")
plot(pred_curva_train, col="green", lwd=2,
     main=paste("Curva ROC - Data Training (AUC =", round(auc_train, 2), ")"),
     xlab="1 - Especificidad (FPR)", ylab="Sensibilidad (TPR)")
abline(a=0, b=1, lty=2, col="gray40")

# Test
#Convertimos a numérico para ROC
pred_area_test <- prediction(as.numeric(ypred_test), as.numeric(ytrue_test))
#Calculamos el área bajo la curva
auc_test <- as.numeric(performance(pred_area_test, "auc")@y.values)
#Curva ROC
pred_curva_test <- performance(pred_area_test, "tpr", "fpr")
plot(pred_curva_test, col="blue", lwd=2,
     main=paste("Curva ROC - Data Test (AUC =", round(auc_test, 2), ")"),
     xlab="1 - Especificidad (FPR)", ylab="Sensibilidad (TPR)")
abline(a=0, b=1, lty=2, col="gray40")

Curvas ROC combinadas: Training vs Test Visualizamos simultáneamente la curva ROC de entrenamiento y prueba para evaluar generalización.

plot(pred_curva_train, col="green", lwd=1,
     main="Curva ROC - Training vs Test",
     xlab="1 - Especificidad (FPR)", ylab="Sensibilidad (TPR)")
plot(pred_curva_test, col="red", lwd=1, add=TRUE)
abline(a=0, b=1, lty=2, col="gray40")

legend("bottomright",
       legend=c(paste("Training AUC =", round(auc_train,2)),
                paste("Test AUC =", round(auc_test,2))),
       col=c("green","red"), lwd=3)

Las curvas prácticamente se superponen → el modelo generaliza bien y no está sobreajustado.

Conclusión: Lo que aprendimos con Machine Learning

Este ejercicio muestra cómo aplicar Machine Learning supervisado para problemas de clasificación binaria, usando la regresión logística para predecir la supervivencia de los pasajeros del Titanic.

Puntos clave

  • Regresión logística efectiva: Nuestro modelo predice correctamente quién sobrevivió y quién no, demostrando que puede capturar patrones reales de los datos.
  • División entrenamiento/prueba: Separar los datos asegura que el modelo pueda generalizar a información nueva, evitando sobreajuste.
  • Validación con métricas: La matriz de confusión, junto con las curvas ROC y el AUC, confirma que el modelo tiene un buen desempeño en ambos conjuntos de datos.

Resultados destacados

  • Las curvas ROC del entrenamiento y prueba prácticamente se superponen, mostrando rendimiento consistente.
  • El AUC = 0.79, lo que indica que el modelo identifica correctamente la mayoría de los casos.
  • La exactitud (accuracy) también es alta, reforzando que las predicciones son confiables.

El modelo construido no solo aprende de los datos de entrenamiento, sino que también generaliza bien a nuevos datos, cumpliendo con uno de los principios fundamentales de Machine Learning supervisado: aprender patrones y aplicarlos a casos no vistos.

THANK YOU