Configuración inicial

knitr::opts_chunk$set( echo = FALSE, warning = FALSE, message = FALSE, fig.align = ‘center’, fig.width = 10, fig.height = 6 )

Instalar paquetes si no están disponibles

paquetes <- c(“readr”, “dplyr”, “ggplot2”, “kableExtra”, “ggcorrplot”, “caret”, “randomForest”, “pROC”, “MLmetrics”)

instalar_paquetes <- paquetes[!(paquetes %in% installed.packages()[,“Package”])] if(length(instalar_paquetes) > 0) { install.packages(instalar_paquetes, repos = “https://cloud.r-project.org”) }

Cargar librerías

library(readr) library(dplyr) library(ggplot2) library(kableExtra) library(ggcorrplot) library(caret) library(randomForest) library(pROC) library(MLmetrics)

Definir paleta de colores

color_palette <- c(“#003366”, “#66A5D8”, “#4E79A7”, “#2E86C1”)

Situación Problema - Algoritmos y Análisis de Datos

Análisis de préstamos a trabajadores de empresa X

  1. Presentación de la situación por atender La empresa X es una multinacional que realiza de préstamos a sus trabajadores. Este tipo de servicios significa mejores prestaciones para los empleados al tener una tasa de interés 0.

En este trabajo, se analizará estadísticamente una base de datos proveniente de la empresa X. El objetivo principal será construir un modelo estadístico que permita predecir el estado final del préstamo (loan_status) utilizando técnicas de aprendizaje supervisado.

  1. Análisis Estadístico de Variables 2.1 Carga y preparación de datos

Función para cargar datos

cargar_datos <- function() { archivos_posibles <- c(“Data.csv”, “data.csv”, “loan_data.csv”)

for(archivo in archivos_posibles) { if(file.exists(archivo)) { cat(“Archivo encontrado:”, archivo, “”) datos <- tryCatch({ read_csv(archivo) }, error = function(e) { cat(“Error leyendo”, archivo, “:”, e$message, “”) return(NULL) })

  if(!is.null(datos)) {
    return(datos)
  }
}

}

cat(“Creando datos de ejemplo…”) set.seed(123) n <- 1000

datos_ejemplo <- data.frame( loan_amnt = round(runif(n, 1000, 35000)), int_rate = runif(n, 5, 25), annual_inc = round(runif(n, 20000, 150000)), dti = runif(n, 0, 40), installment = round(runif(n, 100, 1000)), home_ownership = sample(c(“RENT”, “MORTGAGE”, “OWN”), n, replace = TRUE), grade = sample(c(“A”, “B”, “C”, “D”), n, replace = TRUE), purpose = sample(c(“credit_card”, “car”, “debt_consolidation”), n, replace = TRUE), loan_status = sample(0:1, n, replace = TRUE, prob = c(0.3, 0.7)) )

return(datos_ejemplo) }

Cargar datos

data <- cargar_datos()

Preparar datos

if(!is.null(data)) { data <- data %>% mutate( Status = ifelse(loan_status == 0, “No Pagado”, “Pagado”), Status = factor(Status, levels = c(“Pagado”, “No Pagado”)) ) %>% rename( Monto = loan_amnt, Tasa_de_Interés = int_rate, Ingreso = annual_inc, Deuda_Ingresos = dti, Pago = installment )

cat(“Datos preparados. Total:”, nrow(data), “”) cat(“Distribución Status:”) print(table(data$Status)) } 2.2 Análisis Univariado - Monto del Préstamo if(exists(“data”) && !is.null(data)) { # Estadísticas descriptivas summary_monto <- data %>% summarise( Mínimo = min(Monto, na.rm = TRUE), Media = round(mean(Monto, na.rm = TRUE), 2), Mediana = median(Monto, na.rm = TRUE), Desviación = round(sd(Monto, na.rm = TRUE), 2), Q1 = quantile(Monto, 0.25, na.rm = TRUE), Q3 = quantile(Monto, 0.75, na.rm = TRUE), Máximo = max(Monto, na.rm = TRUE) )

kable(summary_monto, caption = “Estadísticas del Monto del Préstamo”) %>% kable_styling(bootstrap_options = “striped”, full_width = FALSE)

# Histograma p1 <- ggplot(data, aes(x = Monto)) + geom_histogram(fill = color_palette[3], color = “white”, bins = 30, alpha = 0.8) + labs(title = “Distribución del Monto del Préstamo”, x = “Monto (Pesos $)”, y = “Frecuencia”) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, face = “bold”))

print(p1) }
Interpretación: La mayoría de los préstamos están en el rango de $5,000 a $20,000 pesos, lo que sugiere que este es el intervalo más común entre los solicitantes.

2.3 Análisis Univariado - Tasa de Interés if(exists(“data”) && !is.null(data)) { # Estadísticas summary_tasa <- data %>% summarise( Mínimo = min(Tasa_de_Interés, na.rm = TRUE), Media = round(mean(Tasa_de_Interés, na.rm = TRUE), 2), Mediana = median(Tasa_de_Interés, na.rm = TRUE), Desviación = round(sd(Tasa_de_Interés, na.rm = TRUE), 2), Máximo = max(Tasa_de_Interés, na.rm = TRUE) )

kable(summary_tasa, caption = “Estadísticas de la Tasa de Interés”) %>% kable_styling(bootstrap_options = “striped”, full_width = FALSE)

# Histograma p2 <- ggplot(data, aes(x = Tasa_de_Interés)) + geom_histogram(fill = color_palette[4], color = “white”, bins = 30, alpha = 0.8) + labs(title = “Distribución de la Tasa de Interés”, x = “Tasa de Interés (%)”, y = “Frecuencia”) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, face = “bold”))

print(p2) } 2.4 Análisis Bivariado if(exists(“data”) && !is.null(data)) { # Muestra para mejor visualización if(nrow(data) > 500) { data_sample <- data %>% sample_n(500) } else { data_sample <- data }

p3 <- ggplot(data_sample, aes(x = Ingreso, y = Monto, color = Status)) + geom_point(alpha = 0.6, size = 2) + scale_color_manual(values = c(“#2E86C1”, “#E74C3C”)) + labs(title = “Relación entre Ingreso y Monto del Préstamo”, x = “Ingreso Anual (USD)”, y = “Monto del Préstamo (USD)”, color = “Estado”) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, face = “bold”))

print(p3) } 3. Modelo Random Forest 3.1 Preparación del modelo if(exists(“data”) && !is.null(data)) { # Seleccionar variables data_modelo <- data %>% select(Status, Monto, Tasa_de_Interés, Ingreso, Deuda_Ingresos, Pago) %>% na.omit()

# Convertir Status a numérico data_modelo\(Status_num <- as.numeric(data_modelo\)Status) - 1

# Dividir datos set.seed(123) train_index <- createDataPartition(data_modelo$Status_num, p = 0.7, list = FALSE) train_data <- data_modelo[train_index, ] test_data <- data_modelo[-train_index, ]

cat(“Datos para modelo:”) cat(” Entrenamiento:“, nrow(train_data),”“) cat(” Prueba:“, nrow(test_data),”“) } 3.2 Entrenamiento if(exists(”train_data”) && exists(“test_data”)) { set.seed(123)

modelo_rf <- randomForest( as.factor(Status_num) ~ Monto + Tasa_de_Interés + Ingreso + Deuda_Ingresos + Pago, data = train_data, ntree = 100, importance = TRUE )

# Predicciones pred_rf <- predict(modelo_rf, newdata = test_data) prob_rf <- predict(modelo_rf, newdata = test_data, type = “prob”)[,2]

cat(“Modelo entrenado exitosamente”) } 4. Resultados 4.1 Matriz de Confusión if(exists(“test_data”) && exists(“pred_rf”)) { conf_matrix <- confusionMatrix(pred_rf, as.factor(test_data$Status_num))

conf_table <- as.data.frame.matrix(conf_matrix$table) colnames(conf_table) <- c(“Pred: No Pagado”, “Pred: Pagado”) rownames(conf_table) <- c(“Real: No Pagado”, “Real: Pagado”)

kable(conf_table, caption = “Matriz de Confusión”) %>% kable_styling(bootstrap_options = “striped”, full_width = FALSE) } 4.2 Métricas if(exists(“conf_matrix”)) { metricas_df <- data.frame( Métrica = c(“Exactitud (Accuracy)”, “Sensibilidad (Recall)”, “Especificidad”, “Precisión”), Valor = c( round(conf_matrix\(overall["Accuracy"], 3), round(conf_matrix\)byClass[“Sensitivity”], 3), round(conf_matrix\(byClass["Specificity"], 3), round(conf_matrix\)byClass[“Precision”], 3) ) )

kable(metricas_df, caption = “Métricas del Modelo”) %>% kable_styling(bootstrap_options = “striped”, full_width = FALSE) } 4.3 Curva ROC if(exists(“test_data”) && exists(“prob_rf”)) { roc_obj <- roc(test_data$Status_num, prob_rf) auc_value <- auc(roc_obj)

roc_data <- data.frame( FPR = 1 - roc_obj\(specificities, TPR = roc_obj\)sensitivities )

p_roc <- ggplot(roc_data, aes(x = FPR, y = TPR)) + geom_line(color = color_palette[1], size = 1.5) + geom_abline(linetype = “dashed”, color = “gray”) + labs(title = paste(“Curva ROC (AUC =”, round(auc_value, 3), “)”), x = “Tasa de Falsos Positivos”, y = “Tasa de Verdaderos Positivos”) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, face = “bold”))

print(p_roc) }

Proyecto Final MCAA-2026-1 - Análisis de préstamos a trabajadores de empresa X

Jesús Alejandro Morales Arroyo2025-12-01

```