library(caret)
library(tidyverse)
library(pROC)
library(MASS)
library(ggplot2)
set.seed(1500)
n <- 200
X1 <- rnorm(n, mean = 5, sd = 2)
X2 <- rnorm(n, mean = 10, sd = 3)
p <- 1 / (1 + exp(-(0.5*X1 - 0.7*X2 + 2)))
Y <- rbinom(n, 1, p)Taller 2 CD
REGRESIÓN LOGÍSTICA
La regresión logística es una técnica estadística fundamental en análisis de datos que permite modelar la probabilidad de que un evento ocurra en función de una o más variables predictoras. Este modelo es especialmente útil cuando la variable depenediente que queremos predecir es categórica y tiene solo dos posibles resultados (binaria), como “sí” o “no”, “éxito” o “fracaso”.
En esencia, la regresión logística establece una relación matemática entre las variables independientes (predictoras) y la probabilidad de que ocurra el evento de interés. Esta relación se expresa a través de una función logística, que transforma los valores de las variables predictoras en una probabilidad entre 0 y 1.
Considere una entrada \(X= x1, x2, x3, …, xn\), la regresión logística pretende encontrar una función h tal que podamos calcular
\[ y = \begin{cases} 1 & \text{si } h(X) \geq \text{umbral}, \\ 0 & \text{si } h(X) < \text{umbral} \end{cases} \]
- Por lo general el umbral se toma como un valor de 0.5
La función sigmoide, definida con valores [0,1]. Se escribe:
\[ \sigma (x) = \frac{1}{1+ e^{-x} } \]
Conceptos básicos
Variable dependiente: Es una variable binaria que toma el valor 1 o 0, donde 1 indica que el evento de interés ocurre y 0 indica que no ocurre.
Variables independientes: Son las variables explicativas (también llamadas regresores o predictores) que influyen en la probabilidad de que ocurra el evento.
La regresión logística usa la función sigmoide para modelar la probabilidad de ocurrencia del evento. La función sigmoide se expresa como:
\[P(Y = 1 | X) = \frac{1}{1 + e^{-(\beta_0 + \beta_1X_1 + \beta_2X_2 + ... + \beta_nX_n)}}\]
Donde:
\(P(Y = 1 | X)\) es la probabilidad de que el evento ocurra dado un conjunto de predictores \(X_1, X_2, ..., X_n\)
\(\beta_0, \beta_1, ..., \beta_n\) son los coeficientes que se estiman.
\(X_1, X_2, ..., X_n\) Son las variables independientes.
Estimación de los parametros del modelo
Función de verosimilitud
La estimación de los parámetros en la regresión logística se realiza comúnmente mediante el método de máxima verosimilitud. Este método busca encontrar los valores de los parámetros que maximizan la probabilidad de observar los datos dados esos parámetros.
El objetivo es encontrar los parámetros que maximicen la siguiente función de verosimilitud:
\[L(\beta) = \prod_{i=1}^{n} P(y_i | x_i)^{y_i}(1 - P(y_i | x_i))^{1 - y_i}\]
Donde \(y_i\) es el valor real de la variable dependiente (0 o 1) y \(P(y_i |x_i)\) es la probabilidad estimada por el modelo.
Optimización
Se utilizan algoritmos de optimización (como el método de Newton-Raphson o el descenso de gradiente) para encontrar los parámetros que maximizan la función de verosimilitud.
Predicciones
Una vez que los parámetros del modelo han sido estimados, la predicción se realiza calculando la probabilidad de que un nuevo conjunto de datos pertenezca a la clase 1 (evento):
\[\hat{P}(Y = 1 | X) = \frac{1}{1 + e^{-(\beta_0 + \beta_1X_1 + \beta_2X_2 + ... + \beta_nX_n)}}\]
Aquí, \(\hat{\beta_0}, \hat{\beta_1}, ..., \hat{\beta_n}\) son los coeficientes estimados, y la predicción final será la probabilidad de \(Y = 1\)
- Si esta probabilidad es mayor que el umbral (generalmente 0.5), se predice que el evento ocurrirá (clase 1), de lo contrario se predice la clase 0.
Evaluación del modelo
Matriz de confusión: Es una tabla que resume los resultados de las predicciones versus los valores reales. Incluye:
- Verdaderos Positivos (VP)
- Falsos Positivos (FP)
- Verdaderos Negativos (VN)
- Falsos Negativos (FN)
A partir de la matriz de confusión, se pueden calcular varias métricas como:
- Exactitud: proporción de predicciones correctas. Se calcula como:
\[EXACTITUD = \frac{VP+VN}{VP+VN+FP+FN}\]
- Sensibilidad: proporción de verdaderos positivos entre todos los casos positivos reales. Se calcula como:
\[SENSIBILIDAD = \frac{VP}{VP+FN}\]
- Precisión: Es la proporción de verdaderos positivos entre todas las predicciones positivas. Se calcula como:
\[PRESICIÓN = \frac{VP}{VP+FP}\]
- Curva ROC y AUC:
La curva ROC (Receiver Operating Characteristic) muestra la relación entre la tasa de verdaderos positivos (Recall) y la tasa de falsos positivos para diferentes umbrales.
El AUC (Area Under the Curve) mide el área bajo la curva ROC y da una idea general del rendimiento del modelo. Un valor de 1 indica un modelo perfecto, mientras que un valor de 0.5 indica un modelo aleatorio.
EJEMPLO DE APLICACIÓN
Simulación de muestra de 200 datos
División de datos
data <- data.frame(X1, X2, Y)
data$Y <- as.factor(data$Y)
data_train <- sample_frac(data, 0.7)
data_test <- setdiff(data, data_train)
data_test$Y <- as.factor(data_test$Y)Modelo de regresión logística
modelo <- glm(Y ~ X1 + X2, data = data_train, family = binomial)
summary(modelo)
Call:
glm(formula = Y ~ X1 + X2, family = binomial, data = data_train)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 0.2210 1.1359 0.195 0.845729
X1 0.5368 0.1595 3.365 0.000764 ***
X2 -0.5264 0.1167 -4.510 6.48e-06 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 137.295 on 139 degrees of freedom
Residual deviance: 92.443 on 137 degrees of freedom
AIC: 98.443
Number of Fisher Scoring iterations: 6
Predicción del modelo
predicciones <- predict(modelo, newdata = data_test , type = "response")
pred_clases <- ifelse(predicciones > 0.5, 1, 0)
pred_clases <- as.factor(pred_clases)Calcular AUC
probabilidades <- predict(modelo, newdata = data_test, type = "response")
roc_curve <- roc(data_test$Y, probabilidades)Setting levels: control = 0, case = 1
Setting direction: controls < cases
auc_value <- auc(roc_curve)
auc_valueArea under the curve: 0.9368
Matriz de confusión
matriz_confusion = confusionMatrix(pred_clases, reference = data_test$Y)
matriz_confusionConfusion Matrix and Statistics
Reference
Prediction 0 1
0 49 5
1 2 4
Accuracy : 0.8833
95% CI : (0.7743, 0.9518)
No Information Rate : 0.85
P-Value [Acc > NIR] : 0.3047
Kappa : 0.4697
Mcnemar's Test P-Value : 0.4497
Sensitivity : 0.9608
Specificity : 0.4444
Pos Pred Value : 0.9074
Neg Pred Value : 0.6667
Prevalence : 0.8500
Detection Rate : 0.8167
Detection Prevalence : 0.9000
Balanced Accuracy : 0.7026
'Positive' Class : 0
Graficos
library(ggplot2)
confusion_data <- as.data.frame(matriz_confusion$table)
colnames(confusion_data) <- c("Predicho", "Real", "Freq")
ggplot(confusion_data, aes(x = Predicho, y = Real)) +
geom_tile(aes(fill = Freq), color = "white") +
scale_fill_gradient(low = "white", high = "steelblue") +
geom_text(aes(label = Freq), vjust = 1) +
labs(title = "Matriz de Confusión", x = "Predicción", y = "Real")- Sensibilidad = 0.96
- Especificidad = 0.44
- Exactitud = 0.88
Los resultados obtenidos del modelo muestran una sensibilidad de 0.96, lo que indica que el modelo logró identificar correctamente el 96% de los casos positivos. Sin embargo, la especificidad es relativamente baja, con un valor de 0.44, lo que sugiere que solo el 44% de los casos negativos fueron clasificados correctamente. La exactitud del modelo es del 88%, lo que implica que, en promedio, el modelo clasificó correctamente el 88% de todos los casos. Estos resultados reflejan un alto desempeño en la identificación de positivos, aunque la capacidad para distinguir entre negativos es limitada, lo que podría ser un área de mejora para el modelo.
# Curva ROC
plot(roc_curve, main = "Curva ROC", col = "blue", lwd = 2)
abline(a = 0, b = 1, lty = 2, col = "red")
legend("bottomright", legend = paste("AUC =", round(auc_value, 2)), col = "blue", lwd = 2)- La curva azul muestra cómo cambia la sensibilidad en función de la especificidad a medida que se ajusta el umbral de clasificación del modelo. En este caso, la curva es bastante empinada hacia la esquina superior izquierda, lo que es una señal de que el modelo tiene un buen rendimiento en términos de clasificar correctamente las observaciones de ambas clases
data_test$Probabilidad_Predicha <- probabilidades
ggplot(data_test, aes(x = Probabilidad_Predicha, y = as.numeric(as.character(Y)))) +
geom_point(alpha = 0.5) +
geom_jitter(width = 0.02) +
labs(title = "Comparación de Probabilidades Predichas vs Valores Reales",
x = "Probabilidad Predicha",
y = "Valor Real (0 o 1)") +
scale_y_continuous(breaks = c(0, 1), labels = c("No", "Sí")) + theme_minimal()- Esta gráfica nos permite visualizar cómo se comporta el modelo al predecir las probabilidades de ocurrencia de las clases. Aunque hay una cierta cantidad de errores (falsos positivos y falsos negativos), el modelo parece tener un buen rendimiento en la predicción de la clase “No” (Y = 0). Sin embargo, el desempeño en la predicción de la clase “Sí” (Y = 1) podría mejorarse, ya que algunas observaciones con probabilidad predicha baja deberían haber sido clasificadas correctamente como “Sí”.
ANALISIS DISCRIMINANTE LINEAL (LDA)
El Análisis Discriminante Lineal (LDA) es un método estadístico y de aprendizaje automático que se utiliza para la clasificación de datos y la reducción de dimensionalidad.
Su principal objetivo es encontrar una combinación lineal de características que maximice la separabilidad entre diferentes clases. Esto se logra proyectando los datos en un espacio de menor dimensión, donde se busca que las medias de las clases estén lo más distantes posible, mientras que la varianza dentro de cada clase se minimiza.
Conceptos básicos
Función Discriminante: LDA utiliza una función discriminante que permite proyectar los datos en una dimensión donde las clases están separadas de manera óptima. Esta proyección se realiza buscando maximizar la varianza entre clases y minimizar la varianza dentro de cada clase.
Varianza entre Clases y Varianza dentro de Clases:
Varianza entre Clases: Refleja la distancia entre las medias de las diferentes clases. LDA se enfoca en maximizar esta varianza.
Varianza dentro de Clases: Representa la variabilidad de los datos dentro de cada clase. LDA busca minimizar esta variabilidad para lograr una mejor compactación de los datos dentro de cada clase.
Hipótesis del Modelo: LDA asume que las clases siguen una distribución normal (gaussiana) con la misma matriz de covarianza, pero con medias diferentes. Esta suposición facilita el cálculo de la probabilidad de que un nuevo punto de datos pertenezca a una clase específica.
Reducción de Dimensionalidad: El LDA se utiliza no solo para clasificar, sino también para reducir la dimensionalidad de los datos, lo que ayuda a evitar el sobreajuste y a disminuir los costos computacionales. Esto es especialmente útil en situaciones donde el número de características es alto en relación con el número de muestras.
Estimación de parametros
En LDA es necesario estimar los siguientes parametros:
Medias \((\mu_k)\): La media de los predictores para cada clase k, estimada como el promedio de cada predictor dentro de las observaciones de entrenamiento de esa clase.
Priors \(\pi_k\): Estas son las probabilidades de que una observación pertenezca a una clase antes de observar los datos, calculadas como la proporción de observaciones de cada clase en el conjunto de entrenamiento.
Matriz de covarianza \((\sum)\): Dado que LDA asume una covarianza igual entre clases, \((\sum)\) se calcula como un promedio ponderado de las matrices de covarianza de muestra de cada clase
\[\Sigma = \frac{1}{N - K} \sum_{k=1}^{K} \sum_{i \in C_k} (x_i - \mu_k)(x_i - \mu_k)^T\]
Donde:
- \(N\) es el número total de muestras
- \(K\) es el número de clases
- \(x_i\) es un punto de datos
- \(C_k\) representa el conjunto de datos de la clase \(k\)
Predicciones
Para clasificar una nueva observación, LDA calcula un puntaje, llamado función discriminante, para cada clase y asigna la observación a la clase con el puntaje más alto. Para un solo predictor, esta función puede expresarse como:
\[\delta_k(x) = x \cdot \frac{\mu_k}{\sigma^2} - \frac{\mu_k^2}{2 \sigma^2} + \log(\pi_k)\]
Para múltiples predictores, la función discriminante se convierte en una combinación lineal de los predictores, dada por:
\[\delta_k(x) = x^T \Sigma^{-1} \mu_k - \frac{1}{2} \mu_k^T \Sigma^{-1} \mu_k + \log(\pi_k)\]
Donde:
- \(\mu_k\) es la media de la clase \(k\)
- \(\sum\) es la matriz de covarianza compartida.
- \(\pi_k\) es la probabilidad a priori de la clase \(k\)
El modelo asigna el punto \(x\) a la clase con la función discriminante más alta.
Evaluación del modelo
Matriz de Confusión: Esta matriz resume las predicciones del modelo frente a las etiquetas de clase reales, mostrando Verdaderos Positivos, Verdaderos Negativos, Falsos Positivos y Falsos Negativos.
Métricas: A partir de la matriz de confusión, se pueden calcular métricas como precisión, sensibilidad y especificidad
\[EXACTITUD = \frac{VP+VN}{VP+VN+FP+FN}\]
\[SENSIBILIDAD = \frac{VP}{VP+FN}\]
\[PRESICIÓN = \frac{VP}{VP+FP}\]
\[ESPECIFICIDAD = \frac{TN}{TN + FP}\]
- Tasa de Error: La tasa de error de LDA se compara frecuentemente con la de otros modelos o con la tasa de error del clasificador de Bayes. El clasificador de Bayes tiene la menor tasa de error bajo el supuesto de que las suposiciones de distribución se cumplan. LDA intenta aproximarse a esta tasa
Ejemplo de aplicación
Simulamos muestra de 200 datos
set.seed(1500)
n <- 200
X1_class1 <- rnorm(n/2, mean = 5, sd = 2)
X2_class1 <- rnorm(n/2, mean = 10, sd = 3)
X1_class2 <- rnorm(n/2, mean = 7, sd = 2)
X2_class2 <- rnorm(n/2, mean = 12, sd = 3)
x1 <- c(X1_class1, X1_class2)
x2 <- c(X2_class1, X2_class2)
y <- as.factor(c(rep(0, n/2), rep(1, n/2)))
data2 <- data.frame(x1, x2, y)Dividimos los datos
data2_train <- sample_frac(data2, 0.7)
data2_test <- setdiff(data2, data2_train)Modelo LDA
lda_modelo <- lda(y ~ x1 + x2, data = data2_train)Predicciones
predicciones2 <- predict(lda_modelo, newdata = data2_test)
pred2_clases <- predicciones2$class
pred2_clases <- as.factor(pred2_clases)
data2_test$y <- as.factor(data2_test$y)Matriz de confusión
conf_matrix <- confusionMatrix(pred2_clases, reference = data2_test$y)
conf_matrixConfusion Matrix and Statistics
Reference
Prediction 0 1
0 20 8
1 11 21
Accuracy : 0.6833
95% CI : (0.5504, 0.7974)
No Information Rate : 0.5167
P-Value [Acc > NIR] : 0.006575
Kappa : 0.3681
Mcnemar's Test P-Value : 0.646355
Sensitivity : 0.6452
Specificity : 0.7241
Pos Pred Value : 0.7143
Neg Pred Value : 0.6562
Prevalence : 0.5167
Detection Rate : 0.3333
Detection Prevalence : 0.4667
Balanced Accuracy : 0.6846
'Positive' Class : 0
confusion_data2 <- as.data.frame(conf_matrix$table)
colnames(confusion_data2) <- c("Predicho", "Real", "Freq")
ggplot(confusion_data2, aes(x = Predicho, y = Real)) +
geom_tile(aes(fill = Freq), color = "white") +
scale_fill_gradient(low = "white", high = "steelblue") +
geom_text(aes(label = Freq), vjust = 1) +
labs(title = "Matriz de Confusión", x = "Predicción", y = "Real")Sensibilidad = 0.6452
Especificidad = 0.7241
Exactitud = 0.68
Los resultados obtenidos del modelo indican una sensibilidad de 0.6452, lo que significa que el modelo fue capaz de identificar correctamente el 64.52% de los casos positivos. La especificidad fue de 0.7241, lo que refleja que el 72.41% de los casos negativos fueron clasificados correctamente. En términos generales, la exactitud del modelo es del 68%, lo que sugiere que, en promedio, el modelo clasificó correctamente el 68% de los casos totales. Estos resultados indican un desempeño moderado del modelo, con margen de mejora tanto en la identificación de positivos como de negativos.
Graficas
roc_curve2 <- roc(data2_test$y, as.numeric(predicciones2$class))
auc_value2 <- auc(roc_curve2)
plot(roc_curve2, main = "Curva ROC", col = "blue", lwd = 2)
abline(a = 0, b = 1, lty = 2, col = "red")
legend("bottomright", legend = paste("AUC =", round(auc_value2, 2)), col = "blue", lwd = 2)- Este gráfico ROC sugiere que el modelo ajustado podría tener problemas para distinguir adecuadamente entre las clases. La curva no se aproxima mucho al punto (0,1), lo que refleja que tanto la sensibilidad como la especificidad no son muy altas, y el modelo no está proporcionando predicciones significativamente mejores que una predicción aleatoria.
data2_test |>
ggplot(aes(x = predicciones2$posterior[, 2], y = as.numeric(as.factor(y)))) +
geom_point() +
labs(title = "Probabilidades Predichas vs. Valores Reales",
x = "Probabilidad Predicha",
y = "Valor Real (0 o 1)") +
scale_y_continuous(breaks = c(1, 2), labels = c("Clase 0", "Clase 1")) +
theme_minimal()- El gráfico muestra que el modelo tiene un buen desempeño general, ya que la mayoría de los puntos de la clase 0 tienen probabilidades predichas bajas (cerca de 0) y la mayoría de los puntos de la clase 1 tienen probabilidades altas (cerca de 1).
Bibliografía
Daniel. (2021, diciembre 16). ¿Qué es la regresión logística? Formación en ciencia de datos | Datascientest.com; DataScientest. https://datascientest.com/es/que-es-la-regresion-logistica
Fiuza, & Jc, R. P. (2000). La regresión logística: una herramienta versátil. Nefrologia: publicacion oficial de la Sociedad Espanola Nefrologia, 20(6), 495–500. https://revistanefrologia.com/es-la-regresion-logistica-una-herramienta-articulo-X0211699500035664
RPubs - REGRESIÓN LOGISTICA. (s/f). Rpubs.com. Recuperado el 13 de octubre de 2024, de https://rpubs.com/HOM05/RL1
James, G., D. Witten, T. Hastie, R. Tibshirani, y J. Taylor. 2021. An Introduction to Statistical Learning: with Applications in R. Springer Texts en Statistics. Springer International Publishing.