Desarrollar un modelo de regresión logística binaria y Random forest, que permita predecir la probabilidad de morosidad crediticia en función de variables explicativas clave, con el fin de optimizar las políticas de otorgamiento de crédito, segmentar clientes según su perfil de riesgo y apoyar la toma de decisiones en instituciones financieras.
La gestión del riesgo crediticio constituye uno de los pilares
fundamentales en la sostenibilidad del sistema bancario. En un entorno
económico dinámico, caracterizado por la volatilidad de los ingresos y
el endeudamiento creciente de los hogares, las instituciones financieras
enfrentan el reto de diseñar políticas de otorgamiento de crédito
basadas en evidencia empírica. La predicción de morosidad a partir de
variables observables se ha convertido en una necesidad estratégica para
garantizar la salud de las carteras de crédito.
El presente trabajo aborda esta problemática mediante la aplicación
de técnicas de modelado estadístico, para estimar la probabilidad de
incumplimiento en función de variables explicativas clave. Esta
aproximación permite simular escenarios que se ajusten a las tendencias
observadas, con el objetivo de minimizar el riesgo y optimizar la toma
de decisiones.
Se espera que los modelos identifiquen de manera significativa las
variables con mayor poder explicativo sobre el riesgo de incumplimiento.
Asimismo, se anticipa una segmentación efectiva de los clientes en
perfiles de riesgo, lo que permitirá a las entidades financieras adoptar
decisiones más informadas respecto a la asignación de crédito, políticas
de tasa de interés y medidas de mitigación.
La implementación de estas métricas contribuyen a diseñar productos financieros personalizados y a fortalecer las capacidades analíticas de las instituciones crediticias en la etapa de evaluación de solicitudes.
El presente informe tiene como objetivo proporcionar un análisis detallado y argumentado de los datos disponibles, con miras a establecer una comprensión profunda de su comportamiento y estructura. Este paso es fundamental para guiar las decisiones relacionadas con el modelado predictivo o clasificaciones posteriores.
Con base en los datos extraidos de [Hoffman, 2024] a continuación se describen las variables del data set “german_credit.csv”.
Title: German Credit data
Source Information
Professor Dr. Hans Hofmann
Institut f”ur Statistik und “Okonometrie
Universit”at Hamburg
FB Wirtschaftswissenschaften
Von-Melle-Park 5
2000 Hamburg 13
Number of Instances: 1000
Attribute description for german
default: (numerical)
Category of customer
0 : Good customer
1 : Bad customer
account_check_status: (qualitative)
Status of existing checking account
1 : < 0 DM
2 : 0 <= … < 200 DM
3 : >= 200 DM / salary assignments for at least 1 year
4 : no checking account
duration_in_month: (numerical)
Duration in month
1 : 1 <= … < 12
2 : 12 <= … < 24
3 : 24 <= … < 36
4 : 36 <= … < 48
5 : 48 <= … < 60
6 : 60 <= … < 72
credit_history: (qualitative)
Credit history
1 : no credits taken/all credits paid back duly
2 : all credits at this bank paid back duly
3 : existing credits paid back duly till now
4 : delay in paying off in the past
5 : critical account/other credits existing (not at this bank)
purpose: (qualitative)
Purpose
1 : car (new)
2 : car (used)
3 : furniture/equipment
4 : radio/television
5 : domestic appliances
6 : repairs
7 : education
8 : (vacation - does not exist?)
9 : retraining
10 : business
11 : others
credit_amount: (numerical)
Credit amount
1 : 1 <= … < 1000
2 : 1000 <= … < 2000
3 : 2000 <= … < 3000
4 : 3000 <= … < 4000
5 : 4000 <= … < 5000
6 : 5000 <= … < 6000
7 : 6000 <= … < 7000
8 : 7000 <= … < 8000
9 : 8000 <= … < 9000
10 : 9000 <= … < 10000
11 : 10000 <= … < 11000
12 : 11000 <= … < 12000
13 : 12000 <= … < 13000
14 : 13000 <= … < 14000
15 : 14000 <= … < 15000
16 : 15000 <= … < 16000
17 : 16000 <= … < 17000
18 : 17000 <= … < 18000
19 : 18000 <= … < 19000
20 : 19000 <= … < 20000
savings: (qualitative)
Savings account/bonds
5 : … < 100 DM
4 : 100 <= … < 500 DM
3 : 500 <= … < 1000 DM
2 : .. >= 1000 DM
1 : unknown/ no savings account
present_emp_since: (qualitative)
Present employment since
5 : unemployed
4 : … < 1 year
3 : 1 <= … < 4 years 2 : 4 <= … < 7 years
1 : .. >= 7 years
installment_as_income_perc: (numerical)
Installment rate in percentage of disposable income
personal_status_sex: (qualitative)
Personal status and sex
1 : male : divorced/separated
2 : female : divorced/separated/married
3 : male : single
4 : male : married/widowed
5 : female : single
other_debtors: (qualitative)
Other debtors / guarantors
1 : none
2 : co-applicant
3 : guarantor
present_res_since: (numerical)
Present residence since
property: (qualitative)
Property
1 : real estate
2 : if not A121 : building society savings agreement/life
insurance
3 : if not A121/A122 : car or other, not in attribute 6
4 : unknown / no property
age: (numerical)
Age in years
1 : 18 <= … < 30
2 : 30 <= … < 40
3 : 40 <= … < 50
4 : 50 <= … < 60
5 : 60 <= … < 70
6 : 70 <= … < 80
other_installment_plans: (qualitative)
Other installment plans
1 : bank
2 : stores
3 : none
housing: (qualitative)
Housing
1 : rent
2 : own
3 : for free
credits_this_bank: (numerical)
Number of existing credits at this bank
job: (qualitative)
Job
1 : unemployed/ unskilled - non-resident
2 : unskilled - resident
3 : skilled employee / official
4 : management/ self-employed/highly qualified employee/ officer
people_under_maintenance: (numerical)
Number of people being liable to provide maintenance for
telephone: (qualitative)
Telephone
0 : none
1 : yes, registered under the customers name
foreign_worker: (qualitative)
foreign worker
1 : yes
0 : no
Para llevar a cabo el presente análisis, se utilizaron diversas librerías especializadas en el entorno de programación R. Estas herramientas permitieron realizar manipulación eficiente de datos, así como la generación de gráficos y su visualización.
Se calcularon métricas estadísticas para cada variable numérica, tales como la media, la mediana, los cuartiles y la desviación estándar. Estas métricas proporcionan una visión general del comportamiento de cada atributo, permitiendo identificar tendencias centrales y variabilidad. Por ejemplo, variables como ‘rango_edad’ muestran una distribución equilibrada, mientras que otras como ‘credits_this_bank’ tienen una concentración más baja en los valores mayores.
## default account_check_status credit_history savings
## Min. :0.0 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:0.0 1st Qu.:1.000 1st Qu.:3.000 1st Qu.:3.000
## Median :0.5 Median :2.000 Median :3.000 Median :5.000
## Mean :0.5 Mean :2.309 Mean :3.361 Mean :3.986
## 3rd Qu.:1.0 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:5.000
## Max. :1.0 Max. :4.000 Max. :5.000 Max. :5.000
## present_emp_since installment_as_income_perc other_debtors property
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:1.000
## Median :3.000 Median :3.000 Median :1.000 Median :2.000
## Mean :2.593 Mean :2.941 Mean :1.111 Mean :2.319
## 3rd Qu.:3.000 3rd Qu.:4.000 3rd Qu.:1.000 3rd Qu.:3.000
## Max. :5.000 Max. :4.000 Max. :3.000 Max. :4.000
## other_installment_plans housing credits_this_bank job
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:2.000
## Median :3.000 Median :2.000 Median :1.000 Median :3.000
## Mean :2.601 Mean :1.864 Mean :1.334 Mean :2.831
## 3rd Qu.:3.000 3rd Qu.:2.000 3rd Qu.:2.000 3rd Qu.:3.000
## Max. :3.000 Max. :3.000 Max. :4.000 Max. :4.000
## telephone foreign_worker estado_civil rango_plazos_credito
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :1.000
## 1st Qu.:0.0000 1st Qu.:1.0000 1st Qu.:0.0000 1st Qu.:1.000
## Median :0.0000 Median :1.0000 Median :0.0000 Median :2.000
## Mean :0.3321 Mean :0.9671 Mean :0.4707 Mean :2.051
## 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:3.000
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :5.000
## rango_edad
## Min. :1.000
## 1st Qu.:1.000
## Median :2.000
## Mean :1.936
## 3rd Qu.:3.000
## Max. :5.000
Una evaluación exhaustiva muestra que no existen valores faltantes en ninguna de las variables del dataset, lo que representa una ventaja importante al no requerir imputaciones adicionales ni eliminación de registros incompletos.
## default account_check_status
## 0 0
## credit_history savings
## 0 0
## present_emp_since installment_as_income_perc
## 0 0
## other_debtors property
## 0 0
## other_installment_plans housing
## 0 0
## credits_this_bank job
## 0 0
## telephone foreign_worker
## 0 0
## estado_civil rango_plazos_credito
## 0 0
## rango_edad
## 0
Los valores atípicos fueron detectados a través del rango intercuartílico (IQR). Estas observaciones extremas pueden influir en las métricas y afectar el rendimiento de algunos modelos estadísticos. Su identificación temprana permite decidir si deben ser eliminados, transformados o mantenidos según el contexto del problema. A continuación, se listan los recuentos de valores atípicos por variable:
detect_outliers <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
sum(x < Q1 - 1.5 * IQR | x > Q3 + 1.5 * IQR, na.rm = TRUE)
}
sapply(df[, sapply(df, is.numeric)], detect_outliers)## default account_check_status
## 0 0
## credit_history savings
## 75 0
## present_emp_since installment_as_income_perc
## 64 0
## other_debtors property
## 104 0
## other_installment_plans housing
## 0 444
## credits_this_bank job
## 6 0
## telephone foreign_worker
## 0 46
## estado_civil rango_plazos_credito
## 0 0
## rango_edad
## 0
Las siguientes gráficas ilustran patrones y relaciones en los datos: Figura 1: El histograma de ‘rango_edad’ muestra una distribución moderadamente uniforme, indicando una representación equilibrada de clientes jóvenes y adultos. Esta diversidad etaria es útil para desarrollar modelos robustos.
# Histograma de rango_edad
ggplot(df, aes(x = rango_edad)) +
geom_histogram(binwidth = 1, fill = "skyblue", color = "black") +
ggtitle("Distribución de la variable rango_edad") +
xlab("Rango Edad") +
ylab("Frecuencia")Figura 2: El boxplot de ‘installment_as_income_perc’ revela que la mayoría de los clientes destinan entre un 25% y 75% de su ingreso a pagar el crédito, lo que refleja una política moderada de otorgamiento. No se observan valores extremos significativos.
# Boxplot de installment_as_income_perc
ggplot(df, aes(y = installment_as_income_perc)) +
geom_boxplot(fill = "lightgreen") +
ggtitle("Boxplot: installment_as_income_perc")Figura 3: La variable ‘housing’ indica la preferencia de los clientes en relación con la vivienda. La mayor parte vive en propiedad o alquiler, mientras que otras formas de vivienda son menos frecuentes.
# Gráfico de barras para housing
ggplot(df, aes(x = factor(housing))) +
geom_bar(fill = "lightcoral") +
ggtitle("Frecuencia de Housing") +
xlab("Tipo de Housing") +
ylab("Frecuencia")Figura 4: Distribución del estado civil de los clientes. Una proporción significativa corresponde a un único grupo, lo que puede correlacionar con decisiones de riesgo crediticio.
# Histograma de estado civil
ggplot(df, aes(x = factor(estado_civil))) +
geom_bar(fill = "orchid") +
ggtitle("Distribución del Estado Civil") +
xlab("Estado Civil (0 = Soltero, 1 = Casado)") +
ylab("Frecuencia")Figura 5: Dispersión entre la proporción de ingreso destinada a pagos y el plazo del crédito. Se observa que mayores cuotas tienden a asociarse a plazos más bajos, lo cual es lógico en términos financieros. Los colores reflejan el estado de incumplimiento (‘default’), mostrando una ligera tendencia a mayor riesgo con mayores cuotas.
# Diagrama de dispersión con color por default
ggplot(df, aes(x = installment_as_income_perc, y = rango_plazos_credito, color = factor(default))) +
geom_point(alpha = 0.7) +
ggtitle("Dispersión: Cuotas como % ingreso vs Plazo de crédito") +
xlab("installment_as_income_perc") +
ylab("rango_plazos_credito") +
scale_color_manual(values = c("0" = "blue", "1" = "red"))Figura 6: El mapa de calor de correlación permite identificar asociaciones lineales entre variables. Algunas relaciones destacan, como la existente entre ‘estado_civil’ y ‘housing’, lo cual puede ser relevante en etapas posteriores de modelado supervisado.
# Mapa de calor de correlación
numeric_vars <- df[, sapply(df, is.numeric)]
corr_matrix <- cor(numeric_vars, use = "complete.obs")
corrplot(corr_matrix, method = "color", col = brewer.pal(8, "RdBu"),
type = "upper", tl.col = "black", tl.srt = 45, addCoef.col = "black")En esta sección se describe la metodología empleada para el desarrollo, implementación y evaluación de los modelos predictivos.
Con la intención de trabajar mejor los datos, se procedió a codificar las variables categóricas. En consecuencia, a cada categoría de una variable cualitativa se le asignó un número entero único, como se muestra a continuación:
Asimismo, se normalizó la base de datos, ya que una variable con una escala mayor puede influir de manera desproporcionada en los resultados del análisis. Esta técnica permite que todas las variables estén centradas y tengan una escala comparable, lo que contribuye a una interpretación más equitativa entre ellas.
Se implementó la prueba KMO (Kaiser-Meyer-Olkin) para evaluar la
idoneidad del conjunto de datos antes de aplicar el Análisis de
Componentes Principales (ACP).
Esta prueba permite determinar si las correlaciones entre las variables son lo suficientemente altas como para justificar la reducción de la dimensionalidad mediante el ACP.
## Kaiser-Meyer-Olkin factor adequacy
## Call: psych::KMO(r = datos_norm)
## Overall MSA = 0.66
## MSA for each item =
## account_check_status credit_history
## 0.67 0.60
## savings present_emp_since
## 0.60 0.71
## installment_as_income_perc other_debtors
## 0.62 0.53
## property other_installment_plans
## 0.68 0.52
## housing credits_this_bank
## 0.70 0.61
## job telephone
## 0.65 0.66
## foreign_worker estado_civil
## 0.58 0.78
## rango_plazos_credito rango_edad
## 0.66 0.68
Inmediatamente, se puede observar que el valor general del índice KMO es de 0.66, lo cual indica una adecuación muestral regular. De acuerdo con los criterios establecidos por Kaiser (1974), este valor es aceptable, aunque no óptimo, lo que permite continuar con el Análisis de Componentes Principales (ACP), pero con precaución al interpretar los resultados.
No obstante, algunas variables presentan valores individuales de KMO bajos, por ejemplo, other_debtors, other_installment_plans y foreign_worker, lo que indica una baja correlación con el resto de las variables. En consecuencia, estas podrían considerarse para su eliminación o para un análisis por separado, a fin de mejorar la calidad del modelo.
Se realizó el Análisis de Componentes Principales (ACP) con el objetivo de reducir la dimensionalidad de los datos y construir un modelo más parsimonioso. El resultado obtenido muestra la desviación estándar explicada por cada componente principal.
De acuerdo con el criterio de Kaiser, se deben conservar únicamente aquellos componentes cuya desviación sea mayor a 1, ya que estos explican una proporción significativa de la variabilidad total del conjunto de datos.
## Call:
## princomp(x = datos_norm)
##
## Standard deviations:
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7 Comp.8
## 1.5653421 1.3031915 1.1536776 1.0754162 1.0505652 1.0057883 0.9970080 0.9495112
## Comp.9 Comp.10 Comp.11 Comp.12 Comp.13 Comp.14 Comp.15 Comp.16
## 0.9294547 0.9075760 0.8594696 0.8358020 0.7907762 0.7577617 0.7296079 0.6963413
##
## 16 variables and 1400 observations.
Como se puede observar, los primeros seis componentes cumplen con el
criterio de Kaiser, al presentar una desviación estándar superior a 1.
No obstante, esta evidencia no es suficiente para confirmar de manera
concluyente que se deba continuar con ese número de componentes.
Por ello, se consultó el resumen que muestra la proporción de varianza acumulada explicada por cada componente, como se ilustra en el siguiente recuadro.
## Importance of components:
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
## Standard deviation 1.565342 1.3031915 1.1536776 1.07541621 1.05056523
## Proportion of Variance 0.153253 0.1062201 0.0832452 0.07233417 0.06902976
## Cumulative Proportion 0.153253 0.2594731 0.3427183 0.41505246 0.48408223
## Comp.6 Comp.7 Comp.8 Comp.9 Comp.10
## Standard deviation 1.00578831 0.99700796 0.94951116 0.92945469 0.90757599
## Proportion of Variance 0.06327083 0.06217096 0.05638849 0.05403147 0.05151768
## Cumulative Proportion 0.54735305 0.60952401 0.66591251 0.71994398 0.77146166
## Comp.11 Comp.12 Comp.13 Comp.14 Comp.15
## Standard deviation 0.85946955 0.83580199 0.79077620 0.75776167 0.72960787
## Proportion of Variance 0.04620099 0.04369152 0.03911087 0.03591332 0.03329426
## Cumulative Proportion 0.81766266 0.86135418 0.90046505 0.93637837 0.96967263
## Comp.16
## Standard deviation 0.69634135
## Proportion of Variance 0.03032737
## Cumulative Proportion 1.00000000
De acuerdo con el diagnóstico anterior, las seis primeras componentes
principales retienen el 54.73 % de la varianza acumulada explicada. En
contraste, al considerar las primeras siete, se alcanza un 60.95 % de
varianza. Además, se observa que la desviación estándar del séptimo
componente es cercana a 1, lo que refuerza su relevancia.
De esta manera, para no perder mucha información se optó por conservar los primeros 7 eigenvalores.
Para ilustrar las afirmaciones anteriores, los siguientes gráficos facilitan la identificación del punto de corte adecuado para la selección de componentes, así como la la contribución de cada una al modelo. Por un lado, los eigenvalores permiten cuantificar la importancia de cada componente en la explicación de la varianza total. En términos simples, un eigenvalor alto señala que el componente correspondiente recoge una gran proporción de la información estructural de los datos.
una vez que el ACP ha transformado las variables originales en nuevas dimensiones (componentes), cada individuo obtiene una puntuación que indica qué tan lejos o cerca está de los demás en esa nueva dimensión reducida. Estas puntuaciones permiten comparar observaciones, agruparlas o detectar patrones que no eran visibles en el espacio original.
El gráfico presenta una representación bidimensional basada en los dos primeros componentes principales. El eje X (Factor 1) representa el primer componente principal, que explica la mayor proporción de varianza de los datos; el eje Y (Factor 2) corresponde al segundo componente principal, que explica la segunda mayor proporción. Ambos ejes suelen etiquetarse con el porcentaje de varianza explicada, por ejemplo: Dim1 (15.3 %).
Cada punto en el gráfico representa una observación (individuo, caso o muestra) del conjunto de datos. Los puntos ubicados cerca del centro (0,0) indican observaciones con baja contribución a ambos componentes, mientras que aquellos más alejados del centro reflejan observaciones influyentes o atípicas, que tienen mayor peso en la definición de los componentes.
En términos prácticos, valores altos de cos² (cercanos a 1) sugieren que la observación está bien representada en el plano factorial, mientras que valores bajos reflejan una representación deficiente.
En el análisis de componentes principales (ACP), las cargas factoriales constituyen un elemento central para la interpretación de los componentes extraídos. Estas cargas representan los coeficientes de correlación entre las variables originales y los componentes principales. Por lo que, permiten conocer qué tan fuertemente una variable contribuye a un componente determinado y, por tanto, facilitan la construcción de un significado o interpretación para cada uno de los componentes obtenidos.
En el biplot, los ángulos menores a 90° entre vectores indican que las variables están correlacionadas positivamente. Los vectores largos reflejan una alta contribución de la variable a los componentes principales. Además, los puntos (observaciones) que se proyectan en la dirección de un vector específico indican que dichos individuos presentan valores elevados en la variable correspondiente.
Es facil saber que los dos primeros componentes explican
aproximadamente el 25.9 % de la variabilidad total en los datos. Esta
proporción, si bien no es dominante, permite una visualización de las
relaciones entre las variables.
Las variables credit_history, credit_this_bank y account_check_status presentan vectores largos y orientados en direcciones similares, por lo que tienen una alta contribución. Estas variables están asociadas principalmente con el historial crediticio y la relación del solicitante con la institución bancaria.
Por otro lado, las variables como rango_edad, estado_civil, telefonone, housing, job, property y rango_plazos_credito, se encuentran alineadas en una misma dirección. Juntas explican una parte específica de la variabilidad, vinculada con el perfil de edad, estado civil, tipo de vivienda, empleo y duración del crédito.
Cuando las variables muestran una fuerte correlación entre sí, indica que comparten información común, permitiendo que puedan ser agrupadas o representadas mediante un número reducido de componentes principales. Dichas correlaciones facilitan que el ACP identifique combinaciones lineales que concentren gran parte de la varianza total del sistema, logrando así una simplificación efectiva y una mejor interpretación de la estructura de los datos originales.
En contraste, cuando las variables están débilmente correlacionadas o son esencialmente independientes, la eficacia del ACP disminuye considerablemente.
###Determinante El análisis de la matriz de correlaciones reveló un valor de determinante de 0.2206302. Este valor, considerablemente cercano a cero, refleja la existencia de fuertes correlaciones lineales entre las variables consideradas, lo que implica una elevada multicolinealidad. Por lo tanto, se evidencia que las variables comparten una cantidad significativa de información común.
La proximidad del determinante a cero indica que la matriz de correlaciones pueden ser expresadas como combinaciones lineales de otras. Esta condición favorece el uso de técnicas de reducción de dimensionalidad (ACP).
## [1] 0.2206302
Se usó la rotación factorial (Varimax) para facilitar la interpretación de estas cargas. Esta técnica busca redistribuir las cargas factoriales de manera que se maximicen las altas y se minimicen las bajas, promoviendo componentes con estructuras más claras y fáciles de interpretar.
varimax <- psych::principal(datos_norm, nfactors = 7 , residuals = FALSE, rotate = "varimax",
scores = TRUE, oblique.scores = FALSE, method = "regression",
use = "pairwise", cor = "cor", weight = NULL)
varimax## Principal Components Analysis
## Call: psych::principal(r = datos_norm, nfactors = 7, residuals = FALSE,
## rotate = "varimax", scores = TRUE, oblique.scores = FALSE,
## method = "regression", use = "pairwise", cor = "cor", weight = NULL)
## Standardized loadings (pattern matrix) based upon correlation matrix
## RC1 RC3 RC2 RC4 RC5 RC7 RC6 h2 u2
## account_check_status 0.06 0.11 0.35 -0.60 0.06 -0.05 0.16 0.53 0.47
## credit_history 0.11 0.02 0.80 -0.10 -0.03 0.04 0.15 0.69 0.31
## savings -0.08 -0.04 0.12 0.82 -0.07 -0.02 0.08 0.71 0.29
## present_emp_since -0.51 0.02 -0.06 0.24 0.09 -0.20 0.25 0.43 0.57
## installment_as_income_perc 0.14 0.01 -0.02 -0.01 -0.05 0.87 0.11 0.78 0.22
## other_debtors -0.03 0.05 0.02 0.15 -0.83 0.08 -0.12 0.73 0.27
## property 0.42 0.51 -0.18 0.16 0.31 -0.07 -0.02 0.59 0.41
## other_installment_plans -0.06 0.02 0.01 0.00 0.06 0.07 0.86 0.75 0.25
## housing 0.71 0.21 0.01 0.12 0.15 -0.09 0.11 0.61 0.39
## credits_this_bank 0.12 0.03 0.82 0.04 0.02 -0.02 -0.13 0.71 0.29
## job 0.04 0.77 0.04 -0.09 -0.08 0.07 0.11 0.63 0.37
## telephone 0.03 0.69 0.18 -0.21 -0.03 -0.04 0.03 0.55 0.45
## foreign_worker -0.12 0.14 0.09 0.07 0.53 0.49 -0.22 0.62 0.38
## estado_civil 0.61 0.12 0.13 -0.04 -0.16 0.15 0.02 0.46 0.54
## rango_plazos_credito 0.04 0.53 -0.14 0.19 0.13 0.08 -0.33 0.47 0.53
## rango_edad 0.67 -0.09 0.12 -0.12 0.04 -0.03 -0.08 0.50 0.50
## com
## account_check_status 1.9
## credit_history 1.2
## savings 1.1
## present_emp_since 2.4
## installment_as_income_perc 1.1
## other_debtors 1.1
## property 3.2
## other_installment_plans 1.0
## housing 1.4
## credits_this_bank 1.1
## job 1.1
## telephone 1.4
## foreign_worker 2.7
## estado_civil 1.5
## rango_plazos_credito 2.4
## rango_edad 1.2
##
## RC1 RC3 RC2 RC4 RC5 RC7 RC6
## SS loadings 1.85 1.71 1.58 1.27 1.15 1.09 1.09
## Proportion Var 0.12 0.11 0.10 0.08 0.07 0.07 0.07
## Cumulative Var 0.12 0.22 0.32 0.40 0.47 0.54 0.61
## Proportion Explained 0.19 0.18 0.16 0.13 0.12 0.11 0.11
## Cumulative Proportion 0.19 0.37 0.53 0.66 0.78 0.89 1.00
##
## Mean item complexity = 1.6
## Test of the hypothesis that 7 components are sufficient.
##
## The root mean square of the residuals (RMSR) is 0.09
## with the empirical chi square 2643.52 with prob < 0
##
## Fit based upon off diagonal values = 0.5
La prueba de hipótesis indica que siete factores son suficientes (p < 0), lo que respalda la aplicación del modelo factorial.
El análisis con rotación Varimax muestra que el modelo tiene una calidad aceptable, aunque puede mejorar. La prueba de suficiencia confirma que los factores son adecuados con un (p < 0.05), pero la prueba chi-cuadrada (2643.52) afirma diferencias entre los datos observados y los esperados, que es común en muestras grandes.
El índice RMSR fue de 0.09, dentro del límite aceptable (< 0.10), pero no ideal (< 0.05), lo que mantiene diferencias moderadas entre las correlaciones reales y las del modelo. El ajuste basado en correlaciones fuera de la diagonal fue de 0.5, mostrando una capacidad media para reflejar las relaciones entre variables, aunque se esperaría un valor más cercano a 1. La complejidad promedio de los ítems fue de 1.6, por lo que algunos ítems están influidos por más de un factor.
Adicionalmente, se calcularon los pesos de cada uno de los componentes principales. Tal como se detalló en el apartado del gráfico de cargas, las agrupaciones observadas permitieron identificar qué variables aportan mayor información a los nuevos componentes, lo que facilita su interpretación y comprensión dentro del modelo reducido.
## account_check_status credit_history
## -0.043153644 -0.016562305
## savings present_emp_since
## 0.006862865 -0.264696631
## installment_as_income_perc other_debtors
## 0.042575996 -0.016601984
## property other_installment_plans
## 0.209478554 0.009954507
## housing credits_this_bank
## 0.420240566 -0.019832820
## job telephone
## -0.084541090 -0.106356033
## foreign_worker estado_civil
## -0.149003926 0.333597419
## rango_plazos_credito rango_edad
## -0.049767371 0.395286637
## account_check_status credit_history
## 0.050436435 -0.006812205
## savings present_emp_since
## 0.003265992 0.088784221
## installment_as_income_perc other_debtors
## -0.038796096 0.108575407
## property other_installment_plans
## 0.243884089 0.024425991
## housing credits_this_bank
## 0.023858305 -0.005566310
## job telephone
## 0.487158664 0.430372559
## foreign_worker estado_civil
## 0.035480094 0.001476031
## rango_plazos_credito rango_edad
## 0.313922215 -0.158403613
## account_check_status credit_history
## 0.148530359 0.509310917
## savings present_emp_since
## 0.189454861 0.036002066
## installment_as_income_perc other_debtors
## -0.054778736 0.000708822
## property other_installment_plans
## -0.127340624 -0.038151590
## housing credits_this_bank
## -0.050979315 0.562412840
## job telephone
## -0.008467389 0.085658152
## foreign_worker estado_civil
## 0.113455918 0.009424489
## rango_plazos_credito rango_edad
## -0.051430905 0.004286030
## account_check_status credit_history
## -0.434161496 0.038362554
## savings present_emp_since
## 0.693483684 0.179371344
## installment_as_income_perc other_debtors
## -0.002309524 0.086487435
## property other_installment_plans
## 0.159143321 0.047643503
## housing credits_this_bank
## 0.162879414 0.137883688
## job telephone
## -0.052411315 -0.141721982
## foreign_worker estado_civil
## 0.061196764 0.022528372
## rango_plazos_credito rango_edad
## 0.133471107 -0.041846031
## account_check_status credit_history
## 0.039576218 0.003746581
## savings present_emp_since
## -0.024222832 0.102215169
## installment_as_income_perc other_debtors
## -0.098034280 -0.736545327
## property other_installment_plans
## 0.217661896 0.041184871
## housing credits_this_bank
## 0.107891259 0.057009369
## job telephone
## -0.154047858 -0.087374018
## foreign_worker estado_civil
## 0.444856228 -0.164644752
## rango_plazos_credito rango_edad
## 0.059207498 0.039759227
## account_check_status credit_history
## -0.05694965 0.02454510
## savings present_emp_since
## -0.02053151 -0.15199250
## installment_as_income_perc other_debtors
## 0.80393447 0.11240654
## property other_installment_plans
## -0.12412133 0.08751731
## housing credits_this_bank
## -0.13428956 -0.05014173
## job telephone
## 0.04441731 -0.06324110
## foreign_worker estado_civil
## 0.41976009 0.10930063
## rango_plazos_credito rango_edad
## 0.03888899 -0.06482996
## account_check_status credit_history
## 0.09221756 0.09474494
## savings present_emp_since
## 0.10642489 0.21099607
## installment_as_income_perc other_debtors
## 0.13594653 -0.10108848
## property other_installment_plans
## 0.03545273 0.80457779
## housing credits_this_bank
## 0.15733368 -0.16899234
## job telephone
## 0.10636310 0.01403412
## foreign_worker estado_civil
## -0.20649330 0.05729896
## rango_plazos_credito rango_edad
## -0.27666652 -0.04766594
Los valores de carga cercanos a 1 o -1 indican una fuerte relación entre la variable y el componente principal. Cuando los pesos son negativos, reflejan una relación inversa con el factor; por el contrario, valores cercanos a cero indican que la variable no contribuye de manera significativa a ese componente.
Para continuar con este estudio, se agregaron los scores obtenidos tras aplicar la rotación Varimax para contruir la nueva base de los modelos propuestos.
Dado que durante el proceso de normalización se eliminó la columna default, la cual indica si un cliente tiene un buen perfil (0: Good customer, 1: Bad customer), esta fue reincorporada a la base de datos “scores” para poder utilizarla en los análisis posteriores.
De este modo, los componentes principales se declararon como nuevas variables en la base de datos, asignándoles los nombres “RC1”, “RC3”, “RC2”, “RC4”, “RC5”, “RC7” y “RC6”, según el orden en que fueron seleccionados para el análisis.
Varios autores mencionan que se trata de un modelo estadístico utilizado para predecir la probabilidad o clasificar un evento binario en función de una o más variables independientes. Este tipo de regresión pertenece a los Modelos Lineales Generalizados (MLG) y tiene como finalidad modelar la relación entre una o más variables independientes (categóricas o continuas) y una variable dependiente dicotómica.
Para ello, se utilizó la función glm, especificando la familia binomial, ya que la variable default actuó como variable dicotomica. Los resultados obtenidos a partir de este modelo se presentan a continuación.
modelo_logit1 <- glm( default ~ RC1 + RC2 + RC3 + RC4 + RC5 + RC6 +RC7,
data = scores, family = binomial)
modelo_logit1##
## Call: glm(formula = default ~ RC1 + RC2 + RC3 + RC4 + RC5 + RC6 + RC7,
## family = binomial, data = scores)
##
## Coefficients:
## (Intercept) RC1 RC2 RC3 RC4 RC5
## -0.0548 -0.4183 -0.8222 -0.1247 0.9536 0.4594
## RC6 RC7
## -0.7136 0.1672
##
## Degrees of Freedom: 1399 Total (i.e. Null); 1392 Residual
## Null Deviance: 1941
## Residual Deviance: 1431 AIC: 1447
##
## Call:
## glm(formula = default ~ RC1 + RC2 + RC3 + RC4 + RC5 + RC6 + RC7,
## family = binomial, data = scores)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.05480 0.06533 -0.839 0.4016
## RC1 -0.41826 0.06607 -6.331 2.44e-10 ***
## RC2 -0.82222 0.07126 -11.538 < 2e-16 ***
## RC3 -0.12466 0.06465 -1.928 0.0538 .
## RC4 0.95363 0.07436 12.825 < 2e-16 ***
## RC5 0.45938 0.07334 6.264 3.76e-10 ***
## RC6 -0.71362 0.07057 -10.112 < 2e-16 ***
## RC7 0.16720 0.06991 2.391 0.0168 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1940.8 on 1399 degrees of freedom
## Residual deviance: 1431.0 on 1392 degrees of freedom
## AIC: 1447
##
## Number of Fisher Scoring iterations: 5
modelo_nulo <- glm(default ~ 1, data = scores, family = binomial)
prueba_lrt <- anova(modelo_nulo, modelo_logit1, test = "Chisq")
prueba_lrtEl modelo de regresión logística reveló que los componentes RC1, RC2 y RC6 tienen un efecto significativo, con coeficientes negativos entre -0.418 y -0.822 (todos con p < 0.001), destacando RC2 como el componente con mayor influencia. En cambio, los componentes RC4 y RC5 se asocian con un mayor riesgo de default, mostrando coeficientes positivos de 0.954 y 0.459 respectivamente (p < 0.001), siendo RC4 el principal factor de riesgo identificado. El componente RC7 también incrementa el riesgo, aunque de forma más moderada (coeficiente = 0.167, p = 0.017). Por su parte, RC3 es el único que no presenta significancia estadística pero se mantiene cerca de un ( p=0.05).
Posteriormente, se calculó el pseudo R² de McFadden, cuyo valor se ubicó entre 0.2 y 0.4. Este rango indica un buen nivel de ajuste del modelo, lo que refuerza la validez de los resultados obtenidos a partir de la regresión logística.
logLik_nulo <- logLik(modelo_nulo)
logLik_modelo <- logLik(modelo_logit1)
pseudo_r2_mcfadden <- 1-(logLik_modelo / logLik_nulo)
pseudo_r2_mcfadden## 'log Lik.' 0.2626837 (df=8)
El área bajo la curva (AUC) fue de 0.8281, lo que indica que el modelo presenta un buen poder predictivo y una adecuada capacidad de clasificación entre clientes buenos y malos. Este valor hace referencia a que el modelo discrimina correctamente en aproximadamente el 83 % de los casos.
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
##
## Call:
## roc.default(response = scores$default, predictor = prob_pred)
##
## Data: prob_pred in 700 controls (scores$default 0) < 700 cases (scores$default 1).
## Area under the curve: 0.8281
Para una mejor comprensión, véase el siguiente gráfico.
Finalmente la tabla de confusión separa las clasifiaciones según la especificidad y sensibilidad a los datos de entrenamiento
pred_clase <- ifelse(prob_pred > 0.5, 1, 0)
tabla_confusion <- table(Real = scores$default, prediccion = pred_clase)
tabla_confusion## prediccion
## Real 0 1
## 0 506 194
## 1 154 546
La tabla de confusión identifica correctamente el 82% de los casos positivos (sensibilidad) y el 87% de los negativos (especificidad). Sin embargo, comete algunos errores: clasifica erróneamente como positivos el 13% de casos que en realidad son negativos (falsos positivos), y no detecta el 18% de verdaderos positivos (falsos negativos). El equilibrio entre sensibilidad y especificidad arroja que el modelo funciona razonablemente bien, aunque podría optimizarse dependiendo del contexto.
En este trabajo se tomó la base de datos una vez realizado el análisis de componentes principales, formado por 1 400 clientes y siete indicadores numéricos de comportamiento crediticio (RC1–RC7), para construir un modelo que anticipe el impago reflejado en la variable binaria “default”. Primero se depuró la hoja eliminando una columna-índice que no sumaba al modelo y se transformó “default” en factor, paso importante para abordar el problema como clasificación y no como regresión. A continuación los datos se dividieron, de manera estratificada, en un 70 % de entrenamiento y un 30 % de prueba; esto garantiza que el balance 50-50 entre morosos y no morosos esté representado en ambos subconjuntos.
df$default <- factor(df$default,
levels = c(0, 1),
labels = c("No", "Yes"))
# División entrenamiento / prueba (70-30)
idx <- createDataPartition(df$default, p = 0.70, list = FALSE)
train <- df[idx, ]
test <- df[-idx, ]El algoritmo elegido fue un Random Forest, es decir, un ensamble de 500 árboles CART (Classification And Regression Trees).
Cada árbol se entrena sobre una muestra bootstrap (aproximadamente el 63 % de los registros originales seleccionados con reemplazo) y, en cada nodo, examina solo √7 ≈ 2 variables tomadas al azar; esta doble aleatorización (filas y variables) reduce la correlación entre árboles y, con ella, el riesgo de sobre-ajuste. Los árboles son de tipo clasificación (no regresión) y emplean el índice de Gini como criterio de pureza: las particiones sucesivas buscan la mayor caída de impureza posible.
Al no imponer un límite de profundidad, los árboles crecen hasta que un nodo es puro o queda una sola observación, alcanzando en la práctica entre seis y un conjunto de veinte niveles; el bosque compensa la alta varianza inherente a estos árboles profundos mediante el promedio de sus votaciones. Entre tanto, las observaciones que no entran en la muestra bootstrap de un árbol funcionan como casos out-of-bag y proporcionan una estimación interna del error sin tocar el conjunto de prueba.
mtry ≈ √p para clasificación; aquí p = 7 predictores
rf_model <- randomForest(default ~ .,
data = train,
ntree = 500, # nº de árboles
mtry = floor(sqrt(ncol(train) - 1)),
importance = TRUE)
rf_model # Error OOB estimado##
## Call:
## randomForest(formula = default ~ ., data = train, ntree = 500, mtry = floor(sqrt(ncol(train) - 1)), importance = TRUE)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 4
##
## OOB estimate of error rate: 19.49%
## Confusion matrix:
## No Yes class.error
## No 388 102 0.2081633
## Yes 89 401 0.1816327
Probabilidades y clases
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 165 27
## Yes 45 183
##
## Accuracy : 0.8286
## 95% CI : (0.7891, 0.8634)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 2e-16
##
## Kappa : 0.6571
##
## Mcnemar's Test P-Value : 0.04513
##
## Sensitivity : 0.8714
## Specificity : 0.7857
## Pos Pred Value : 0.8026
## Neg Pred Value : 0.8594
## Prevalence : 0.5000
## Detection Rate : 0.4357
## Detection Prevalence : 0.5429
## Balanced Accuracy : 0.8286
##
## 'Positive' Class : Yes
##
Al evaluar el modelo sobre las 420 observaciones restantes, se obtuvo una exactitud global del 76,9 % y, lo más revelador, una AUC (o curva ROC) de 0.895: el modelo discrimina satisfactoriamente entre clientes morosos y solventes. En términos de la matriz de confusión, capturó la mayoría de los impagos (sensibilidad) y se equivocó con una minoría de sobresaltos falsos, un equilibrio razonable cuando la prioridad es no dejar morosos sin señalar. El análisis de importancia de variables (medido como disminución media de Gini) mostró que RC4, RC2 y RC7 concentran más de la mitad del poder explicativo del bosque, sugiriendo que esos indicadores resumen la mayor parte del riesgo crediticio latente.
## Setting direction: controls < cases
## Area under the curve: 0.8948
El análisis exploratorio ha sido clave para identificar la estructura y comportamiento del dataset. Se confirmó la ausencia de datos faltantes, y se identificaron valores atípicos relevantes que podrían representar perfiles de riesgo o comportamientos no comunes. Las visualizaciones complementan las estadísticas al evidenciar patrones complejos como correlaciones cruzadas, agrupamientos implícitos y sesgos de clase. Toda esta información es fundamental para preparar el terreno hacia técnicas de modelado más avanzadas como PCA, regresión logística o árboles de decisión.
En síntesis, el proceso conformó un modelo competente: un bosque de 500 árboles CART profundos, alimentados por bootstrapping y limitados a dos características por nodo, capaz de identificar cuatro de cada cinco impagos potenciales y de ofrecer un criterio numérico (probabilidad) con gran capacidad discriminante. Las próximas mejoras podrían pasar por ajustar el umbral de decisión al costo real de falsos positivos y falsos negativos, afinar hiperparámetros como mtry o min_samples_leaf, e incorporar explicaciones locales (SHAP) que traduzcan la lógica del bosque a reglas comprensibles para analistas y reguladores.
Del mismo modo, el modelo de regresión logística desarrollado demostró un buen desempeño predictivo, con un valor de AUC-ROC de 0.83, lo que indica una sólida capacidad para discriminar entre casos de default y no default. Los coeficientes estimados señalan que el componente RC4 (β = 0.95, p < 0.001) representa el principal factor de riesgo, mientras que RC2 (β = -0.82, p < 0.001) y RC6 (β = -0.71, p < 0.001) actúan como factores protectores frente al incumplimiento. Aunque RC3 presentó un efecto marginalmente significativo (p = 0.054), su contribución al modelo fue limitada.
La reducción sustancial en la devianza, de 1940.8 a 1431.0, confirma que el modelo logra explicar una proporción importante de la variabilidad en los datos. Este ajuste se ve respaldado por un valor de AIC de 1447, lo que sugiere un equilibrio adecuado entre capacidad explicativa y simplicidad del modelo. No obstante, la presencia de devianza residual indica que aún existe variabilidad no explicada, posiblemente atribuible a factores no considerados en el modelo actual.
Castaño, H. F., & Ramírez, F. O. P. (2005). El modelo logístico: una herramienta estadística para evaluar el riesgo de crédito. Revista Ingenierías Universidad de Medellín, 4(6), 55-75. https://www.redalyc.org/pdf/750/75040605.pdf
Pardo Carrillo, O. S. (2020). Perfil de riesgo de crédito para una coopertiva en Villavicencio a partir de un modelo logit. Revista Universidad y Empresa, 22(38), 237-256. http://www.scielo.org.co/scielo.php?pid=S0124-46392020000100237&script=sci_arttext