Universidad del Valle

Programa de Ingeniería Industrial

Algoritmos de Clasificación para Gestión de Datos

Presentado por:

Erik Tombe-2376283

Samuel Santander-2451045

Ana Sofía Ramos-2463326

Fecha de entrega: 11 de junio de 2026


ALGORITMOS DE CLASIFICACIÓN

Los algoritmos de clasificación son métodos de aprendizaje automático supervisado que permiten asignar una categoría o etiqueta a nuevas observaciones, aprendiendo patrones a partir de datos históricos etiquetados. Son ampliamente utilizados en diagnóstico médico, detección de fraude, análisis de riesgo crediticio y muchos otros campos de la ingeniería industrial.


ALGORITMO 1: NAIVE BAYES


DEFINICIÓN

El algoritmo «Naive Bayes» es un clasificador probabilístico basado en el «Teorema de Bayes», el modelo fue creado por el matemático inglés, Thomas Bayes (1701 – 1761).

Naive Bayes es un algoritmo con aplicaciones muy versátiles, debiendo ser utilizado en los casos en que las variables sean condicionalmente independientes. También es un algoritmo que presenta un óptimo desempeño clasificando categorías muy bien separadas y para datos con dimensiones altas, donde la complejidad del modelo es menos importante.


FÓRMULA

El algoritmo se basa en el Teorema de Bayes:

\[\color{#BA4A00}{\Large P(A|B) = (P(B|A) \times P(A)) \div P(B)}\]

Dónde:

  • \(P(B|A)\): Probabilidad de que B suceda, dado que A sucedió.
  • \(P(A)\): Probabilidad de que ocurra A.
  • \(P(B)\): Probabilidad de que ocurra B.

Veamos un ejemplo del Teorema de Bayes en el diagnóstico de enfermedades:


HIPÓTESIS

El algoritmo Naive Bayes puede predecir con una exactitud superior al 75% si un paciente tiene o no diabetes, utilizando variables clínicas como glucosa, presión arterial, índice de masa corporal y edad.

Para verificar esta hipótesis, se aplicó el algoritmo sobre el dataset Pima Indians Diabetes Database, el cual fue obtenido de la plataforma otorgada por el profesor (Kaggle). Este conjunto de datos contiene registros clínicos de pacientes de sexo femenino mayores de 21 años, pertenecientes a la comunidad Pima, permitiendo comparar las predicciones generadas por el modelo con los diagnósticos reales de cada paciente.


BASE DE DATOS

La base de datos contiene información clínica de 768 pacientes mujeres de origen indígena Pima. Las variables son:

Vista de la tabla (Diabetes)

datos_diabetes <- read.csv("diabetes_traducido.csv")
datos_diabetes <- na.omit(datos_diabetes)

head(datos_diabetes, 5) %>%
  kbl(
    align = "c",
    caption = "Primeros registros de salud"
  ) %>%
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover",
      "condensed"
    ),
    full_width = FALSE
  ) %>%
  row_spec(
    0,
    bold = TRUE,
    color = "white",
    background = "#BA4A00"
  )
Primeros registros de salud
Embarazos Glucosa Presion_Arterial Grosor_Pliegue_Cutaneo Insulina IMC Funcion_Hereditaria_Diabetes Edad Resultado
6 148 72 35 0 33.6 0.627 50 1
1 85 66 29 0 26.6 0.351 31 0
8 183 64 0 0 23.3 0.672 32 1
1 89 66 23 94 28.1 0.167 21 0
0 137 40 35 168 43.1 2.288 33 1

Diagrama de dispersión (Diabetes)

ggplot(
  datos_diabetes,
  aes(
    x = Glucosa,
    y = Insulina,
    color = as.factor(Resultado)
  )
) +
  geom_point(alpha = 0.5) +
  geom_smooth(
    method = "lm",
    color = "red"
  ) +
  labs(
    title = "Relación Glucosa vs Insulina",
    x = "Glucosa",
    y = "Insulina",
    color = "Resultado"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Distribución Lognormal: Glucosa

ggplot(datos_diabetes, aes(x = Glucosa)) +
  geom_density(
    fill = "#BA4A00",
    alpha = 0.3
  ) +
  scale_x_log10() +
  labs(
    title = "Distribución Lognormal: Glucosa",
    x = "Log(Glucosa)",
    y = "Densidad"
  ) +
  theme_minimal()
## Warning in scale_x_log10(): log-10 transformation introduced infinite values.
## Warning: Removed 5 rows containing non-finite outside the scale range
## (`stat_density()`).

Distribución Gaussiana: Edad

media_d <- mean(datos_diabetes$Edad)
sd_d <- sd(datos_diabetes$Edad)

ggplot(datos_diabetes, aes(x = Edad)) +
  geom_histogram(
    aes(y = after_stat(density)),
    bins = 20,
    fill = "skyblue",
    color = "white"
  ) +
  stat_function(
    fun = dnorm,
    args = list(
      mean = media_d,
      sd = sd_d
    ),
    color = "darkred",
    linewidth = 1
  ) +
  labs(
    title = "Distribución Gaussiana: Edad",
    x = "Edad",
    y = "Densidad"
  ) +
  theme_minimal()

Distribución Poisson: Embarazos

frec_d <- table(datos_diabetes$Embarazos)
prob_d <- as.numeric(frec_d) /
          length(datos_diabetes$Embarazos)

plot(
  as.numeric(names(frec_d)),
  prob_d,
  type = "b",
  pch = 19,
  col = "orange",
  main = "Poisson: Número de Embarazos",
  xlab = "Frecuencia",
  ylab = "Probabilidad"
)

APLICACIÓN DEL ALGORITMO

El modelo Naive Bayes aprende la probabilidad de cada valor de las variables clínicas dado el diagnóstico (con o sin diabetes). Luego, para un nuevo paciente, multiplica esas probabilidades y predice la clase más probable. Los pasos son:

  1. Dividir los datos: 70% para entrenar el modelo y 30% para evaluarlo.
  2. Entrenar: el modelo calcula las probabilidades de cada variable para cada clase (0 = No diabético, 1 = Diabético).
  3. Predecir: aplica el Teorema de Bayes sobre los datos de prueba.
  4. Evaluar: compara las predicciones con los diagnósticos reales usando una matriz de confusión.
# 1. usa los datos para saber quien tiene diabetes y quien no
datos_diabetes$Resultado <- as.factor(datos_diabetes$Resultado)

# 2. Dividir datos: 70% entrenamiento - 30% prueba
set.seed(42)
indice_muesta <- createDataPartition(datos_diabetes$Resultado, p = 0.7, list = FALSE)
datos_entrenamiento <- datos_diabetes[indice_muesta, ]
datos_prueba <- datos_diabetes[-indice_muesta, ]

# 3. Entrenar el modelo Naive Bayes
modelo_bayes <- naiveBayes(Resultado ~ Glucosa + Presion_Arterial + IMC + Edad + Embarazos,
                        data = datos_entrenamiento)

# 4. Predecir sobre datos de prueba y evaluar
prediciones_diabetes <- predict(modelo_bayes, datos_prueba)
matrix_diabetes  <- confusionMatrix(prediciones_diabetes, datos_prueba$Resultado)

GRÁFICA - VERIFICACIÓN DE HIPÓTESIS

metricas <- c(
  Exactitud     = as.numeric(matrix_diabetes$overall["Accuracy"]),
  Sensibilidad  = as.numeric(matrix_diabetes$byClass["Sensitivity"]),
  Especificidad = as.numeric(matrix_diabetes$byClass["Specificity"])
) * 100


barplot(metricas,
        col       = "#BA4A00",
        ylim      = c(0, 110),
        main      = "Métricas del Modelo Naive Bayes",
        ylab      = "Porcentaje (%)",
        border    = "white",
        las       = 1)

abline(h = 75, col = "red", lty = 2, lwd = 2)

text(x = c(0.7, 1.9, 3.1),
     y = metricas + 4,
     labels = paste0(round(metricas, 1), "%"),
     cex = 1, font = 2)


CONCLUSIÓN HIPÓTESIS 1

El modelo Naive Bayes fue evaluado sobre 230 pacientes del conjunto de prueba, obteniendo una exactitud del 77.39%, una sensibilidad del 86% y una especificidad del 61.25%.

La sensibilidad indica la capacidad del modelo para detectar correctamente a los pacientes diabéticos, mientras que la especificidad refleja su capacidad para identificar a los pacientes sanos. En un contexto clínico, ambas métricas son igualmente importantes para garantizar un diagnóstico confiable.

Con base en estos resultados, la hipótesis H SE VERIFICA, ya que el modelo superó el umbral del 75% con una exactitud de 77.39%..

Las barras de color naranja superan el umbral del 75% marcado por la línea roja, mientras que las grises no lo alcanzan. Una sensibilidad alta significa que el modelo detecta bien a los pacientes diabéticos; una especificidad alta significa que no confunde a los pacientes sanos.


ALGORITMO 2: ÁRBOLES DE DECISION


DEFINICIÓN

Un Árbol de Decisión es un algoritmo de aprendizaje supervisado que representa las decisiones de clasificación en forma de árbol jerárquico. Cada nodo interno representa una pregunta sobre una variable, cada rama representa una posible respuesta, y cada hoja (nodo terminal) representa la clase predicha.

El árbol se construye dividiendo recursivamente el conjunto de datos en subconjuntos más homogéneos usando criterios matemáticos de impureza. Los más comunes son el Índice de Gini y la Entropía de Información.


FÓRMULAS

Índice de Gini — Mide qué tan mezcladas están las clases en un nodo. Un valor de 0 significa nodo puro (todos de la misma clase):

\[\color{#BA4A00}{\Large Gini(t) = 1 - \sum_{k=1}^{K} p_k^2}\]

Entropía — mide el desorden o incertidumbre dentro de un nodo. A mayor entropía, más mezcladas están las clases:

\[\color{#BA4A00}{\Large H(t) = -\sum_{k=1}^{K} p_k \log_2(p_k)}\]

Ganancia de Información — mide cuánto mejora la pureza al dividir un nodo por una variable. El árbol elige siempre la variable con mayor ganancia:

\[\color{#BA4A00}{\Large IG(t, a) = H(t) - \sum_{v \in vals(a)} \frac{|t_v|}{|t|} H(t_v)}\]

Donde:


HIPÓTESIS

El algoritmo Árbol de Decisión puede clasificar correctamente si un préstamo será pagado o incumplido (estado del préstamo: 0 = pagado, 1 = incumplido) con una exactitud superior al 80%, utilizando variables financieras como los ingresos de la persona, la edad, y la tasa de interés del préstamo.

Para verificar esta hipótesis, se construyó un Árbol de Decisión sobre el Credit Risk Dataset, obtenido de la plataforma otorgada por el profesor (Kaggle), permitiendo comparar las clasificaciones generadas por el modelo con el estado real de cada préstamo.


BASE DE DATOS

Se utiliza un dataset de riesgo crediticio bancario, las variables empleadas son:

Vista de la tabla (Riesgo Crediticio)

datos_credito <- read.csv("credit_risk_dataset_traducido.csv")
datos_credito <- na.omit(datos_credito)

head(datos_credito, 5) %>%
  kbl(
    align = "c",
    caption = "Primeros registros financieros"
  ) %>%
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover",
      "condensed"
    ),
    full_width = FALSE
  ) %>%
  row_spec(
    0,
    bold = TRUE,
    color = "white",
    background = "#BA4A00"
  )
Primeros registros financieros
edad_persona ingresos_persona vivienda_persona antiguedad_empleo intencion_prestamo grado_prestamo monto_prestamo tasa_interes estado_prestamo porcentaje_ingreso incumplimiento_previo longitud_historial.
24 54400 ARRIENDO 8 MÉDICO C 35000 14.27 1 0.55 4
21 9900 PROPIA 2 EMPRENDIMIENTO A 2500 7.14 1 0.25 NO 2
26 77100 ARRIENDO 8 EDUCACIÓN B 35000 12.42 1 0.45 NO 3
24 78956 ARRIENDO 5 MÉDICO B 35000 11.11 1 0.44 NO 4
24 83000 ARRIENDO 8 PERSONAL A 35000 8.90 1 0.42 NO 2

Diagrama de dispersión (Crédito)

ggplot(
  datos_credito,
  aes(
    x = ingresos_persona,
    y = monto_prestamo,
    color = as.factor(estado_prestamo)
  )
) +
  geom_point(alpha = 0.4) +
  geom_smooth(
    method = "lm",
    color = "red"
  ) +
  labs(
    title = "Relación Ingresos vs Monto Préstamo",
    x = "Ingresos",
    y = "Monto",
    color = "Estado del Préstamo\n(0=Pagado, 1=Incumplido)"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

APLICACIÓN DEL ALGORITMO

El Árbol de Decisión aprende reglas de división a partir de los datos de entrenamiento. Para clasificar un préstamo nuevo, recorre el árbol respondiendo preguntas sobre las variables financieras hasta llegar a una hoja que indica si el préstamo será pagado o incumplido. Los pasos son:

  1. Dividir los datos: 70% para entrenamiento y 30% para evaluación.
  2. Construir el árbol: en cada nodo elige la variable que más reduce la impureza (mayor Ganancia de Información).
  3. Visualizar: el árbol muestra en cada nodo la condición de división, la clase predicha y el porcentaje de datos.
  4. Evaluar: se comparan las predicciones con las etiquetas reales mediante una matriz de confusión.
# 1. Convertir la variable objetivo a factor
datos_credito$estado_prestamo <- as.factor(datos_credito$estado_prestamo)

# 2. Dividir datos: 70% entrenamiento - 30% prueba
set.seed(42)
indice_credito <- createDataPartition(datos_credito$estado_prestamo, p = 0.7, list = FALSE)
datos_entre <- datos_credito[indice_credito, ]
datos_prueb  <- datos_credito[-indice_credito, ]

# 3. Construir el Árbol de Decisión
modelo_tree <- rpart(
  estado_prestamo ~ ingresos_persona + edad_persona + tasa_interes,
  data   = datos_entre,
  method = "class"
)

# 4. Visualizar el árbol
rpart.plot(
  modelo_tree,
  main = "Árbol de Decisión: Estado del Préstamo"
)

# 5. Predecir y evaluar
pred_tree <- predict(modelo_tree, datos_prueb, type = "class")
cm_tree   <- confusionMatrix(pred_tree, datos_prueb$estado_prestamo)

# 6. Calcular métricas para el texto
exactitud_tree <- round(as.numeric(cm_tree$overall["Accuracy"]) * 100, 2)
total_tree     <- sum(cm_tree$table)
imp_sorted     <- sort(modelo_tree$variable.importance, decreasing = TRUE)
var_top        <- names(imp_sorted)[1]
imp_top        <- round(imp_sorted[1] / sum(imp_sorted) * 100, 1)

GRÁFICA - VERIFICACIÓN DE HIPÓTESIS

imp      <- modelo_tree$variable.importance
imp_norm <- sort(imp / sum(imp) * 100, decreasing = FALSE)

par(mar = c(5, 16, 4, 4))

barplot(imp_norm,
        horiz  = TRUE,
        col    = "#BA4A00",
        main   = "Variables más importantes para el árbol de decisión",
        xlab   = "Importancia relativa (%)",
        border = "white",
        las    = 1,
        xlim   = c(0, max(imp_norm) + 10))

text(x      = imp_norm + 1.5,
     y      = seq(0.7, length(imp_norm) * 1.2, by = 1.2),
     labels = paste0(round(imp_norm, 1), "%"),
     cex    = 0.9, font = 2)

CONCLUSIÓN HIPÓTESIS 2

El modelo Árbol de Decisión fue evaluado sobre 8590 clientes del conjunto de prueba, alcanzando una exactitud del 82.43%.

La variable más determinante en las decisiones del árbol fue tasa_interes, con una importancia relativa del 65.5%, lo que indica que esta característica es la que mejor separa los préstamos pagados de los incumplidos.

Con base en estos resultados, la hipótesis H SE VERIFICA, ya que el modelo superó el umbral del 80% con una exactitud de 82.43%..

La gráfica muestra qué tan importante fue cada variable para las decisiones del árbol. Las variables con mayor porcentaje fueron las más utilizadas en los nodos superiores, es decir, los factores que más influyen en el estado del préstamo de un cliente.


Referencias