En la era del Big Data, la capacidad de transformar datos brutos en conocimiento accionable es un pilar fundamental para la toma de decisiones estratégicas. El modelado predictivo combina la rigurosidad estadística con la potencia algorítmica de las ciencias de la computación para anticipar escenarios futuros y mitigar riesgos.
Este documento presenta una implementación práctica y estructurada de dos de los algoritmos de clasificación más robustos y utilizados en la analítica de datos: la Regresión Logística Binaria (un pilar clásico de la modelación estadística) y los Bosques de Clasificación o Random Forest (un enfoque moderno basado en ensambles de aprendizaje supervisado). A través de entornos analíticos controlados, se evaluará el comportamiento, la precisión y la interpretabilidad de ambos modelos, garantizando los principios de reproducibilidad técnica.
En el ámbito de la salud pública y la analítica médica, la detección temprana de enfermedades crónicas como la diabetes representa un desafío crítico. El diagnóstico tardío incrementa los costos del sistema de salud y reduce la calidad de vida del paciente. El problema radica en la necesidad de identificar patrones combinados en variables fisiológicas como la Edad, los niveles de Glucosa en sangre y el Índice de Masa Corporal (IMC) para clasificar con precisión si un individuo pertenece al grupo de riesgo (1) o al grupo sano (0).
Desarrollar y evaluar un modelo de Regresión Logística Binaria capaz de estimar la probabilidad de riesgo de padecer diabetes en un conjunto de pacientes, utilizando variables predictoras cuantitativas para establecer un clasificador óptimo que optimice la toma de decisiones médicas preventivas.
La Regresión Logística Binaria se utiliza cuando la variable respuesta es categórica dicotómica (0 o 1). En lugar de predecir directamente el valor de la variable, el modelo predice la probabilidad matemática (\(p\)) de que ocurra el evento de interés.
Para evitar que el modelo lineal arroje probabilidades fuera del rango \([0, 1]\), se utiliza la función Logit, que define los log-odds (logaritmo de la razón de probabilidades):
\[\ln\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_k X_k\]
Al despejar la probabilidad \(p\), obtenemos la Función Sigmoide o Logística:
\[p = \frac{1}{1 + e^{-(\beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_k X_k)}}\]
Donde: - \(p\) es la probabilidad de que el paciente tenga riesgo de diabetes. - \(\beta_0\) es el intercepto del modelo. - \(\beta_i\) son los coeficientes asociados a cada variable predictora (\(X_i\)).
Para garantizar la consistencia analítica, se establece una semilla
estática (set.seed(42)) que genera una distribución normal
controlada para las variables predictoras clínicas de 200 pacientes.
# Configuración de reproducibilidad
set.seed(42)
# Construcción de la matriz de datos clínicos de ejemplo
datos_medicina <- data.frame(
Edad = round(rnorm(200, 45, 10)),
Glucosa = round(rnorm(200, 120, 30)),
IMC = round(rnorm(200, 28, 5), 1),
Resultado = sample(c(0, 1), 200, replace = TRUE, prob = c(0.6, 0.4))
)
# Visualización de la estructura inicial (Primeros 10 registros)
knitr::kable(head(datos_medicina, 10), caption = "Tabla 1: Muestra analítica del dataset de diabetes")| Edad | Glucosa | IMC | Resultado |
|---|---|---|---|
| 59 | 60 | 34.7 | 0 |
| 39 | 130 | 23.7 | 0 |
| 49 | 155 | 28.3 | 1 |
| 51 | 182 | 28.2 | 0 |
| 49 | 79 | 25.1 | 1 |
| 44 | 85 | 23.0 | 1 |
| 60 | 99 | 28.0 | 1 |
| 44 | 88 | 31.3 | 0 |
| 65 | 101 | 35.4 | 0 |
| 44 | 114 | 18.5 | 1 |
Utilizamos la función nativa glm() (Generalized Linear
Models). Es imperativo definir el argumento
family = binomial para indicarle al entorno de R que
ejecute una regresión logística binaria y no una lineal estándar.
# Ajuste del modelo matemático en R
modelo_diabetes <- glm(Resultado ~ Glucosa + IMC + Edad, data = datos_medicina, family = binomial)
# Resumen detallado del comportamiento estadístico de los coeficientes
summary(modelo_diabetes)##
## Call:
## glm(formula = Resultado ~ Glucosa + IMC + Edad, family = binomial,
## data = datos_medicina)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.644619 1.240088 -1.326 0.185
## Glucosa 0.001229 0.005144 0.239 0.811
## IMC 0.000835 0.028319 0.029 0.976
## Edad 0.022826 0.015285 1.493 0.135
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 267.50 on 199 degrees of freedom
## Residual deviance: 265.21 on 196 degrees of freedom
## AIC: 273.21
##
## Number of Fisher Scoring iterations: 4
set.seed(42): Garantiza que la generación aleatoria de
datos sea idéntica cada vez que compilemos el RMarkdown.rnorm(200, mean, sd): Genera datos que siguen una
distribución gaussiana simulando métricas reales de salud.glm(...): Ejecuta el ajuste por Máxima Verosimilitud
para encontrar los estimadores \(\beta\).predict(..., type = "response"): Transforma las
unidades log-odds directamente a la escala de probabilidad \([0, 1]\).La gráfica inferior representa las curvas de densidad de probabilidad. Permite evaluar visualmente si el algoritmo logra separar eficientemente a los individuos sanos de aquellos que presentan la patología según sus niveles de glucosa.
# Generación de la visualización avanzada con ggplot2
ggplot(datos_medicina, aes(x = Glucosa, fill = as.factor(Resultado))) +
geom_density(alpha = 0.5) +
scale_fill_manual(values = c("#7f8c8d", "#3498db"), labels = c("Sano (0)", "Diabetes (1)")) +
labs(
title = "Análisis de Regresión Logística Binaria",
subtitle = "Distribución de Densidad de Glucosa según el Diagnóstico Clínico Real",
x = "Nivel de Glucosa en Sangre (mg/dL)",
y = "Densidad de Pacientes",
fill = "Estado del Diagnóstico"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, color = "#2c3e50"),
plot.subtitle = element_text(size = 11, italic = TRUE),
panel.grid.minor = element_blank()
)En el ecosistema comercial y empresarial modernos, la retención de usuarios es un factor crítico de rentabilidad. La pérdida masiva de suscriptores (conocida en la industria como Churn) impacta negativamente los ingresos recurrentes. El problema radica en analizar el historial de comportamiento —tales como la cantidad de interacciones con Soporte Asistido, el tipo de Meses de Contrato vigentes y el Gasto Mensual— para predecir si un cliente va a cancelar (“Si”) o mantener (“No”) su servicio comercial.
Construir y validar un algoritmo de Bosques de Clasificación (Random Forest) enfocado en la gobernanza de datos comerciales para categorizar de forma automatizada la tasa de deserción de clientes, evaluando el nivel de importancia de cada métrica operativa en la pureza de la clasificación final.
Random Forest es un algoritmo de aprendizaje supervisado de ensamble (Bagging). Construye múltiples árboles de decisión independientes durante el entrenamiento y combina sus salidas mediante un sistema de votación mayoritaria para generar la predicción final.
La métrica utilizada para evaluar la separación en los nodos de los árboles es el Índice de Impureza de Gini, formulado como:
\[Gini = 1 - \sum_{i=1}^{C} (p_i)^2\]
Donde \(p_i\) representa la probabilidad de que un registro seleccionado pertenezca a la clase categórica \(i\) dentro de un nodo determinado. El algoritmo calcula el Mean Decrease Gini (Disminución Media de Gini), que mide cuánta pureza aporta cada variable predictora al modelo global. Una mayor disminución indica que la variable es más importante en la gestión de datos corporativos.
Se genera una estructura de datos sintética que emula el comportamiento analítico de un sistema ERP/CRM empresarial corporativo con 200 registros estructurados.
# Fijado de semilla comercial
set.seed(123)
# Construcción del dataframe corporativo
datos_ventas <- data.frame(
Soporte_Asistido = round(rpois(200, 3)),
Meses_Contrato = round(runif(200, 1, 24)),
Gasto_Mensual = round(rnorm(200, 75, 20), 2),
Cancelado = sample(c("No", "Si"), 200, replace = TRUE, prob = c(0.7, 0.3))
)
# Restricción técnica: Conversión explícita a factor categórico para clasificación
datos_ventas$Cancelado <- as.factor(datos_ventas$Cancelado)
# Visualización de la estructura de datos comerciales
knitr::kable(head(datos_ventas, 10), caption = "Tabla 2: Matriz comercial de fidelización de clientes")| Soporte_Asistido | Meses_Contrato | Gasto_Mensual | Cancelado |
|---|---|---|---|
| 2 | 6 | 118.98 | No |
| 4 | 23 | 101.25 | No |
| 2 | 15 | 69.70 | No |
| 5 | 13 | 85.86 | No |
| 6 | 10 | 66.71 | No |
| 0 | 21 | 65.48 | Si |
| 3 | 9 | 59.23 | No |
| 5 | 8 | 63.11 | No |
| 3 | 5 | 108.02 | Si |
| 3 | 5 | 73.92 | No |
Invocamos la función randomForest() ajustando el modelo
con un parámetro controlado de ntree = 100 árboles para
balancear rendimiento, precisión y estabilidad computacional.
# Entrenamiento analítico del ensamble algorítmico
modelo_bosque <- randomForest(
Cancelado ~ Soporte_Asistido + Meses_Contrato + Gasto_Mensual,
data = datos_ventas,
ntree = 100,
importance = TRUE
)
# Resultados de la matriz de confusión e índice de error Out-Of-Bag (OOB)
print(modelo_bosque)##
## Call:
## randomForest(formula = Cancelado ~ Soporte_Asistido + Meses_Contrato + Gasto_Mensual, data = datos_ventas, ntree = 100, importance = TRUE)
## Type of random forest: classification
## Number of trees: 100
## No. of variables tried at each split: 1
##
## OOB estimate of error rate: 37.5%
## Confusion matrix:
## No Si class.error
## No 122 21 0.1468531
## Si 54 3 0.9473684
as.factor(datos_ventas$Cancelado): Requisito
metodológico obligatorio. Si la variable respuesta no es un factor, R
ejecutará por defecto un bosque de regresión lineal en lugar de un
bosque de clasificación categórica.rpois(200, 3): Simula variables de conteo discreto
(como el número de llamadas a soporte técnico) mediante una distribución
de Poisson.ntree = 100: Especifica la cantidad de árboles de
decisión independientes que se construirán para conformar el bosque
predictivo.El siguiente gráfico de barras horizontales revela de forma directa el impacto de cada indicador en el negocio. Las variables situadas en la parte superior poseen mayor peso matemático al predecir la fuga de clientes.
# Construcción del gráfico de importancia mediante GGPlot2
ggplot(tabla_importancia, aes(x = reorder(Variable, MeanDecreaseGini), y = MeanDecreaseGini)) +
geom_bar(stat = "identity", fill = "#2c3e50", width = 0.5) +
coord_flip() +
labs(
title = "Bosques de Clasificación: Gráfica de Importancia de Variables",
subtitle = "Evaluación del impacto de métricas comerciales sobre la pureza del nodo (Gini)",
x = "Métricas Analizadas del Cliente",
y = "Importancia Estructural (Mean Decrease Gini)"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, color = "#2c3e50"),
plot.subtitle = element_text(size = 11, italic = TRUE),
panel.grid.major.y = element_blank()
)La integración de herramientas analíticas bajo entornos web estructurados como RPubs permite comunicar hallazgos técnicos de forma clara y profesional: