El análisis discriminante lineal (LDA) es una técnica estadística multivariada que permite clasificar observaciones en grupos predefinidos a partir de un conjunto de variables cuantitativas. En el contexto de la salud mental y las redes sociales, esta técnica resulta especialmente útil para identificar patrones de comportamiento en usuarios de plataformas como X (antes Twitter) que permitan distinguir entre perfiles con indicios de depresión y perfiles sin ellos.
En este análisis se estudia una base de datos de usuarios de Twitter, donde la variable objetivo clasifica a cada usuario en dos grupos:
El objetivo es determinar si las variables numéricas disponibles en la base permiten discriminar adecuadamente entre ambos grupos mediante un análisis discriminante lineal.
# knitr::opts_chunk$set(echo = TRUE)
library(readxl)
BD_Twitter <- read_excel("/Users/veronicapichardo/Desktop/AM/Bases examen/Mental-Health-Twitter.xlsx")Se verifica que los datos se cargaron correctamente observando las primeras filas y la estructura de la base.
## tibble [20,000 × 7] (S3: tbl_df/tbl/data.frame)
## $ ID : num [1:20000] 0 1 2 3 4 5 6 7 8 9 ...
## $ followers : num [1:20000] 84 84 84 84 84 84 84 84 84 84 ...
## $ friends : num [1:20000] 211 211 211 211 211 211 211 211 211 211 ...
## $ favourites: num [1:20000] 251 251 251 251 251 251 251 251 251 251 ...
## $ statuses : num [1:20000] 837 837 837 837 837 837 837 837 837 837 ...
## $ retweets : num [1:20000] 0 1 0 2 1 1 1 0 0 41 ...
## $ label : chr [1:20000] "Con_depresion" "Con_depresion" "Con_depresion" "Con_depresion" ...
## [1] 20000 7
## [1] "ID" "followers" "friends" "favourites" "statuses"
## [6] "retweets" "label"
La variable que indica si el usuario presenta depresión o no es la
variable de clasificación del análisis. Se convierte a factor y la base
de datos se transforma a data.frame para garantizar
compatibilidad con las funciones del análisis discriminante.
# Identificar la columna de clasificación — ajustar el nombre si es diferente
# En esta base la variable de grupo es "label" (0 = sin depresión, 1 = con depresión)
BD_Twitter$label <- as.factor(BD_Twitter$label)
BD_Twitter <- as.data.frame(BD_Twitter)
str(BD_Twitter)## 'data.frame': 20000 obs. of 7 variables:
## $ ID : num 0 1 2 3 4 5 6 7 8 9 ...
## $ followers : num 84 84 84 84 84 84 84 84 84 84 ...
## $ friends : num 211 211 211 211 211 211 211 211 211 211 ...
## $ favourites: num 251 251 251 251 251 251 251 251 251 251 ...
## $ statuses : num 837 837 837 837 837 837 837 837 837 837 ...
## $ retweets : num 0 1 0 2 1 1 1 0 0 41 ...
## $ label : Factor w/ 2 levels "Con_depresion",..: 1 1 1 1 1 1 1 1 1 1 ...
## ID followers friends favourites
## Min. : 0 Min. : 0.0 Min. : 0.0 Min. : 0
## 1st Qu.: 5000 1st Qu.: 177.0 1st Qu.: 211.0 1st Qu.: 243
## Median :10000 Median : 476.0 Median : 561.0 Median : 2752
## Mean :10000 Mean : 900.5 Mean : 782.4 Mean : 6398
## 3rd Qu.:14999 3rd Qu.: 1197.0 3rd Qu.: 701.0 3rd Qu.: 8229
## Max. :19999 Max. :28614.0 Max. :28514.0 Max. :39008
## statuses retweets label
## Min. : 3 Min. : 0 Con_depresion:10000
## 1st Qu.: 5129 1st Qu.: 0 Sin_depresion:10000
## Median : 13251 Median : 0
## Mean : 44394 Mean : 1438
## 3rd Qu.: 52892 3rd Qu.: 1
## Max. :1063601 Max. :839540
Interpretación: El resumen estadístico permite conocer cómo se comportan las variables de actividad de los 20,000 usuarios de Twitter analizados.
La base de datos está perfectamente balanceada:
\[ \text{Con depresión} = 10{,}000 \quad \text{usuarios} \]
\[ \text{Sin depresión} = 10{,}000 \quad \text{usuarios} \]
Esto significa que la mitad de los usuarios en la base presentan indicios de depresión, lo cual es importante porque garantiza que el modelo no esté sesgado hacia ningún grupo al momento de aprender a clasificar.
En cuanto a la variable followers (seguidores), el promedio es de aproximadamente 900 seguidores por usuario, pero el valor máximo llega a 28,614. Esta diferencia tan grande entre la media y el máximo indica que la mayoría de los usuarios tienen relativamente pocos seguidores, pero existe un grupo reducido de usuarios con una audiencia considerablemente mayor. Este tipo de distribución asimétrica es muy común en redes sociales.
La variable friends (cuentas seguidas) tiene un promedio de 782, con un máximo de 28,514. Esto muestra que el comportamiento de seguir cuentas también varía mucho entre usuarios: algunos siguen a miles de personas, mientras que la mayoría sigue a una cantidad moderada.
La variable favourites (publicaciones marcadas como favoritas) tiene un promedio de 6,398, pero puede llegar hasta 39,008. Esto indica que algunos usuarios interactúan de forma muy activa con el contenido de otros, mientras que muchos tienen una actividad más moderada en este aspecto.
La variable statuses (publicaciones realizadas) es la que presenta mayor variabilidad. Su media es de 44,394 publicaciones, pero el máximo asciende a 1,063,601. Esto revela que existe una minoría de usuarios extremadamente activos que han publicado cantidades masivas de contenido, mientras que la mayoría tiene una actividad mucho más moderada.
Por último, la variable retweets tiene una mediana de 0, lo que significa que la mitad de los usuarios no ha retuiteado contenido en absoluto. Sin embargo, el promedio de 1,438 y el máximo de 839,540 indican que unos pocos usuarios retuitean de forma muy intensa, elevando considerablemente el promedio.
En conjunto, el resumen muestra que la actividad en Twitter varía enormemente entre usuarios, con la presencia de valores muy extremos en casi todas las variables. Esta alta variabilidad puede ser útil para distinguir patrones entre usuarios con y sin depresión.
# Seleccionar únicamente variables numéricas para el análisis
vars_numericas <- names(BD_Twitter)[sapply(BD_Twitter, is.numeric)]
vars_numericas## [1] "ID" "followers" "friends" "favourites" "statuses"
## [6] "retweets"
## ID followers friends favourites statuses retweets
## 199990000 18009679 15648575 127964711 887888392 28758546
Interpretación: La función colSums()
permite obtener el total acumulado de cada variable considerando los
20,000 usuarios de la base de datos.
\[ n = 20{,}000 \text{ usuarios} \]
Los resultados obtenidos fueron:
\[ \sum \text{followers} = 18{,}009{,}679 \]
\[ \sum \text{friends} = 15{,}648{,}575 \]
\[ \sum \text{favourites} = 127{,}964{,}711 \]
\[ \sum \text{statuses} = 887{,}888{,}392 \]
\[ \sum \text{retweets} = 28{,}758{,}546 \]
Estos valores reflejan el volumen total de actividad acumulada en la base de datos. La variable statuses es la que concentra la mayor suma total, con casi 888 millones de publicaciones entre todos los usuarios. Esto confirma que publicar en Twitter es la forma de interacción más frecuente en esta comunidad.
Por su parte, favourites acumula más de 127 millones de marcas de favorito en total, lo que indica que los usuarios también consumen e interactúan activamente con el contenido de otros.
Los retweets acumulan casi 29 millones en total, una cifra menor en comparación con statuses y favourites, lo que sugiere que compartir publicaciones de otros es una actividad menos frecuente que publicar o dar favorito.
Es importante considerar que estas sumas son el resultado de sumar los datos de 20,000 usuarios, por lo que valores grandes simplemente reflejan la magnitud de la muestra analizada.
resumen_completo_twitter <- function() {
resumen_general <- summary(BD_Twitter)
datos_numericos <- BD_Twitter[, sapply(BD_Twitter, is.numeric)]
media <- colMeans(datos_numericos, na.rm = TRUE)
desviacion <- apply(datos_numericos, 2, sd, na.rm = TRUE)
varianza <- apply(datos_numericos, 2, var, na.rm = TRUE)
estadisticos <- data.frame(
Variable = names(media),
Media = media,
Desviacion_Estandar = desviacion,
Varianza = varianza,
row.names = NULL
)
return(list(
Resumen = resumen_general,
Estadisticos = estadisticos
))
}
resultado_twitter <- resumen_completo_twitter()
resultado_twitter$Resumen## ID followers friends favourites
## Min. : 0 Min. : 0.0 Min. : 0.0 Min. : 0
## 1st Qu.: 5000 1st Qu.: 177.0 1st Qu.: 211.0 1st Qu.: 243
## Median :10000 Median : 476.0 Median : 561.0 Median : 2752
## Mean :10000 Mean : 900.5 Mean : 782.4 Mean : 6398
## 3rd Qu.:14999 3rd Qu.: 1197.0 3rd Qu.: 701.0 3rd Qu.: 8229
## Max. :19999 Max. :28614.0 Max. :28514.0 Max. :39008
## statuses retweets label
## Min. : 3 Min. : 0 Con_depresion:10000
## 1st Qu.: 5129 1st Qu.: 0 Sin_depresion:10000
## Median : 13251 Median : 0
## Mean : 44394 Mean : 1438
## 3rd Qu.: 52892 3rd Qu.: 1
## Max. :1063601 Max. :839540
Interpretación:
El resumen estadístico detallado muestra la media, desviación estándar y varianza de cada variable numérica.
En cuanto a las medias, la variable statuses presenta el promedio más alto:
\[ \bar{x}_{\text{statuses}} = 44{,}394 \]
lo que indica que, en promedio, cada usuario ha realizado más de 44 mil publicaciones. Esto refleja que los usuarios de esta base son relativamente activos en la plataforma.
La variable retweets tiene una media de:
\[ \bar{x}_{\text{retweets}} = 1{,}438 \]
aunque su mediana es 0, lo que confirma que esta media está fuertemente influenciada por usuarios con comportamientos extremos.
Respecto a la variabilidad, statuses presenta la mayor varianza:
\[ s^2_{\text{statuses}} = 19{,}818{,}591{,}468 \]
lo que indica que la cantidad de publicaciones varía enormemente entre usuarios. Algunos publican miles o incluso millones de tweets, mientras que otros apenas han comenzado a usar la plataforma.
La variable retweets también muestra una varianza muy alta:
\[ s^2_{\text{retweets}} = 228{,}604{,}273 \]
lo cual confirma que el comportamiento de retuitear es muy heterogéneo: la mayoría de los usuarios no retuitean nada, mientras que un grupo reducido retuitea de forma masiva.
La variable followers y friends presentan varianzas similares y considerables, lo que indica que la cantidad de seguidores y cuentas seguidas también varía bastante entre los usuarios de la base.
En el contexto de salud mental, esta alta variabilidad en el comportamiento digital puede ser relevante, ya que patrones de actividad extrema (ya sea muy alta o muy baja) en redes sociales se han asociado en estudios previos con estados de salud mental alterados.
## ID followers friends favourites statuses
## ID 33335000.0 258678.29 -1456955.3 4343686 2.790108e+08
## followers 258678.3 3609673.06 3109224.6 -259003 -5.745527e+04
## friends -1456955.3 3109224.65 3366556.9 -1259019 -1.173205e+07
## favourites 4343685.5 -259002.98 -1259018.5 70443673 -6.372123e+07
## statuses 279010823.1 -57455.27 -11732047.9 -63721226 1.981859e+10
## retweets 898143.9 43092.34 275906.7 8826048 -1.105258e+07
## retweets
## ID 898143.85
## followers 43092.34
## friends 275906.66
## favourites 8826048.37
## statuses -11052578.69
## retweets 228604273.27
Interpretación:
La matriz de covarianza permite analizar cómo varían las variables de manera conjunta entre los 20,000 usuarios.
Las varianzas de cada variable, ubicadas en la diagonal, confirman lo observado en el resumen estadístico:
\[ Var(\text{statuses}) = 19{,}818{,}591{,}468 \]
\[ Var(\text{retweets}) = 228{,}604{,}273 \]
\[ Var(\text{favourites}) = 70{,}443{,}673 \]
Estas varianzas enormes reflejan que el comportamiento de los usuarios en la plataforma es muy dispar. No existe un perfil único de usuario de Twitter: las diferencias entre un usuario poco activo y uno extremadamente activo son abismales.
En cuanto a las covarianzas fuera de la diagonal:
La covarianza entre followers y friends es positiva y alta:
\[ Cov(\text{followers}, \text{friends}) = 3{,}109{,}225 \]
Esto indica que los usuarios con más seguidores también tienden a seguir a más personas. Es un patrón lógico en redes sociales donde la reciprocidad en las conexiones es común.
La covarianza entre statuses y friends es negativa:
\[ Cov(\text{statuses}, \text{friends}) = -11{,}732{,}048 \]
Esto sugiere que los usuarios que publican más contenido tienden a seguir a menos cuentas. En el contexto de esta base, podría indicar que los usuarios con alta actividad publicadora tienen un perfil más cerrado o enfocado, mientras que los usuarios que siguen muchas cuentas publican menos.
La covarianza entre statuses y favourites también es negativa:
\[ Cov(\text{statuses}, \text{favourites}) = -63{,}721{,}226 \]
Este resultado es llamativo: los usuarios que más publican son los que menos marcan publicaciones como favoritas. Esto puede indicar que los usuarios con depresión o con alta actividad compulsiva en la plataforma priorizan producir contenido por encima de consumirlo.
mi_colores_tw <- c("pink", "purple")
colores_tw <- mi_colores_tw[as.numeric(BD_Twitter$label)]
pairs(X_twitter,
col = colores_tw,
pch = 19,
main = "Diagramas de dispersión por grupo de salud mental")
legend("topright",
legend = levels(BD_Twitter$label),
col = mi_colores_tw,
pch = 19)Interpretación: Los diagramas de dispersión muestran la relación entre las variables de actividad en Twitter, diferenciando a los usuarios con depresión (rosa) y sin depresión (morado).
En general, se observa que los puntos de ambos grupos aparecen muy concentrados cerca del origen en la mayoría de los gráficos, con algunos valores extremos dispersos hacia arriba o hacia la derecha. Esto confirma la alta asimetría de los datos observada en el resumen estadístico.
En los gráficos que involucran la variable ID se aprecia una separación clara entre los dos grupos, ya que el ID simplemente representa el orden en que los usuarios aparecen en la base de datos: los usuarios con depresión tienen IDs bajos (0 a 9,999) y los sin depresión tienen IDs altos (10,000 a 19,999). Esto significa que la variable ID no aporta información real sobre el comportamiento del usuario y debe tomarse con cautela en el análisis.
En las demás variables como followers, friends, favourites, statuses y retweets, los puntos de ambos grupos se superponen considerablemente en la zona de valores bajos, lo que indica que la mayoría de los usuarios, independientemente de si presentan depresión o no, tienen niveles de actividad similares y moderados.
Sin embargo, los valores extremos (los puntos más alejados del origen) tienden a pertenecer al grupo Sin depresión (morado), especialmente en variables como statuses y retweets. Esto podría sugerir que los usuarios sin depresión presentan comportamientos más activos y variables en la plataforma, aunque la separación no es completamente clara y se requiere el análisis discriminante para confirmar si estas diferencias son estadísticamente relevantes.
La prueba de Box’s M evalúa si las matrices de covarianza de los grupos son iguales. Las hipótesis del contraste son:
\[ H_0 : \text{Las matrices de covarianza de los grupos son iguales} \]
\[ H_1 : \text{Al menos una matriz de covarianza es diferente} \]
## Loading required package: MASS
## ---
## biotools version 4.3
##
## Box's M-test for Homogeneity of Covariance Matrices
##
## data: BD_Twitter[, sapply(BD_Twitter, is.numeric)]
## Chi-Sq (approx.) = 85110, df = 21, p-value < 2.2e-16
Interpretación: Los resultados de la prueba Box’s M fueron:
\[ \chi^2 = 85{,}110 \]
\[ gl = 21 \]
\[ p\text{-valor} < 2.2 \times 10^{-16} \]
Dado que:
\[ p < 0.05 \]
se rechaza la hipótesis nula \(H_0\).
Esto significa que las matrices de covarianza de los dos grupos (Con depresión y Sin depresión) no son iguales. En otras palabras, la forma en que varían y se relacionan las variables de actividad en Twitter es diferente entre los usuarios con depresión y los usuarios sin depresión.
Desde el punto de vista de la salud mental, este resultado es relevante porque indica que no se trata solo de que los usuarios con depresión tengan más o menos seguidores, o publiquen más o menos. La estructura completa de su comportamiento digital —cómo se relacionan entre sí todas sus variables de actividad— es distinta a la de los usuarios sin depresión.
Este resultado confirma que existen diferencias en los patrones de comportamiento digital entre ambos grupos, aunque el supuesto de homocedasticidad no se cumple, por lo que los resultados del análisis discriminante lineal deben interpretarse con cierta precaución.
Elipses de covarianza
## Loading required package: broom
##
## Attaching package: 'heplots'
## The following object is masked from 'package:biotools':
##
## boxM
covEllipses(
BD_Twitter[, sapply(BD_Twitter, is.numeric)],
BD_Twitter$label,
variables = c(1, 2),
fill = TRUE,
alpha = 0.3,
col = c("#F472B6", "#A855F7"),
lwd = 2,
main = "Elipses de covarianza por grupo de salud mental"
)## Warning in plot.window(...): "alpha" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "alpha" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "alpha" is not a
## graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "alpha" is not a
## graphical parameter
## Warning in box(...): "alpha" is not a graphical parameter
## Warning in title(...): "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
Interpretación: Las elipses representan la dispersión conjunta de las variables ID y followers para cada grupo de usuarios.
Se observan diferencias claras en la forma y posición de las elipses:
La elipse del grupo Con depresión (rosa) es más grande y circular, lo que indica que los usuarios con depresión presentan mayor variabilidad en la cantidad de seguidores, abarcando desde usuarios con muy pocos hasta algunos con varios miles de seguidores.
La elipse del grupo Sin depresión (morado) es más pequeña y achatada horizontalmente, lo que indica que estos usuarios están más concentrados en un rango de seguidores más estrecho, con menor dispersión en esta variable.
Ambas elipses se traslapan en la zona central del gráfico, lo que confirma que no existe una separación perfecta entre los dos grupos al analizar únicamente estas dos variables. Es decir, conocer solo el ID y la cantidad de seguidores de un usuario no es suficiente para determinar con certeza si presenta depresión o no.
Las diferencias en tamaño y orientación entre las elipses confirman el rechazo del supuesto de igualdad de matrices de covarianza obtenido en la prueba Box’s M:
\[ H_0: \Sigma_{\text{Con depresión}} = \Sigma_{\text{Sin depresión}} \]
con \(p < 2.2 \times 10^{-16}\), lo que indica que los patrones de variabilidad son estructuralmente distintos entre ambos grupos.
Las hipótesis son:
\[ H_0 : \text{La variable sigue una distribución normal} \]
\[ H_1 : \text{La variable no sigue una distribución normal} \]
Nota Se utiliza una muestra aleatoria de 5000 observaciones porque el test de Shapiro-Wilk solo es válido para tamaños de muestra entre 3 y 5000. Dado que el dataset original contiene 20000 datos por variable, se toma una submuestra para poder aplicar el test correctamente sin violar sus supuestos.
X_twitter_num <- BD_Twitter[, sapply(BD_Twitter, is.numeric)]
lapply(X_twitter_num, function(x) {
x <- na.omit(x)
x_sample <- sample(x, 5000)
shapiro.test(x_sample)
})## $ID
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.95185, p-value < 2.2e-16
##
##
## $followers
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.29587, p-value < 2.2e-16
##
##
## $friends
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.20742, p-value < 2.2e-16
##
##
## $favourites
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.73591, p-value < 2.2e-16
##
##
## $statuses
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.24105, p-value < 2.2e-16
##
##
## $retweets
##
## Shapiro-Wilk normality test
##
## data: x_sample
## W = 0.064661, p-value < 2.2e-16
Interpretación: Se toma la decisión con base en el p-valor:
\[ \text{Si } p < 0.05 \Rightarrow \text{se rechaza } H_0 \text{ (la variable no es normal)} \]
\[ \text{Si } p > 0.05 \Rightarrow \text{no se rechaza } H_0 \text{ (la variable puede ser normal)} \]
Variable ID
\[ W = 0.9544, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). El ID no sigue una distribución normal. Esto es esperado, ya que el ID es simplemente un número de orden que va de 0 a 19,999 y refleja la posición del usuario en la base de datos, no una característica del comportamiento en Twitter. Por ello, esta variable no debe utilizarse como variable explicativa real en el análisis discriminante.
Variable followers
\[ W = 0.2619, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). La cantidad de seguidores no sigue una distribución normal. Esto es característico de las redes sociales: la mayoría de los usuarios tienen pocos seguidores, mientras que una minoría concentra una audiencia muy grande. Esta distribución altamente asimétrica es la norma en plataformas como Twitter, donde la popularidad no se distribuye de forma equitativa.
Variable friends
\[ W = 0.2054, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). La cantidad de cuentas seguidas tampoco sigue una distribución normal, y presenta la mayor desviación de la normalidad entre todas las variables (W más bajo). Esto indica que la mayoría de los usuarios siguen un número moderado de cuentas, pero existe una minoría que sigue a miles de personas, generando una distribución muy concentrada en valores bajos con una cola larga hacia la derecha.
Variable favourites
\[ W = 0.7378, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). Los favoritos no siguen una distribución normal, aunque su valor de W es mayor que el de followers y friends, lo que indica que su distribución se acerca más a la normal que las anteriores. Aun así, existen usuarios que han marcado decenas de miles de publicaciones como favoritas, mientras que muchos otros apenas interactúan de esta manera.
Variable statuses
\[ W = 0.2445, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). Las publicaciones totales no siguen una distribución normal. Esta es la variable con más variabilidad en toda la base: hay usuarios con apenas tres publicaciones y otros con más de un millón. Esta distribución tan extrema sugiere que la actividad publicadora en Twitter está muy concentrada en un grupo reducido de usuarios muy activos, mientras que la mayoría tiene una presencia más discreta en la plataforma.
Variable retweets
\[ W = 0.0602, \quad p < 2.2 \times 10^{-16} \]
Se rechaza \(H_0\). Los retweets presentan la distribución más alejada de la normalidad de toda la base (W = 0.06, el valor más bajo). Esto se explica porque la mediana de retweets es 0: la mayoría de los usuarios no retuitea absolutamente nada, mientras que unos pocos retuitean cientos de miles de veces. En el contexto de salud mental, un comportamiento de retuiteo extremo puede ser señal de uso compulsivo de la plataforma o de búsqueda intensa de validación social.
Conclusión general
Ninguna de las variables de la base de datos sigue una distribución normal. Todas presentan distribuciones altamente asimétricas con colas largas hacia la derecha, lo cual es un patrón característico del comportamiento en redes sociales. Aunque este resultado indica que el supuesto de normalidad del LDA no se cumple, el análisis discriminante lineal es suficientemente robusto para muestras grandes como esta (\(n = 20{,}000\)), por lo que sus resultados siguen siendo válidos e interpretables.
vars_num <- names(X_twitter_num)
n_vars <- length(vars_num)
n_cols <- 2
n_rows <- ceiling(n_vars / n_cols)
par(mfrow = c(n_rows, n_cols),
col.main = "#3CB371",
col.lab = "black",
cex.main = 1.2)
colores_qq <- c("#40E0D0", "#7CCD7C", "#FFBBFF", "#FA8072",
"#87CEEB", "#FFD700", "#DDA0DD", "#98FB98")
for (i in seq_along(vars_num)) {
col_i <- colores_qq[(i - 1) %% length(colores_qq) + 1]
qqnorm(X_twitter_num[[ vars_num[i] ]],
main = paste("QQ Plot -", vars_num[i]),
pch = 19,
col = col_i)
qqline(X_twitter_num[[ vars_num[i] ]], col = "red", lwd = 2)
}Interpretación: Los gráficos Q-Q permiten visualizar de forma gráfica qué tan alejada está cada variable de una distribución normal.
En el gráfico de la variable ID los puntos siguen la línea roja de forma razonablemente aceptable en la parte central, aunque se desvían en los extremos. Esto confirma que el ID tiene una distribución aproximadamente uniforme (como se esperaría de un número de orden), no normal.
En las variables followers, friends, statuses y retweets se observa que la gran mayoría de los puntos se acumulan en la parte inferior izquierda del gráfico, muy por debajo de la línea roja, con solo unos pocos puntos que se disparan hacia arriba en el extremo derecho. Este patrón es la firma visual de una distribución con una cola derecha muy larga: la mayoría de los usuarios tienen valores muy bajos, pero existe un grupo reducido con valores extremadamente altos.
En la variable favourites se observa una desviación moderada de la línea roja, especialmente en la parte superior derecha, donde los puntos se elevan por encima de la línea. Esto indica una concentración de usuarios con muchos favoritos que supera lo que se esperaría bajo una distribución normal.
En general, todos los gráficos Q-Q confirman los resultados de la prueba de Shapiro-Wilk: ninguna variable sigue una distribución normal. Las desviaciones más pronunciadas corresponden a followers, friends, statuses y retweets, que son precisamente las variables con los valores W más bajos en la prueba de normalidad.
library(MASS)
# Construir fórmula dinámica con todas las variables numéricas
formula_tw <- as.formula(
paste("label ~", paste(vars_numericas, collapse = " + "))
)
lda_twitter <- lda(formula_tw, data = BD_Twitter)
lda_twitter## Call:
## lda(formula_tw, data = BD_Twitter)
##
## Prior probabilities of groups:
## Con_depresion Sin_depresion
## 0.5 0.5
##
## Group means:
## ID followers friends favourites statuses retweets
## Con_depresion 4999.5 879.2420 1002.2682 4280.807 9697.184 1056.959
## Sin_depresion 14999.5 921.7259 562.5893 8515.664 79091.656 1818.896
##
## Coefficients of linear discriminants:
## LD1
## ID 3.702640e-04
## followers -1.187301e-04
## friends 1.278933e-04
## favourites 5.134753e-05
## statuses -7.180788e-07
## retweets 4.453489e-07
Interpretación: El modelo de Análisis Discriminante Lineal se ajustó utilizando como variable de clasificación label (Con depresión / Sin depresión) y como variables explicativas ID, followers, friends, favourites, statuses y retweets.
Probabilidades a priori
Las probabilidades previas de cada grupo son:
\[ P(\text{Con depresión}) = 0.5 \]
\[ P(\text{Sin depresión}) = 0.5 \]
Esto ocurre porque la base de datos contiene exactamente el mismo número de observaciones en cada grupo (10,000 cada uno), lo cual es una configuración balanceada ideal para el análisis discriminante.
Medias de grupo
Las medias de grupo revelan diferencias importantes en el comportamiento digital entre los dos tipos de usuarios:
La variable statuses muestra la diferencia más pronunciada:
\[ \bar{x}_{\text{statuses, Con depresión}} = 9{,}697 \]
\[ \bar{x}_{\text{statuses, Sin depresión}} = 79{,}092 \]
Esto indica que los usuarios sin depresión han publicado, en promedio, más de ocho veces más contenido que los usuarios con depresión. Este hallazgo puede interpretarse de dos formas: los usuarios sin depresión son más activos en la plataforma, o bien los usuarios con depresión tienen una presencia más pasiva o retraída en Twitter.
La variable friends también muestra una diferencia notable:
\[ \bar{x}_{\text{friends, Con depresión}} = 1{,}002 \]
\[ \bar{x}_{\text{friends, Sin depresión}} = 563 \]
Los usuarios con depresión siguen en promedio a más cuentas que los usuarios sin depresión. Esto podría sugerir un comportamiento de búsqueda de conexión social o de contenido como estrategia de afrontamiento.
La variable favourites también muestra diferencias:
\[ \bar{x}_{\text{favourites, Con depresión}} = 4{,}281 \]
\[ \bar{x}_{\text{favourites, Sin depresión}} = 8{,}516 \]
Los usuarios sin depresión marcan como favoritas aproximadamente el doble de publicaciones que los usuarios con depresión, lo que sugiere que consumen e interactúan más activamente con el contenido de otros.
Coeficientes de la función discriminante
\[ LD_1 = 0.000370(\text{ID}) - 0.000119(\text{followers}) + 0.000128(\text{friends}) + 0.0000513(\text{favourites}) - 0.000000718(\text{statuses}) + 0.000000445(\text{retweets}) \]
La variable con mayor peso relativo en la función discriminante es el ID, lo que refleja que la separación entre grupos está parcialmente determinada por el orden de los datos en la base. Las demás variables tienen coeficientes pequeños, lo que indica que la separación entre grupos no depende de una sola característica de comportamiento, sino de la combinación de todas ellas.
w_tw <- lda_twitter$scaling[, 1]
medias_tw <- lda_twitter$means
priors_tw <- lda_twitter$prior
constantes_tw <- -0.5 * as.vector(medias_tw %*% w_tw) + log(priors_tw)
constantes_tw## Con_depresion Sin_depresion
## -1.737268 -3.641929
Interpretación: Las constantes obtenidas para cada grupo fueron:
\[ c_{\text{Con depresión}} = -1.7373 \]
\[ c_{\text{Sin depresión}} = -3.6419 \]
Las funciones clasificatorias completas quedan definidas como:
\[ \delta_{\text{Con depresión}}(x) = 0.000370(\text{ID}) - 0.000119(\text{followers}) + 0.000128(\text{friends}) + 0.0000513(\text{favourites}) - 7.18 \times 10^{-7}(\text{statuses}) + 4.45 \times 10^{-7}(\text{retweets}) - 1.7373 \]
\[ \delta_{\text{Sin depresión}}(x) = 0.000370(\text{ID}) - 0.000119(\text{followers}) + 0.000128(\text{friends}) + 0.0000513(\text{favourites}) - 7.18 \times 10^{-7}(\text{statuses}) + 4.45 \times 10^{-7}(\text{retweets}) - 3.6419 \]
La constante de la función para Con depresión es mayor (\(-1.7373 > -3.6419\)), lo que indica que, manteniendo constantes las variables de comportamiento, el modelo tiene una inclinación base hacia clasificar un usuario como con depresión antes de considerar sus características digitales. La diferencia entre las constantes es la que establece el umbral de clasificación entre los dos grupos.
Para clasificar a un nuevo usuario, se evalúan ambas funciones y se asigna al grupo cuya función produzca el valor más alto.
## Con_depresion Sin_depresion
## -1.904661 1.904661
Interpretación: Los promedios de la función discriminante por grupo fueron:
\[ \bar{LD1}_{\text{Con depresión}} = -1.9047 \]
\[ \bar{LD1}_{\text{Sin depresión}} = +1.9047 \]
Estos valores indican que la primera función discriminante logra separar claramente los dos grupos a lo largo del eje discriminante: los usuarios con depresión se posicionan en valores negativos de \(LD_1\), mientras que los usuarios sin depresión se ubican en valores positivos y de igual magnitud.
La separación perfectamente simétrica (\(\pm 1.9047\)) es un indicador de que el modelo está bien calibrado y que la función discriminante captura una diferencia sistemática en el comportamiento digital entre ambos grupos. Un usuario cuya combinación de variables produzca un valor de \(LD_1\) negativo será clasificado como Con depresión, y uno con valor positivo será clasificado como Sin depresión.
##
## Con_depresion Sin_depresion
## Con_depresion 9643 357
## Sin_depresion 11 9989
Interpretación: La matriz de confusión compara el grupo real de cada usuario con el grupo asignado por el modelo:
\[ \begin{array}{lcc} & \text{Pred. Con dep.} & \text{Pred. Sin dep.} \\ \text{Real Con dep.} & 9{,}643 & 357 \\ \text{Real Sin dep.} & 11 & 9{,}989 \end{array} \]
De los 10,000 usuarios con depresión, el modelo clasificó correctamente a 9,643 y cometió error en solo 357, es decir, clasificó erróneamente a esos 357 usuarios como si no tuvieran depresión cuando en realidad sí la presentaban. En el contexto de salud mental, este tipo de error (falso negativo) es el más preocupante, ya que significaría que una herramienta basada en este modelo dejaría sin identificar a una parte de los usuarios que necesitan atención.
De los 10,000 usuarios sin depresión, el modelo clasificó correctamente a 9,989 y cometió error en apenas 11 casos, clasificándolos incorrectamente como usuarios con depresión. Este tipo de error (falso positivo) es considerablemente menor.
En general, la diagonal principal concentra la gran mayoría de las clasificaciones, lo que indica que el modelo tiene un desempeño muy sólido. Las principales confusiones ocurren al intentar identificar a los usuarios con depresión, lo cual es razonable dado que el comportamiento digital de estos usuarios puede ser más variable y difícil de distinguir.
## [1] 0.9816
Interpretación: \[ Exactitud = \frac{\text{Clasificaciones correctas}}{\text{Total de observaciones}} = \frac{9{,}643 + 9{,}989}{20{,}000} = 0.9816 \]
El modelo clasificó correctamente al 98.16% de los usuarios.
Este resultado es notablemente alto e indica que las variables de comportamiento en Twitter (seguidores, amigos, favoritos, publicaciones y retweets) contienen información suficiente para distinguir entre usuarios con y sin depresión con una precisión muy elevada.
Desde una perspectiva de salud pública digital, un modelo con esta exactitud podría ser útil como herramienta de detección temprana de indicios de depresión en redes sociales, identificando perfiles de riesgo a partir del comportamiento observable de los usuarios, sin necesidad de cuestionarios clínicos explícitos.
Validación cruzada
La validación cruzada clasifica cada observación con un modelo que no la vio antes, lo cual evita el sobreajuste y proporciona una estimación más realista del desempeño del modelo. La exactitud con validación cruzada se calcula como:
\[ Exactitud_{CV} = \frac{\text{Número de clasificaciones correctas}}{\text{Total de observaciones}} \]
lda_twitter_cv <- lda(formula_tw,
data = BD_Twitter,
CV = TRUE)
table(
Real = BD_Twitter$label,
Predicho = lda_twitter_cv$class
)## Predicho
## Real Con_depresion Sin_depresion
## Con_depresion 9642 358
## Sin_depresion 13 9987
## [1] 0.98145
Interpretación: La matriz de confusión con validación cruzada mostró los siguientes resultados:
\[ \begin{array}{lcc} & \text{Pred. Con dep.} & \text{Pred. Sin dep.} \\ \text{Real Con dep.} & 9{,}642 & 358 \\ \text{Real Sin dep.} & 12 & 9{,}988 \end{array} \]
La exactitud con validación cruzada fue:
\[ Exactitud_{CV} = 0.9815 \approx 98.15\% \]
Comparando ambos resultados:
| Tipo | Exactitud |
|---|---|
| Modelo completo | \(98.16\%\) |
| Validación cruzada | \(98.15\%\) |
La diferencia entre ambas exactitudes es prácticamente nula (\(0.01\%\)), lo que es un resultado excepcional. Indica que el modelo no presenta sobreajuste: clasifica nuevos usuarios con la misma precisión con la que clasifica los datos con los que fue entrenado.
En el contexto de salud mental, esto significa que el modelo es generalizable: si se aplicara a un conjunto de usuarios de Twitter completamente nuevo, se esperaría mantener una exactitud cercana al 98%, lo cual lo hace potencialmente útil como herramienta de detección a escala en la plataforma.
# Sustituir los valores según las variables disponibles en la base
# Este es un ejemplo genérico — ajustar los nombres y valores reales
nuevo_usuario <- data.frame(
matrix(
colMeans(X_twitter_num), # usa las medias como valores de ejemplo
nrow = 1,
dimnames = list(NULL, vars_numericas)
)
)
predict(lda_twitter, nuevo_usuario)## $class
## [1] Sin_depresion
## Levels: Con_depresion Sin_depresion
##
## $posterior
## Con_depresion Sin_depresion
## 1 0.5 0.5
##
## $x
## LD1
## 1 -1.764722e-14
Interpretación: Se evaluó un usuario con valores promedio en todas las variables:
\[ \bar{x}_{\text{ID}} = 9{,}999.5, \quad \bar{x}_{\text{followers}} = 900.5, \quad \bar{x}_{\text{friends}} = 782.4 \]
\[ \bar{x}_{\text{favourites}} = 6{,}398.2, \quad \bar{x}_{\text{statuses}} = 44{,}394.4, \quad \bar{x}_{\text{retweets}} = 1{,}437.9 \]
El modelo asignó probabilidades exactamente iguales a ambos grupos:
\[ P(\text{Con depresión}) = 0.50 \]
\[ P(\text{Sin depresión}) = 0.50 \]
y clasificó al usuario como Sin depresión, aunque con una probabilidad del 50%, lo que representa el caso de máxima incertidumbre en el modelo.
Este resultado es coherente con la estructura de la base: el usuario promedio tiene exactamente el ID 9,999.5, que cae justo en la frontera entre los IDs de los usuarios con depresión (0–9,999) y los sin depresión (10,000–19,999). Esto confirma que la variable ID tiene una influencia artificial en el modelo y que, para un análisis más robusto, sería recomendable excluirla y clasificar nuevos usuarios con valores reales de comportamiento (como seguidores, publicaciones y favoritos) en lugar de utilizar las medias del conjunto de datos.
En este trabajo se aplicó el Análisis Discriminante Lineal (LDA) para estudiar si las variables de comportamiento digital de los usuarios de Twitter permiten clasificarlos en los grupos:
\[ \text{Con depresión} \quad \text{y} \quad \text{Sin depresión} \]
El modelo construyó una función discriminante de la forma:
\[ LD_1 = a_1(\text{ID}) + a_2(\text{followers}) + a_3(\text{friends}) + a_4(\text{favourites}) + a_5(\text{statuses}) + a_6(\text{retweets}) \]
Los resultados mostraron diferencias claras en el comportamiento digital entre ambos grupos. Los usuarios sin depresión presentan, en promedio, un volumen de publicaciones (\(\bar{x} = 79{,}092\)) ocho veces mayor al de los usuarios con depresión (\(\bar{x} = 9{,}697\)), mientras que los usuarios con depresión tienden a seguir a más cuentas (\(\bar{x} = 1{,}002\) vs \(\bar{x} = 563\)) y a interactuar menos con publicaciones de otros.
La exactitud del modelo fue:
\[ Exactitud = 0.9816 \approx 98.16\% \]
con una exactitud en validación cruzada de:
\[ Exactitud_{CV} = 0.9815 \approx 98.15\% \]
La diferencia de apenas \(0.01\%\) entre ambas métricas indica que el modelo no presenta sobreajuste y es altamente generalizable.
En conclusión, el análisis muestra que las variables de comportamiento digital en Twitter contienen información valiosa para identificar patrones asociados con la depresión. El modelo puede utilizarse como herramienta de apoyo en la detección temprana de indicios de depresión en redes sociales, abriendo la posibilidad de intervenciones preventivas a escala digital. Sin embargo, es importante considerar que el modelo se basa en comportamiento observable y no en diagnósticos clínicos, por lo que sus resultados deben complementarse con evaluaciones especializadas.
El análisis discriminante lineal (LDA) es una técnica estadística multivariada que permite clasificar observaciones en grupos predefinidos a partir de un conjunto de variables cuantitativas. En el contexto de la salud y la medicina, esta técnica resulta especialmente útil para identificar patrones en pacientes que permitan distinguir entre personas que presentan cáncer de pulmón y personas que no lo presentan.
En este análisis se estudia una base de datos de pacientes, donde la variable objetivo clasifica a cada persona en dos grupos:
El objetivo es determinar si las variables disponibles en la base permiten discriminar adecuadamente entre ambos grupos mediante un análisis discriminante lineal.
# knitr::opts_chunk$set(echo = TRUE)
library(readxl)
BD_LungCancer <- read_excel("/Users/veronicapichardo/Desktop/AM/Bases examen/survey-lung-cancer.xlsx")Se verifica que los datos se cargaron correctamente observando las primeras filas y la estructura de la base.
## tibble [309 × 16] (S3: tbl_df/tbl/data.frame)
## $ GENDER : chr [1:309] "M" "M" "F" "M" ...
## $ AGE : num [1:309] 69 74 59 63 63 75 52 51 68 53 ...
## $ SMOKING : num [1:309] 1 2 1 2 1 1 2 2 2 2 ...
## $ YELLOW_FINGERS : num [1:309] 2 1 1 2 2 2 1 2 1 2 ...
## $ ANXIETY : num [1:309] 2 1 1 2 1 1 1 2 2 2 ...
## $ PEER_PRESSURE : num [1:309] 1 1 2 1 1 1 1 2 1 2 ...
## $ CHRONIC DISEASE : num [1:309] 1 2 1 1 1 2 1 1 1 2 ...
## $ FATIGUE : num [1:309] 2 2 2 1 1 2 2 2 2 1 ...
## $ ALLERGY : num [1:309] 1 2 1 1 1 2 1 2 1 2 ...
## $ WHEEZING : num [1:309] 2 1 2 1 2 2 2 1 1 1 ...
## $ ALCOHOL CONSUMING : num [1:309] 2 1 1 2 1 1 2 1 1 2 ...
## $ COUGHING : num [1:309] 2 1 2 1 2 2 2 1 1 1 ...
## $ SHORTNESS OF BREATH : num [1:309] 2 2 2 1 2 2 2 2 1 1 ...
## $ SWALLOWING DIFFICULTY: num [1:309] 2 2 1 2 1 1 1 2 1 2 ...
## $ CHEST PAIN : num [1:309] 2 2 2 2 1 1 2 1 1 2 ...
## $ LUNG_CANCER : chr [1:309] "YES" "YES" "NO" "NO" ...
## [1] 309 16
## [1] "GENDER" "AGE" "SMOKING"
## [4] "YELLOW_FINGERS" "ANXIETY" "PEER_PRESSURE"
## [7] "CHRONIC DISEASE" "FATIGUE" "ALLERGY"
## [10] "WHEEZING" "ALCOHOL CONSUMING" "COUGHING"
## [13] "SHORTNESS OF BREATH" "SWALLOWING DIFFICULTY" "CHEST PAIN"
## [16] "LUNG_CANCER"
La variable que indica si el paciente presenta cáncer de pulmón o no
es la variable de clasificación del análisis. Se convierte a factor y la
base de datos se transforma a data.frame para garantizar
compatibilidad con las funciones del análisis discriminante.
Nota importante: Aunque varias variables están codificadas numéricamente (1 y 2), en realidad representan variables categóricas binarias (por ejemplo, 1 = No / 2 = Sí para síntomas como tos, fatiga, ansiedad, etc.). Sin embargo, se mantienen como numéricas para cumplir con los supuestos del modelo LDA, el cual requiere variables cuantitativas.
# La variable de grupo es "LUNG_CANCER" (YES = con cáncer, NO = sin cáncer)
BD_LungCancer$LUNG_CANCER <- as.factor(BD_LungCancer$LUNG_CANCER)
# La variable GENDER también se convierte a factor (M = masculino, F = femenino)
BD_LungCancer$GENDER <- as.factor(BD_LungCancer$GENDER)
BD_LungCancer <- as.data.frame(BD_LungCancer)
str(BD_LungCancer)## 'data.frame': 309 obs. of 16 variables:
## $ GENDER : Factor w/ 2 levels "F","M": 2 2 1 2 1 1 2 1 1 2 ...
## $ AGE : num 69 74 59 63 63 75 52 51 68 53 ...
## $ SMOKING : num 1 2 1 2 1 1 2 2 2 2 ...
## $ YELLOW_FINGERS : num 2 1 1 2 2 2 1 2 1 2 ...
## $ ANXIETY : num 2 1 1 2 1 1 1 2 2 2 ...
## $ PEER_PRESSURE : num 1 1 2 1 1 1 1 2 1 2 ...
## $ CHRONIC DISEASE : num 1 2 1 1 1 2 1 1 1 2 ...
## $ FATIGUE : num 2 2 2 1 1 2 2 2 2 1 ...
## $ ALLERGY : num 1 2 1 1 1 2 1 2 1 2 ...
## $ WHEEZING : num 2 1 2 1 2 2 2 1 1 1 ...
## $ ALCOHOL CONSUMING : num 2 1 1 2 1 1 2 1 1 2 ...
## $ COUGHING : num 2 1 2 1 2 2 2 1 1 1 ...
## $ SHORTNESS OF BREATH : num 2 2 2 1 2 2 2 2 1 1 ...
## $ SWALLOWING DIFFICULTY: num 2 2 1 2 1 1 1 2 1 2 ...
## $ CHEST PAIN : num 2 2 2 2 1 1 2 1 1 2 ...
## $ LUNG_CANCER : Factor w/ 2 levels "NO","YES": 2 2 1 1 1 2 2 2 1 2 ...
## GENDER AGE SMOKING YELLOW_FINGERS ANXIETY
## F:147 Min. :21.00 Min. :1.000 Min. :1.00 Min. :1.000
## M:162 1st Qu.:57.00 1st Qu.:1.000 1st Qu.:1.00 1st Qu.:1.000
## Median :62.00 Median :2.000 Median :2.00 Median :1.000
## Mean :62.67 Mean :1.563 Mean :1.57 Mean :1.498
## 3rd Qu.:69.00 3rd Qu.:2.000 3rd Qu.:2.00 3rd Qu.:2.000
## Max. :87.00 Max. :2.000 Max. :2.00 Max. :2.000
## PEER_PRESSURE CHRONIC DISEASE FATIGUE ALLERGY
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :2.000 Median :2.000 Median :2.000 Median :2.000
## Mean :1.502 Mean :1.505 Mean :1.673 Mean :1.557
## 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000 Max. :2.000 Max. :2.000
## WHEEZING ALCOHOL CONSUMING COUGHING SHORTNESS OF BREATH
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :2.000 Median :2.000 Median :2.000 Median :2.000
## Mean :1.557 Mean :1.557 Mean :1.579 Mean :1.641
## 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000 Max. :2.000 Max. :2.000
## SWALLOWING DIFFICULTY CHEST PAIN LUNG_CANCER
## Min. :1.000 Min. :1.000 NO : 39
## 1st Qu.:1.000 1st Qu.:1.000 YES:270
## Median :1.000 Median :2.000
## Mean :1.469 Mean :1.557
## 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000
Interpretación: El resumen estadístico presenta una vista general de los 309 pacientes de la muestra. A continuación se analizan los aspectos más relevantes:
Distribución por género
La muestra está compuesta por 147 mujeres (F) y 162 hombres (M), una distribución relativamente equilibrada. Aunque el género no se incluye directamente en el modelo LDA (por ser variable categórica no binaria numérica), su representación equilibrada evita sesgos de género en los datos.
Edad
\[\bar{x}_{\text{AGE}} = 62.67 \text{ años}, \quad \text{Mín} = 21, \quad \text{Máx} = 87\]
La edad promedio de los pacientes es de casi 63 años, lo cual es consistente con la epidemiología del cáncer de pulmón: esta enfermedad es significativamente más frecuente en adultos de mediana edad y adultos mayores. El rango amplio (de 21 a 87 años) indica que la muestra incluye desde pacientes jóvenes hasta muy longevos.
Variables binarias: síntomas y comportamientos
Las variables como SMOKING, FATIGUE,
COUGHING, entre otras, están codificadas como 1 (ausencia)
y 2 (presencia). Sus medias permiten estimar qué porcentaje de los
pacientes presenta cada característica. Por ejemplo:
\[\bar{x}_{\text{FATIGUE}} = 1.673 \implies \approx 67\% \text{ de los pacientes presenta fatiga}\]
\[\bar{x}_{\text{SWALLOWING DIFFICULTY}} = 1.469 \implies \approx 47\% \text{ de los pacientes tiene dificultad para tragar}\]
La fatiga es el síntoma más extendido, lo cual es clínicamente comprensible: es uno de los síntomas más comunes del cáncer de pulmón avanzado. En contraste, la dificultad para tragar es el menos frecuente, ya que se asocia más con afecciones del esófago que con el cáncer de pulmón en estadios tempranos.
Desbalance en la variable objetivo
\[n_{\text{YES}} = 270 \quad (87.4\%) \qquad n_{\text{NO}} = 39 \quad (12.6\%)\]
Este desbalance es el aspecto más importante del resumen. Más del 87% de los pacientes tiene diagnóstico de cáncer de pulmón, lo que significa que el modelo tiene una tendencia a priori muy fuerte hacia clasificar como positivo. En la práctica, esto implica que una exactitud alta por sí sola no garantiza que el modelo sea útil: un clasificador que dijera “todos tienen cáncer” ya tendría una exactitud del 87.4% sin aprender nada. Por eso, la exactitud del 93.5% del LDA debe complementarse con un análisis de los errores (falsos negativos y falsos positivos).
# Seleccionar únicamente variables numéricas para el análisis
vars_numericas_lc <- names(BD_LungCancer)[sapply(BD_LungCancer, is.numeric)]
vars_numericas_lc## [1] "AGE" "SMOKING" "YELLOW_FINGERS"
## [4] "ANXIETY" "PEER_PRESSURE" "CHRONIC DISEASE"
## [7] "FATIGUE" "ALLERGY" "WHEEZING"
## [10] "ALCOHOL CONSUMING" "COUGHING" "SHORTNESS OF BREATH"
## [13] "SWALLOWING DIFFICULTY" "CHEST PAIN"
## AGE SMOKING YELLOW_FINGERS
## 19366 483 485
## ANXIETY PEER_PRESSURE CHRONIC DISEASE
## 463 464 465
## FATIGUE ALLERGY WHEEZING
## 517 481 481
## ALCOHOL CONSUMING COUGHING SHORTNESS OF BREATH
## 481 488 507
## SWALLOWING DIFFICULTY CHEST PAIN
## 454 481
Interpretación:
Las sumas totales nos indican cuánto acumula cada variable a lo largo de los 309 pacientes. Dado que las variables binarias están codificadas como 1 o 2, el mínimo posible sería 309 (si todos marcaron 1) y el máximo sería 618 (si todos marcaron 2).
FATIGUE tiene una suma de
517, lo que significa que una gran cantidad de
pacientes reportó tener fatiga (valor 2). Esto cobra sentido porque la
fatiga es uno de los síntomas más comunes del cáncer de pulmón.SHORTNESS OF BREATH (dificultad para
respirar) también suma 507, lo que apunta a que este
síntoma es muy frecuente en la muestra, especialmente en pacientes con
cáncer.SWALLOWING DIFFICULTY (dificultad para
tragar) es la que suma menos (454), lo que indica que
este síntoma es menos frecuente; no todos los pacientes con cáncer de
pulmón necesariamente lo presentan.AGE suma 19,366
porque es la única variable continua, siendo su escala completamente
diferente al resto.En resumen, variables con sumas más altas reflejan síntomas muy extendidos en la población estudiada, mientras que las más bajas corresponden a síntomas menos generalizados.
resumen_completo_lc <- function() {
resumen_general_lc <- summary(BD_LungCancer)
datos_numericos_lc <- BD_LungCancer[, sapply(BD_LungCancer, is.numeric)]
media_lc <- colMeans(datos_numericos_lc, na.rm = TRUE)
desviacion_lc <- apply(datos_numericos_lc, 2, sd, na.rm = TRUE)
varianza_lc <- apply(datos_numericos_lc, 2, var, na.rm = TRUE)
estadisticos_lc <- data.frame(
Variable = names(media_lc),
Media = media_lc,
Desviacion_Estandar = desviacion_lc,
Varianza = varianza_lc,
row.names = NULL
)
return(list(
Resumen = resumen_general_lc,
Estadisticos = estadisticos_lc
))
}
resultado_lc <- resumen_completo_lc()
resultado_lc$Resumen## GENDER AGE SMOKING YELLOW_FINGERS ANXIETY
## F:147 Min. :21.00 Min. :1.000 Min. :1.00 Min. :1.000
## M:162 1st Qu.:57.00 1st Qu.:1.000 1st Qu.:1.00 1st Qu.:1.000
## Median :62.00 Median :2.000 Median :2.00 Median :1.000
## Mean :62.67 Mean :1.563 Mean :1.57 Mean :1.498
## 3rd Qu.:69.00 3rd Qu.:2.000 3rd Qu.:2.00 3rd Qu.:2.000
## Max. :87.00 Max. :2.000 Max. :2.00 Max. :2.000
## PEER_PRESSURE CHRONIC DISEASE FATIGUE ALLERGY
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :2.000 Median :2.000 Median :2.000 Median :2.000
## Mean :1.502 Mean :1.505 Mean :1.673 Mean :1.557
## 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000 Max. :2.000 Max. :2.000
## WHEEZING ALCOHOL CONSUMING COUGHING SHORTNESS OF BREATH
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :2.000 Median :2.000 Median :2.000 Median :2.000
## Mean :1.557 Mean :1.557 Mean :1.579 Mean :1.641
## 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000 Max. :2.000 Max. :2.000
## SWALLOWING DIFFICULTY CHEST PAIN LUNG_CANCER
## Min. :1.000 Min. :1.000 NO : 39
## 1st Qu.:1.000 1st Qu.:1.000 YES:270
## Median :1.000 Median :2.000
## Mean :1.469 Mean :1.557
## 3rd Qu.:2.000 3rd Qu.:2.000
## Max. :2.000 Max. :2.000
Interpretación:
La tabla de estadísticos descriptivos presenta la media, desviación estándar y varianza de cada variable numérica de la base.
Medias
Como se observa, la variable AGE tiene la media más alta
de todas:
\[\bar{x}_{\text{AGE}} = 62.67 \text{ años}\]
lo que confirma que los pacientes de esta muestra son predominantemente adultos de mediana edad y adultos mayores, el grupo etario con mayor riesgo de desarrollar cáncer de pulmón.
Entre las variables binarias, FATIGUE presenta la media
más alta:
\[\bar{x}_{\text{FATIGUE}} = 1.673\]
Esto significa que aproximadamente el 67% de los pacientes reportó fatiga (valor 2). La fatiga es uno de los síntomas sistémicos más frecuentes del cáncer de pulmón, ya que el tumor consume recursos energéticos del organismo y puede generar anemia. Este hallazgo es clínicamente coherente.
Por el contrario, SWALLOWING DIFFICULTY tiene la media
más baja entre los síntomas:
\[\bar{x}_{\text{SWALLOWING DIFFICULTY}} = 1.469\]
lo que indica que menos del 47% de los pacientes lo presenta. La dificultad para tragar no es un síntoma primario del cáncer de pulmón, sino que aparece cuando el tumor ha invadido estructuras del mediastino o el esófago, lo que ocurre en estadios más avanzados.
Desviaciones estándar y varianzas
AGE es la variable con mayor varianza:
\[s^2_{\text{AGE}} = 67.41, \qquad s_{\text{AGE}} = 8.21 \text{ años}\]
Esto significa que los pacientes pueden diferir hasta 8 años por encima o por debajo del promedio de manera típica, con casos extremos de hasta 40 años de diferencia respecto a la media. Esta variabilidad en edad puede ser relevante para el modelo, ya que pacientes más jóvenes con cáncer pueden tener perfiles de síntomas distintos a los de pacientes mayores.
Las variables binarias tienen desviaciones estándar notablemente menores y muy similares entre sí, rondando entre 0.47 y 0.50:
\[s_{\text{binaria}} \approx 0.47 - 0.50\]
Esto es esperado: dado que los valores solo pueden ser 1 o 2, la dispersión máxima posible es limitada. El hecho de que todas tengan desviaciones similares indica que ningún síntoma domina la variabilidad sobre los demás; todos aportan información de manera relativamente equitativa, lo cual favorece el uso de todas las variables en el modelo LDA.
## AGE SMOKING YELLOW_FINGERS ANXIETY
## AGE 67.409048880 -0.3445656285 0.021193208 0.218625226
## SMOKING -0.344565629 0.2468162905 -0.003593494 0.039875173
## YELLOW_FINGERS 0.021193208 -0.0035934939 0.245954693 0.140535031
## ANXIETY 0.218625226 0.0398751734 0.140535031 0.250809061
## PEER_PRESSURE 0.076829320 -0.0106543941 0.080244189 0.054385744
## CHRONIC DISEASE -0.051979574 -0.0352099357 0.010213088 -0.002427184
## FATIGUE 0.048659270 -0.0069032909 -0.027508091 -0.044361787
## ALLERGY 0.114350859 0.0004728281 -0.035609213 -0.041304165
## WHEEZING 0.224740470 -0.0319947043 -0.019375447 -0.047797672
## ALCOHOL CONSUMING 0.240974236 -0.0125141848 -0.071323499 -0.041304165
## COUGHING 0.689961333 -0.0318055731 -0.003099651 -0.055877779
## SHORTNESS OF BREATH -0.069095953 0.0146261505 -0.025249023 -0.034674064
## SWALLOWING DIFFICULTY -0.005211617 0.0076282940 0.085750011 0.122515025
## CHEST PAIN -0.073960829 0.0296936074 -0.025868953 -0.028317152
## PEER_PRESSURE CHRONIC DISEASE FATIGUE ALLERGY
## AGE 0.07682932 -0.0519795738 0.0486592695 0.1143508595
## SMOKING -0.01065439 -0.0352099357 -0.0069032909 0.0004728281
## YELLOW_FINGERS 0.08024419 0.0102130879 -0.0275080906 -0.0356092128
## ANXIETY 0.05438574 -0.0024271845 -0.0443617871 -0.0413041651
## PEER_PRESSURE 0.25080906 0.0121674442 0.0183877611 -0.0203841466
## CHRONIC DISEASE 0.01216744 0.2507880469 -0.0260055479 0.0265098979
## FATIGUE 0.01838776 -0.0260055479 0.2207371916 0.0007144959
## ALLERGY -0.02038415 0.0265098979 0.0007144959 0.2475938301
## WHEEZING -0.01713739 -0.0124511411 0.0331820283 0.0430483756
## ALCOHOL CONSUMING -0.03986467 0.0005358719 -0.0447400496 0.0852561678
## COUGHING -0.02204430 -0.0434056235 0.0341171773 0.0466313622
## SHORTNESS OF BREATH -0.05298827 -0.0063674190 0.0997352162 -0.0071869878
## SWALLOWING DIFFICULTY 0.09177069 0.0188185601 -0.0311856428 -0.0152986172
## CHEST PAIN -0.02363090 -0.0092043878 -0.0025322574 0.0592821418
## WHEEZING ALCOHOL CONSUMING COUGHING
## AGE 0.224740470 0.2409742361 0.689961333
## SMOKING -0.031994704 -0.0125141848 -0.031805573
## YELLOW_FINGERS -0.019375447 -0.0713234985 -0.003099651
## ANXIETY -0.047797672 -0.0413041651 -0.055877779
## PEER_PRESSURE -0.017137393 -0.0398646661 -0.022044299
## CHRONIC DISEASE -0.012451141 0.0005358719 -0.043405624
## FATIGUE 0.033182028 -0.0447400496 0.034117177
## ALLERGY 0.043048376 0.0852561678 0.046631362
## WHEEZING 0.247593830 0.0657756483 0.092085908
## ALCOHOL CONSUMING 0.065775648 0.2475938301 0.049878115
## COUGHING 0.092085908 0.0498781154 0.244504686
## SHORTNESS OF BREATH 0.009046778 -0.0429012735 0.065912243
## SWALLOWING DIFFICULTY 0.017168915 -0.0023116043 -0.038950532
## CHEST PAIN 0.036554869 0.0820094145 0.020657336
## SHORTNESS OF BREATH SWALLOWING DIFFICULTY CHEST PAIN
## AGE -0.069095953 -0.005211617 -0.073960829
## SMOKING 0.014626151 0.007628294 0.029693607
## YELLOW_FINGERS -0.025249023 0.085750011 -0.025868953
## ANXIETY -0.034674064 0.122515025 -0.028317152
## PEER_PRESSURE -0.052988274 0.091770689 -0.023630900
## CHRONIC DISEASE -0.006367419 0.018818560 -0.009204388
## FATIGUE 0.099735216 -0.031185643 -0.002532257
## ALLERGY -0.007186988 -0.015298617 0.059282142
## WHEEZING 0.009046778 0.017168915 0.036554869
## ALCOHOL CONSUMING -0.042901273 -0.002311604 0.082009415
## COUGHING 0.065912243 -0.038950532 0.020657336
## SHORTNESS OF BREATH 0.230929265 -0.038677342 0.005800025
## SWALLOWING DIFFICULTY -0.038677342 0.249863405 0.017168915
## CHEST PAIN 0.005800025 0.017168915 0.247593830
Interpretación:
La matriz de covarianza describe cómo varían las variables de manera conjunta. Los valores en la diagonal principal son las varianzas de cada variable (ya analizadas), mientras que los valores fuera de la diagonal indican si dos variables tienden a aumentar o disminuir al mismo tiempo (covarianza positiva) o de forma opuesta (covarianza negativa).
Covarianzas más altas: relaciones clínicamente relevantes
La covarianza más alta de toda la matriz es entre AGE y
COUGHING:
\[\text{Cov}(\text{AGE}, \text{COUGHING}) = 0.690\]
Esto indica que los pacientes de mayor edad tienden a reportar más tos. Desde el punto de vista clínico, esto es coherente: la tos crónica es uno de los síntomas más comunes del cáncer de pulmón, y la enfermedad es más prevalente en adultos mayores. Además, el daño acumulado en el sistema respiratorio a lo largo de los años (por tabaquismo, contaminación o enfermedades previas) hace que la tos sea más frecuente en personas mayores independientemente del diagnóstico.
Otras covarianzas positivas notables con AGE son:
\[\text{Cov}(\text{AGE}, \text{ALCOHOL.CONSUMING}) = 0.241 \qquad \text{Cov}(\text{AGE}, \text{WHEEZING}) = 0.225\]
Ambas indican que los pacientes de mayor edad en esta muestra tienden también a consumir más alcohol y a presentar más sibilancias. Las sibilancias (sonido al respirar) se asocian con obstrucción de las vías respiratorias, lo cual es más común en fumadores de larga data o en pacientes con cáncer de pulmón avanzado.
Covarianzas negativas: relaciones inversas
La covarianza más negativa es entre AGE y
SMOKING:
\[\text{Cov}(\text{AGE}, \text{SMOKING}) = -0.345\]
Esto puede parecer contraintuitivo, pero sugiere que en esta muestra los pacientes más jóvenes son los que más fuman actualmente (valor 2), mientras que los pacientes mayores tienen más proporción de valor 1 (podrían haber dejado de fumar). También puede reflejar que muchos pacientes mayores con cáncer ya han abandonado el tabaquismo tras el diagnóstico o por indicación médica.
Independencia entre síntomas
La mayoría de las covarianzas entre pares de síntomas binarios (como
ANXIETY y FATIGUE, WHEEZING y
COUGHING, etc.) son pequeñas, cercanas a cero. Por
ejemplo:
\[\text{Cov}(\text{FATIGUE}, \text{ALLERGY}) = 0.0007\]
Esto indica que los síntomas son relativamente independientes entre sí, es decir, presentar fatiga no predice fuertemente si el paciente tiene o no alergia. Esta independencia es deseable para el LDA, ya que significa que cada variable aporta información propia y no redundante al modelo.
mi_colores_lc <- c("pink", "purple")
colores_lc <- mi_colores_lc[as.numeric(BD_LungCancer$LUNG_CANCER)]
pairs(X_lc,
col = colores_lc,
pch = 19,
main = "Diagramas de dispersión por grupo de Lung Cancer")
legend("topright",
legend = levels(BD_LungCancer$LUNG_CANCER),
col = mi_colores_lc,
pch = 19)Interpretación:
Los diagramas de dispersión muestran simultáneamente las relaciones entre todas las variables numéricas de la base, diferenciando con color a los pacientes sin cáncer (rosa) y con cáncer (morado). Cada celda de la matriz corresponde a un par de variables graficadas entre sí.
Dominio visual del grupo con cáncer
Lo primero que salta a la vista es que los puntos morados (YES) llenan casi completamente cada panel. Esto no es un error gráfico, sino el reflejo directo del desbalance entre grupos:
\[n_{\text{YES}} = 270 \quad \text{frente a} \quad n_{\text{NO}} = 39\]
Es decir, por cada paciente sin cáncer, hay aproximadamente 7 pacientes con cáncer en la muestra. Esto implica que cualquier modelo entrenado con estos datos tendrá una tendencia natural a clasificar como positivo, ya que esa es la clase dominante.
Separación entre grupos
En ningún panel se observa una separación perfecta o clara entre los dos grupos de puntos. Esto indica que ninguna variable por sí sola es capaz de distinguir completamente entre pacientes con y sin cáncer de pulmón. Sin embargo, esta situación es común en datos médicos: raramente un único síntoma diagnostica una enfermedad.
Lo que sí se puede observar es que los puntos rosas
(NO) tienden a agruparse en la esquina inferior izquierda de
varios paneles, particularmente en aquellos que involucran síntomas como
FATIGUE, ALLERGY, COUGHING y
WHEEZING. Esto significa que los pacientes sin cáncer
tienden a tener valor 1 (ausencia del síntoma) en más variables,
mientras que los pacientes con cáncer se dispersan más hacia valor 2
(presencia del síntoma).
Variables con mayor separación visual
Aunque ningún par separa perfectamente, algunos paneles muestran más contraste que otros:
AGE vs. variables binarias: Los puntos
rosas aparecen más distribuidos en edades menores (hay pacientes jóvenes
sin cáncer), mientras que los morados dominan en rangos de edad más
altos. Esto es coherente con el hecho de que el cáncer de pulmón es más
frecuente en adultos mayores.FATIGUE y ALLERGY: En el
panel correspondiente a este par, se observa que varios puntos rosas se
acumulan en la coordenada (1, 1), es decir, pacientes sin fatiga y sin
alergia. Esto sugiere que la ausencia simultánea de estos dos
síntomas podría ser un indicador de que el paciente no tiene
cáncer.Justificación del LDA
El hecho de que ninguna variable aísle perfectamente a los grupos justifica precisamente el uso del Análisis Discriminante Lineal: el LDA toma todas las variables en conjunto y encuentra la combinación lineal que maximiza la separación entre grupos. Lo que visualmente aparece como nubes de puntos mezcladas puede separarse de forma mucho más efectiva en el espacio multidimensional que el LDA construye.
La prueba de Box’s M evalúa si las matrices de covarianza de los grupos son iguales. Las hipótesis del contraste son:
\[ H_0 : \text{Las matrices de covarianza de los grupos son iguales} \]
\[ H_1 : \text{Al menos una matriz de covarianza es diferente} \]
library(biotools)
boxM(
BD_LungCancer[, sapply(BD_LungCancer, is.numeric)],
BD_LungCancer$LUNG_CANCER
)##
## Box's M-test for Homogeneity of Covariance Matrices
##
## data: BD_LungCancer[, sapply(BD_LungCancer, is.numeric)] by BD_LungCancer$LUNG_CANCER
## Chi-Sq (approx.) = 228.6669, df = 105, p-value = 3.537e-11
Interpretación:
\[ \text{Si } p < 0.05 \Rightarrow \text{se rechaza } H_0 \]
\[ \text{Si } p > 0.05 \Rightarrow \text{no se rechaza } H_0 \]
\[\chi^2 \approx 228.67, \quad gl = 105, \quad p\text{-value} = 3.537 \times 10^{-11}\]
El resultado del test de Box’s M es extremadamente significativo: el valor \(p = 3.537 \times 10^{-11}\) es prácticamente cero, muy por debajo del umbral de \(\alpha = 0.05\). Por lo tanto, se rechaza \(H_0\) con toda contundencia.
Esto significa que las estructuras de variabilidad y correlación entre variables son fundamentalmente distintas en los pacientes con cáncer y sin cáncer. En términos prácticos:
Implicación para el LDA
Formalmente, esta violación del supuesto de homocedasticidad significa que el LDA no es el método óptimo para estos datos. Una alternativa sería el Análisis Discriminante Cuadrático (QDA), que permite que cada grupo tenga su propia matriz de covarianza. Sin embargo, el QDA requiere estimar más parámetros y puede ser inestable cuando uno de los grupos es pequeño, como ocurre aquí con el grupo NO (\(n = 39\)). Por ello, el LDA sigue siendo una opción razonable y sus resultados son interpretables, siempre que se tenga presente esta limitación.
Elipses de covarianza
options(rgl.useNULL = TRUE)
library(heplots)
covEllipses(
BD_LungCancer[, sapply(BD_LungCancer, is.numeric)],
BD_LungCancer$LUNG_CANCER,
variables = c(1, 2),
fill = TRUE,
alpha = 0.3,
col = c("#F472B6", "#A855F7"),
lwd = 2,
main = "Elipses de covarianza por grupo de Lung Cancer"
)## Warning in plot.window(...): "alpha" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "alpha" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "alpha" is not a
## graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "alpha" is not a
## graphical parameter
## Warning in box(...): "alpha" is not a graphical parameter
## Warning in title(...): "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
## Warning in text.default(x, y, label, pos = pos, xpd = xpd, col = col, ...):
## "alpha" is not a graphical parameter
Interpretación:
Las elipses de covarianza son una representación visual de cómo se
distribuyen y varían los dos grupos de pacientes en el espacio formado
por las variables AGE (eje X) y SMOKING (eje
Y). El centro de cada elipse corresponde a la media del grupo, y su
forma refleja la variabilidad y correlación de las variables dentro de
ese grupo.
Tamaño de las elipses: variabilidad interna
La elipse del grupo con cáncer (morado/azul) es considerablemente más grande que la del grupo sin cáncer (rosa). Esto indica que:
\[s^2_{\text{YES, AGE}} > s^2_{\text{NO, AGE}} \qquad \text{y} \qquad s^2_{\text{YES, SMOKING}} > s^2_{\text{NO, SMOKING}}\]
En términos prácticos, los pacientes con cáncer de pulmón son un grupo muy heterogéneo: hay personas de distintas edades (desde relativamente jóvenes hasta mayores de 80 años) y con distintos niveles de tabaquismo. Esta diversidad tiene sentido clínico, ya que el cáncer de pulmón puede desarrollarse tanto en fumadores crónicos como en personas con poco o ningún historial de tabaquismo, influenciado por factores genéticos, ambientales y de otro tipo.
Por el contrario, la elipse más compacta del grupo sin cáncer (rosa) sugiere que estos 39 pacientes comparten perfiles más similares entre sí en cuanto a edad y hábito tabáquico.
Posición de los centros: diferencias entre grupos
Los cruces (+) en el interior de cada elipse marcan las medias de cada grupo. Se observa que el centro del grupo YES está desplazado ligeramente hacia la derecha respecto al grupo NO, lo que confirma lo visto en el summary:
\[\bar{x}_{\text{AGE, YES}} = 62.95 \quad > \quad \bar{x}_{\text{AGE, NO}} = 60.74\]
Aunque la diferencia en edad promedio entre grupos es de aproximadamente 2 años, esta diferencia por sí sola no es suficiente para separar los grupos de forma definitiva.
Traslape entre elipses: dificultad de separación
Un aspecto crucial de la gráfica es que las dos elipses se traslapan considerablemente. Esto significa que hay una zona donde coexisten pacientes con y sin cáncer con valores similares de edad y tabaquismo, lo cual hace imposible clasificar correctamente a todos los pacientes usando solo estas dos variables.
Esta observación, combinada con el resultado de Box’s M (\(p < 0.05\)), confirma que las matrices de covarianza de los grupos son distintas y que el LDA opera bajo una violación de su supuesto de homocedasticidad. Sin embargo, también refuerza la necesidad de incluir más variables (los 12 síntomas restantes) para lograr una discriminación efectiva.
Las hipótesis son:
\[ H_0 : \text{La variable sigue una distribución normal} \]
\[ H_1 : \text{La variable no sigue una distribución normal} \]
X_lc_num <- BD_LungCancer[, sapply(BD_LungCancer, is.numeric)]
lapply(X_lc_num, function(x) {
x <- na.omit(x)
# Si hay más de 5000 observaciones se toma una muestra, de lo contrario se usa todo
if (length(x) > 5000) {
x <- sample(x, 5000)
}
shapiro.test(x)
})## $AGE
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.97875, p-value = 0.0001524
##
##
## $SMOKING
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63067, p-value < 2.2e-16
##
##
## $YELLOW_FINGERS
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.62941, p-value < 2.2e-16
##
##
## $ANXIETY
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63649, p-value < 2.2e-16
##
##
## $PEER_PRESSURE
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63649, p-value < 2.2e-16
##
##
## $`CHRONIC DISEASE`
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63646, p-value < 2.2e-16
##
##
## $FATIGUE
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.59134, p-value < 2.2e-16
##
##
## $ALLERGY
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63181, p-value < 2.2e-16
##
##
## $WHEEZING
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63181, p-value < 2.2e-16
##
##
## $`ALCOHOL CONSUMING`
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63181, p-value < 2.2e-16
##
##
## $COUGHING
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.62728, p-value < 2.2e-16
##
##
## $`SHORTNESS OF BREATH`
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.607, p-value < 2.2e-16
##
##
## $`SWALLOWING DIFFICULTY`
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63511, p-value < 2.2e-16
##
##
## $`CHEST PAIN`
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.63181, p-value < 2.2e-16
Interpretación:
\[ \text{Si } p < 0.05 \Rightarrow \text{se rechaza } H_0 \text{ (la variable no es normal)} \]
\[ \text{Si } p > 0.05 \Rightarrow \text{no se rechaza } H_0 \text{ (la variable puede ser normal)} \]
\[\text{Si } p < 0.05 \Rightarrow \text{se rechaza } H_0 \text{ (la variable NO es normal)}\]
\[\text{Si } p > 0.05 \Rightarrow \text{no se rechaza } H_0 \text{ (la variable puede ser normal)}\]
Los resultados de la prueba de Shapiro-Wilk son contundentes:
AGE es la única que se
aproxima más a la normalidad (\(W =
0.979\), \(p = 0.000152\)),
aunque también se rechaza formalmente. Su distribución es más continua
que las demás.Al igual que con la prueba de Box’s M, esta violación del supuesto de normalidad es importante conocerla, pero el LDA sigue siendo ampliamente utilizado y útil incluso cuando no se cumple perfectamente, especialmente con muestras medianas o grandes.
vars_num_lc <- names(X_lc_num)
n_vars_lc <- length(vars_num_lc)
n_cols_lc <- 2
n_rows_lc <- ceiling(n_vars_lc / n_cols_lc)
par(mfrow = c(n_rows_lc, n_cols_lc),
col.main = "#3CB371",
col.lab = "black",
cex.main = 1.2)
colores_qq_lc <- c("#40E0D0", "#7CCD7C", "#FFBBFF", "#FA8072",
"#87CEEB", "#FFD700", "#DDA0DD", "#98FB98",
"#FFB6C1", "#B0C4DE", "#F0E68C", "#E6E6FA",
"#FFDAB9", "#98FB98")
par(mar = c(2, 2, 2, 1))
for (i in seq_along(vars_num_lc)) {
col_i <- colores_qq_lc[(i - 1) %% length(colores_qq_lc) + 1]
qqnorm(X_lc_num[[ vars_num_lc[i] ]],
main = paste("QQ Plot -", vars_num_lc[i]),
pch = 19,
col = col_i)
qqline(X_lc_num[[ vars_num_lc[i] ]], col = "red", lwd = 2)
}Interpretación:
Los gráficos Q-Q (quantile-quantile) comparan la distribución real de cada variable contra lo que se esperaría si siguiera una distribución normal perfecta. Si los puntos cayeran exactamente sobre la línea roja diagonal, la variable sería perfectamente normal. Cualquier desviación sistemática de esa línea indica alejamiento de la normalidad.
Variables binarias: patrón de escalera
Para todas las variables codificadas como 1 o 2 (síntomas y
comportamientos como SMOKING, YELLOW_FINGERS,
ANXIETY, FATIGUE, etc.), el patrón es
idéntico: los puntos forman dos escalones horizontales,
uno en la parte baja del eje Y (correspondiente al valor 1) y otro en la
parte alta (correspondiente al valor 2), mientras que la línea roja
cruza diagonalmente.
Esto es completamente esperado y tiene una explicación directa: estas variables solo toman dos valores posibles, por lo que su distribución es Bernoulli, no normal. Una variable que solo puede valer 1 o 2 nunca podrá ajustarse a una campana de Gauss. El alejamiento de la línea roja no indica un problema en los datos, sino la naturaleza categórica de las variables.
Variable AGE: la más cercana a la
normalidad
El gráfico Q-Q de AGE es cualitativamente diferente al
del resto. Los puntos siguen más de cerca la línea roja a lo largo del
rango central, lo que indica que la distribución de edades en la muestra
es aproximadamente normal. Sin embargo, se observan
desviaciones en las colas, especialmente en la cola izquierda (pacientes
jóvenes):
A pesar de estas desviaciones en las colas, la prueba de Shapiro-Wilk
arrojó \(W = 0.979\) para
AGE, el valor más cercano a 1 de todas las variables,
confirmando que es la que más se aproxima a la normalidad, aunque
formalmente se rechace:
\[W_{\text{AGE}} = 0.979, \quad p = 0.000152\]
Implicación para el LDA
El LDA asume que las variables siguen una distribución normal
multivariada dentro de cada grupo. Como se observa claramente en los
gráficos Q-Q, este supuesto no se cumple para ninguna
de las 13 variables binarias, y solo se aproxima en AGE.
Sin embargo, como se mencionó anteriormente, el LDA es robusto a esta
violación cuando el tamaño de muestra es razonablemente grande, y los
resultados de clasificación (93.5% de exactitud) demuestran que el
modelo sigue siendo útil en la práctica a pesar de no cumplir
formalmente este supuesto.
library(MASS)
# 1. Arreglar nombres del dataset
names(BD_LungCancer) <- make.names(names(BD_LungCancer))
# 2. Volver a crear el subconjunto numérico (MUY IMPORTANTE)
X_lc_num <- BD_LungCancer[, sapply(BD_LungCancer, is.numeric)]
# 3. Obtener nombres ya corregidos
vars_numericas_lc <- names(X_lc_num)
# 4. Crear fórmula
formula_lc <- as.formula(
paste("LUNG_CANCER ~", paste(vars_numericas_lc, collapse = " + "))
)
lda_lc <- lda(formula_lc, data = BD_LungCancer)
lda_lc## Call:
## lda(formula_lc, data = BD_LungCancer)
##
## Prior probabilities of groups:
## NO YES
## 0.1262136 0.8737864
##
## Group means:
## AGE SMOKING YELLOW_FINGERS ANXIETY PEER_PRESSURE CHRONIC.DISEASE
## NO 60.74359 1.487179 1.333333 1.307692 1.256410 1.358974
## YES 62.95185 1.574074 1.603704 1.525926 1.537037 1.525926
## FATIGUE ALLERGY WHEEZING ALCOHOL.CONSUMING COUGHING SHORTNESS.OF.BREATH
## NO 1.487179 1.128205 1.230769 1.179487 1.256410 1.564103
## YES 1.700000 1.618519 1.603704 1.611111 1.625926 1.651852
## SWALLOWING.DIFFICULTY CHEST.PAIN
## NO 1.128205 1.307692
## YES 1.518519 1.592593
##
## Coefficients of linear discriminants:
## LD1
## AGE 0.008739491
## SMOKING 0.448612697
## YELLOW_FINGERS 0.733697370
## ANXIETY 0.470822326
## PEER_PRESSURE 0.539319233
## CHRONIC.DISEASE 0.559024598
## FATIGUE 0.921041677
## ALLERGY 0.911857758
## WHEEZING 0.367599366
## ALCOHOL.CONSUMING 1.192037648
## COUGHING 0.648397386
## SHORTNESS.OF.BREATH 0.272467731
## SWALLOWING.DIFFICULTY 0.610744217
## CHEST.PAIN 0.170821647
Interpretación: El modelo LDA construye una función lineal que combina todas las variables para separar lo mejor posible a los pacientes con cáncer de los que no lo tienen.
Probabilidades a priori:
\[P(\text{NO}) = 0.126 \quad \text{y} \quad P(\text{YES}) = 0.874\]
Esto refleja el desbalance de la muestra: el modelo “sabe” de antemano que el 87.4% de los pacientes tiene cáncer. Si no hay información adicional, lo más probable es clasificar a alguien como positivo.
Medias por grupo: Las medias muestran el perfil promedio de cada grupo:
FATIGUE: 1.70 (con cáncer) vs. 1.49 (sin cáncer) → los
pacientes con cáncer presentan más fatiga.ALLERGY: 1.62 (con cáncer) vs. 1.13 (sin cáncer) → las
alergias son mucho más comunes en pacientes con cáncer.WHEEZING: 1.60 vs. 1.23 → las sibilancias también son
más frecuentes en el grupo con cáncer.Coeficientes de la función discriminante (\(LD1\)):
La función discriminante tiene la forma:
\[LD1 = 0.009(\text{AGE}) + 0.449(\text{SMOKING}) + 0.734(\text{YELLOW\_FINGERS}) + 0.471(\text{ANXIETY}) + \cdots + 1.192(\text{ALCOHOL.CONSUMING})\]
Los coeficientes indican el peso de cada variable en la separación de los grupos:
ALCOHOL.CONSUMING (1.192) tiene el
coeficiente más alto, lo que indica que el consumo de alcohol es la
variable que más contribuye a discriminar entre
pacientes con y sin cáncer. Valores altos de esta variable empujan
fuertemente hacia la clasificación como “con cáncer”.FATIGUE (0.921) y
ALLERGY (0.912) también tienen
coeficientes muy altos, siendo los siguientes síntomas más influyentes
en el modelo.CHEST.PAIN (0.171) y
SHORTNESS.OF.BREATH (0.272) tienen
coeficientes más bajos, lo que indica que, en conjunto con las demás
variables, aportan menos información discriminante.AGE (0.009) tiene el coeficiente más
pequeño; aunque los pacientes mayores tienden a tener más cáncer, su
contribución marginal en el modelo combinado es mínima porque otras
variables capturan mejor la diferencia.w_lc <- lda_lc$scaling[, 1]
medias_lc <- lda_lc$means
priors_lc <- lda_lc$prior
constantes_lc <- -0.5 * as.vector(medias_lc %*% w_lc) + log(priors_lc)
constantes_lc## NO YES
## -7.389521 -6.679333
Interpretación: Las constantes completan la función de clasificación de cada grupo:
\[c_{NO} = -7.39 \qquad c_{YES} = -6.68\]
Estas constantes actúan como umbrales de partida para cada grupo antes de considerar los valores de las variables del paciente. Un paciente se clasificará en el grupo cuya función discriminante (constante + combinación lineal de sus variables) sea más alta.
\[ LD_1 = a_1(\text{AGE}) + a_2(\text{SMOKING}) + a_3(\text{YELLOW\_FINGERS}) + a_4(\text{ANXIETY}) + a_5(\text{PEER\_PRESSURE}) + a_6(\text{CHRONIC\_DISEASE}) + a_7(\text{FATIGUE}) + a_8(\text{ALLERGY}) + a_9(\text{WHEEZING}) + a_{10}(\text{ALCOHOL.CONSUMING}) + a_{11}(\text{COUGHING}) + a_{12}(\text{SHORTNESS\_OF\_BREATH}) + a_{13}(\text{SWALLOWING\_DIFFICULTY}) + a_{14}(\text{CHEST\_PAIN}) \]
donde cada coeficiente \(a_j\) indica la contribución de la variable correspondiente a la separación entre los grupos.
El modelo genera una función clasificatoria para cada grupo:
\[ c_{\text{YES}} = k_1 \qquad c_{\text{NO}} = k_2 \]
\[ \delta_{\text{YES}}(x) = a_1(\text{AGE}) + a_2(\text{SMOKING}) + \cdots + a_{14}(\text{CHEST\_PAIN}) + c_{\text{YES}} \]
\[ \delta_{\text{NO}}(x) = a_1(\text{AGE}) + a_2(\text{SMOKING}) + \cdots + a_{14}(\text{CHEST\_PAIN}) + c_{\text{NO}} \]
La clasificación se realiza asignando cada observación al grupo cuya función \(\delta_k(x)\) tome el .
## NO YES
## -2.1402031 0.3091404
Interpretación:
Los valores medios de \(LD1\) por grupo son:
\[\bar{LD1}_{NO} = -2.14 \qquad \bar{LD1}_{YES} = 0.31\]
Estos valores muestran cuánto separa la función discriminante a ambos grupos:
##
## NO YES
## NO 28 11
## YES 9 261
Interpretación:
La matriz de confusión muestra cuántos pacientes fueron clasificados correctamente e incorrectamente por el modelo:
| Predicho: NO | Predicho: YES | |
|---|---|---|
| Real: NO | 28 | 11 |
| Real: YES | 9 | 261 |
Clasificaciones correctas
\[\text{Verdaderos negativos (TN)} = 28 \qquad \text{Verdaderos positivos (TP)} = 261\]
El modelo identificó correctamente a 261 de los 270 pacientes con cáncer, y a 28 de los 39 pacientes sin cáncer.
Clasificaciones incorrectas
\[\text{Falsos positivos (FP)} = 11 \qquad \text{Falsos negativos (FN)} = 9\]
Sensibilidad y especificidad
A partir de la matriz se pueden calcular métricas adicionales importantes:
\[\text{Sensibilidad} = \frac{TP}{TP + FN} = \frac{261}{261 + 9} = \frac{261}{270} \approx 96.7\%\]
\[\text{Especificidad} = \frac{TN}{TN + FP} = \frac{28}{28 + 11} = \frac{28}{39} \approx 71.8\%\]
La sensibilidad del 96.7% indica que el modelo detecta correctamente al 96.7% de los pacientes que realmente tienen cáncer, lo cual es muy bueno para una herramienta de screening. Sin embargo, la especificidad del 71.8% revela que el modelo tiene más dificultad para identificar correctamente a los pacientes sanos, clasificando incorrectamente a casi 3 de cada 10 personas sin cáncer como si lo tuvieran.
## [1] 0.9352751
Interpretación: ### Interpretación
\[\text{Exactitud} = \frac{TP + TN}{n} = \frac{261 + 28}{309} = \frac{289}{309} \approx 93.5\%\]
El modelo clasifica correctamente al 93.5% de los pacientes utilizando los mismos datos con los que fue entrenado. Esta métrica es optimista por naturaleza: el modelo ya “conoce” los datos y puede haber aprendido particularidades específicas de esta muestra que no necesariamente se generalizan a nuevos pacientes.
Sin embargo, este valor también puede contrastarse con una línea base ingenua: si el modelo simplemente predijera “YES” para todos los pacientes, su exactitud sería del 87.4% (la proporción de YES en la muestra). El LDA supera esta línea base en 6.1 puntos porcentuales, lo que indica que efectivamente aprendió patrones útiles de los datos y no solo está aprovechando el desbalance entre grupos.
Validación cruzada
La validación cruzada clasifica cada observación con un modelo que no la vio antes, lo cual evita el sobreajuste y proporciona una estimación más realista del desempeño del modelo.
lda_lc_cv <- lda(formula_lc,
data = BD_LungCancer,
CV = TRUE)
table(
Real = BD_LungCancer$LUNG_CANCER,
Predicho = lda_lc_cv$class
)## Predicho
## Real NO YES
## NO 27 12
## YES 12 258
## [1] 0.9223301
Interpretación: Con validación cruzada (leave-one-out), la exactitud desciende ligeramente:
\[\text{Exactitud con CV} = \frac{27 + 258}{309} = \frac{285}{309} \approx 92.2\%\]
La caída de 93.5% a 92.2% representa apenas 1.3 puntos porcentuales de diferencia. Este resultado es muy favorable porque indica que el modelo no está sobreajustado: su capacidad predictiva se mantiene prácticamente igual cuando se evalúa con datos que no vio durante el entrenamiento.
Comparando las matrices de confusión:
| Sin CV | Con CV | |
|---|---|---|
| Falsos negativos (FN) | 9 | 12 |
| Falsos positivos (FP) | 11 | 12 |
| Clasificaciones correctas | 289 | 285 |
Los falsos negativos (pacientes con cáncer no detectados) aumentaron de 9 a 12 con la validación cruzada. Desde el punto de vista clínico, esto significa que en un escenario real el modelo podría dejar sin detectar aproximadamente 12 de cada 309 pacientes con cáncer. Es un número pequeño, pero en medicina cada falso negativo tiene un impacto humano significativo.
La estabilidad del modelo entre entrenamiento y validación cruzada confirma que las variables seleccionadas capturan patrones reales y generalizables del cáncer de pulmón, no solo ruido estadístico de esta muestra particular.
# Se crea un paciente de ejemplo con los valores promedio de cada variable numérica
nuevo_paciente <- data.frame(
matrix(
colMeans(X_lc_num),
nrow = 1,
dimnames = list(NULL, vars_numericas_lc)
)
)
predict(lda_lc, nuevo_paciente)## $class
## [1] YES
## Levels: NO YES
##
## $posterior
## NO YES
## 1 0.01510795 0.9848921
##
## $x
## LD1
## 1 6.638339e-16
Interpretación: Se creó un paciente hipotético con los valores promedio de todas las variables numéricas de la base (es decir, un “paciente típico” de la muestra). El modelo predice que este paciente tiene cáncer de pulmón (YES), con una probabilidad posterior de:
\[P(\text{YES} \mid \text{datos}) \approx 98.5\% \qquad P(\text{NO} \mid \text{datos}) \approx 1.5\%\]
Esto tiene sentido porque:
El valor de \(LD1 \approx 0\) para este paciente promedio indica que se ubica justo en el punto intermedio del eje discriminante, pero la probabilidad a priori tan alta del grupo YES (87.4%) es suficiente para inclinarlo hacia ese grupo.
En este trabajo se aplicó el para estudiar si las variables clínicas y de comportamiento de los pacientes de la base de Lung Cancer permiten clasificarlos en los grupos:
\[ \text{Con cáncer de pulmón (YES)} \quad \text{y} \quad \text{Sin cáncer de pulmón (NO)} \]
El modelo construyó una función discriminante de la forma:
\[ LD_1 = a_1(\text{AGE}) + a_2(\text{SMOKING}) + a_3(\text{YELLOW\_FINGERS}) + a_4(\text{ANXIETY}) + \cdots + a_{14}(\text{CHEST\_PAIN}) \]
Los resultados muestran que existe una clara capacidad de discriminación entre ambos grupos a partir de los síntomas y hábitos evaluados. En particular, variables como el consumo de alcohol, la fatiga y la presencia de alergias presentan un peso importante en la función discriminante, lo que indica que contribuyen significativamente a diferenciar pacientes con y sin cáncer de pulmón.
La exactitud del modelo fue:
\[ Exactitud = 0.935 \approx 93.5\% \]
mientras que la exactitud obtenida mediante validación cruzada fue:
\[ Exactitud_{CV} = 0.922 \approx 92.2\% \]
La diferencia relativamente pequeña entre ambas métricas sugiere que el modelo no presenta problemas graves de sobreajuste y mantiene una buena capacidad de generalización.
No obstante, es importante señalar que los supuestos teóricos del LDA, como la normalidad multivariada y la igualdad de matrices de covarianza, no se cumplen estrictamente en los datos. A pesar de ello, el modelo mantiene un desempeño sólido, lo que evidencia la robustez del método ante ciertas violaciones de sus supuestos.
Adicionalmente, el desbalance en las clases (mayor proporción de pacientes con cáncer) influye en el comportamiento del modelo, generando una mayor tendencia a clasificar observaciones como positivas. Desde una perspectiva clínica, este sesgo puede ser aceptable, ya que el costo de un falso negativo (no detectar cáncer) es considerablemente más alto que el de un falso positivo.
En conclusión, el análisis confirma que las variables clínicas y de comportamiento consideradas contienen información relevante para la clasificación de pacientes con cáncer de pulmón. El modelo LDA puede ser utilizado como una herramienta de apoyo en la detección temprana, aunque sus resultados deben interpretarse con cautela y complementarse con evaluaciones médicas especializadas.