La concesión de créditos es uno de los principales negocios de las instituciones bancarias, que a su vez puede ocasionar la quiebra de las mismas. Tal es el caso de numerosos bancos europeos que, en la actualidad, está pasando por una delicada situación debido a la creciente tasa de morosidad, obligando así a dichas entidades a incrementar la provisión por insolvencia, y eliminado cualquier posibilidad de beneficio e incluso llegando a tener que soportar importantes pérdidas.
Cada vez más se reclaman sistemas automáticos de concesión de créditos que aseguren con alta probabilidad que el cliente será capaz de hacer frente a sus obligaciones crediticias. Las entidades precisan incorporar calidad a sus créditos, utilizando para ello distintos modelos que faciliten y mejoren el proceso de aprobación de los mismos.
Se denomina credit scoring a todo sistema de evaluación crediticia que permite valorar de forma automática el riesgo asociado a cada solicitud de crédito. Riesgo que estará en función de la solvencia del deudor, del tipo de crédito, de los plazos, y de otras características propias del cliente y de la operación, que van a definir cada observación, es decir, cada solicitud de crédito.
Así, el riesgo de crédito de una entidad bancaria estará cada vez más en la obligación de disponer de un modelo que permita decidir si conceder o no un crédito a un individuo. Para este proceso se tomó encuenta dos medidas para la cuantificación del riesgo de crédito: el capital económico (CE) y la pérdida esperada (PE), dónde además se atribuirá los parámetros de riesgo (PD, LGD, EAD) a cada uno de los grupos homogéneos que se crearon con anterioridad. En este proyecto y dentro de la probabilidad de inclumplimiento PD existe la clasificación de riesgo, point in time (PIT) y Through the cycle (TIC) dónde dado nuestro modelo logístico se utilizará una filosofía PIT.
El principal problema que se busca afrontar con este modelo es reducir la tasa de morosidad de los clientes para evitar que una entidad financiera deba incrementar la provisión por insolvencia, o eliminar cualquier posibilidad de beneficio e incluso llegar a tener que soportar importantes pérdidas.
Los modelos de credit scoring, como hemos indicado, tratan de obtener, a partir la relación existente entre diversas variables que definen tanto al solicitante como a la operación, una regla general que permita determinar, con rapidez y fiabilidad, la probabilidad de fallido de una determinada solicitud. Por tanto, resulta imprescindible estudiar las relaciones existentes entre la información recogida de cada una de los créditos concedidos en el pasado y los impagos observados.
Realizado este análisis, y utilizando en este caso un modelo de regresión logítica (Modelo Logit) en función de las características del cliente, se podrá determinar la probabilidad de que éste pueda o no afrontar sus obligaciones de pago
Se implentará en el software R modelos de regresión logistica, para poder predecir el otorgamiento o no de un crédito a los solicitantes.
En cuanto a la exploración de los datos se usará el software R para la implementación y visualización.
La Base a trabajar es bank-additional-full, que consiste en datos de clientes que han recibido un crédito y contiene 21 variables y 41188 observaciones. A continuación se presentan las variables de dicha base.
| Nombre | Descripción | Tipo | |
|---|---|---|---|
| 1 | age | Edad del Cliente | Numérico |
| 2 | job | Ocupación del cliente | Categórica |
| 3 | marital | Estado Civil | Categórica |
| 4 | education | Nivel de educación del cliente | Categórica |
| 5 | default | Indica si el cliente tiene un crédito en mora | Categórica |
| 6 | housing | Indica si el cliente tiene un crédito hipotecario | Categórica |
| 7 | loan | Indica si el cliente tiene préstamos personales | Categórica |
| 8 | contact | Tipo de comunicación que se tiene con el cliente | Categórica |
| 9 | month | Mes en el que se hizo el último contacto | Categórica |
| 10 | day_of_week | Día de la semana en el que se hizo el ultimo contacto | Categórica |
| 11 | duration | Duración del último contacto en segundos | Numérico |
| 12 | campaign | Número de contactos realizados durante la campaña para este cliente | Numerico |
| 13 | pdays | Número de días desde la última vez que se contactó con el cliente. | Numérico |
| 14 | previous | Número de contactos realizados antes de la campaña actual | Numérico |
| 15 | poutcome | Resultado de la campaña de marketing anterior | Categórica |
| 16 | empvarrate | Tasa de variación del empleo- Indicador de cuartiles | Numérico |
| 17 | conspriceidx | Índice de precios al consumidor- Indicador mensual | Numérico |
| 18 | consconfidx | Índice de confianza del consumidor- Indicador mensual | Numérico |
| 19 | euribor3m | Tasa de interés de bancos europeos - Indicador diario | Numérico |
| 20 | nremployed | Número de empleados- Indicador cuariles | Numérico |
El conjunto de datos consta de 41.118 solicitudes con 21 atributos, que describen las características de los solicitantes de crédito. La base se compone de variables numéricas y categóricas.
En esta sección se depurará la base permitiendonos identificar datos incompletos, incorrectos, inexactos, no pertinentes,etc. De tal manera que podamos substituir, modificar o eliminar estos datos con el fin de obtener una base de datos de calidad y tomar decisiones estratégicas correctas.
Como se observa en la gráfica, la base de datos proporcionada tiene un 100% de los datos, por lo cual no es necesario eliminar datos.
Ahora procederemos a ver que el tipo de variables este de acuerdo con las información proporcianada:
tibble [41,188 x 21] (S3: tbl_df/tbl/data.frame)
$ age : num [1:41188] 56 57 37 40 56 45 59 41 24 25 ...
$ job : chr [1:41188] "housemaid" "services" "services" "admin." ...
$ marital : chr [1:41188] "married" "married" "married" "married" ...
$ education : chr [1:41188] "basic.4y" "high.school" "high.school" "basic.6y" ...
$ default : chr [1:41188] "no" "unknown" "no" "no" ...
$ housing : chr [1:41188] "no" "no" "yes" "no" ...
$ loan : chr [1:41188] "no" "no" "no" "no" ...
$ contact : chr [1:41188] "telephone" "telephone" "telephone" "telephone" ...
$ month : chr [1:41188] "may" "may" "may" "may" ...
$ day_of_week : chr [1:41188] "mon" "mon" "mon" "mon" ...
$ duration : num [1:41188] 261 149 226 151 307 198 139 217 380 50 ...
$ campaign : num [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ pdays : num [1:41188] 999 999 999 999 999 999 999 999 999 999 ...
$ previous : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ poutcome : chr [1:41188] "nonexistent" "nonexistent" "nonexistent" "nonexistent" ...
$ emp.var.rate : chr [1:41188] "1.1" "1.1" "1.1" "1.1" ...
$ cons.price.idx: num [1:41188] 93994 93994 93994 93994 93994 ...
$ cons.conf.idx : chr [1:41188] "-36.4" "-36.4" "-36.4" "-36.4" ...
$ euribor3m : num [1:41188] 4857 4857 4857 4857 4857 ...
$ nr.employed : num [1:41188] 5191 5191 5191 5191 5191 ...
$ y : chr [1:41188] "no" "no" "no" "no" ...
Como podemos ver las variables emp.var.rate y cons.conf.idx son numericas pero estan guardadas como caracter, por lo cual debemos cambiar el tipo de dichas variables:
tibble [41,188 x 21] (S3: tbl_df/tbl/data.frame)
$ age : num [1:41188] 56 57 37 40 56 45 59 41 24 25 ...
$ job : chr [1:41188] "housemaid" "services" "services" "admin." ...
$ marital : chr [1:41188] "married" "married" "married" "married" ...
$ education : chr [1:41188] "basic.4y" "high.school" "high.school" "basic.6y" ...
$ default : chr [1:41188] "no" "unknown" "no" "no" ...
$ housing : chr [1:41188] "no" "no" "yes" "no" ...
$ loan : chr [1:41188] "no" "no" "no" "no" ...
$ contact : chr [1:41188] "telephone" "telephone" "telephone" "telephone" ...
$ month : chr [1:41188] "may" "may" "may" "may" ...
$ day_of_week : chr [1:41188] "mon" "mon" "mon" "mon" ...
$ duration : num [1:41188] 261 149 226 151 307 198 139 217 380 50 ...
$ campaign : num [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ pdays : num [1:41188] 999 999 999 999 999 999 999 999 999 999 ...
$ previous : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ poutcome : chr [1:41188] "nonexistent" "nonexistent" "nonexistent" "nonexistent" ...
$ cons.price.idx: num [1:41188] 93994 93994 93994 93994 93994 ...
$ euribor3m : num [1:41188] 4857 4857 4857 4857 4857 ...
$ nr.employed : num [1:41188] 5191 5191 5191 5191 5191 ...
$ y : chr [1:41188] "no" "no" "no" "no" ...
$ emp.var.rate : num [1:41188] 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 ...
$ cons.conf.idx : num [1:41188] -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 ...
Con lo cual ahora las variables son del tipo correcto.
Ahora bien, notemos que para poder realizar el modelo logit es necesario transformar la variable “y” a una variabe dicotómica, lo cual se realiza a continuación y para una mejor visualización se colocan las variables numéricas a la izquierda y las categóricas a la derecha.
tibble [41,188 x 21] (S3: tbl_df/tbl/data.frame)
$ y : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ age : num [1:41188] 56 57 37 40 56 45 59 41 24 25 ...
$ duration : num [1:41188] 261 149 226 151 307 198 139 217 380 50 ...
$ campaign : num [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ pdays : num [1:41188] 999 999 999 999 999 999 999 999 999 999 ...
$ previous : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ cons.price.idx: num [1:41188] 93994 93994 93994 93994 93994 ...
$ euribor3m : num [1:41188] 4857 4857 4857 4857 4857 ...
$ nr.employed : num [1:41188] 5191 5191 5191 5191 5191 ...
$ emp.var.rate : num [1:41188] 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 ...
$ cons.conf.idx : num [1:41188] -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 -36.4 ...
$ job : chr [1:41188] "housemaid" "services" "services" "admin." ...
$ marital : chr [1:41188] "married" "married" "married" "married" ...
$ education : chr [1:41188] "basic.4y" "high.school" "high.school" "basic.6y" ...
$ default : chr [1:41188] "no" "unknown" "no" "no" ...
$ housing : chr [1:41188] "no" "no" "yes" "no" ...
$ loan : chr [1:41188] "no" "no" "no" "no" ...
$ contact : chr [1:41188] "telephone" "telephone" "telephone" "telephone" ...
$ month : chr [1:41188] "may" "may" "may" "may" ...
$ day_of_week : chr [1:41188] "mon" "mon" "mon" "mon" ...
$ poutcome : chr [1:41188] "nonexistent" "nonexistent" "nonexistent" "nonexistent" ...
Las variables (cons.conf.idx,euribor3m y cons.price.idx)son indicadoras con un valor numérico bastante grande, lo que puede dificultar la implementación de técnicas para nuestro modelo.
# A tibble: 6 x 21
y age duration campaign pdays previous cons.price.idx[~ euribor3m[,1]
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 0 56 261 1 999 0 0.325 0.804
2 0 57 149 1 999 0 0.325 0.804
3 0 37 226 1 999 0 0.325 0.804
4 0 40 151 1 999 0 0.325 0.804
5 0 56 307 1 999 0 0.325 0.804
6 0 45 198 1 999 0 0.325 0.804
# ... with 13 more variables: nr.employed <dbl>, emp.var.rate <dbl>,
# cons.conf.idx[,1] <dbl>, job <chr>, marital <chr>, education <chr>,
# default <chr>, housing <chr>, loan <chr>, contact <chr>, month <chr>,
# day_of_week <chr>, poutcome <chr>
En esta sección identificamos las observaciones que numéricamente son distintas al resto de datos, es decir, identificamos valores atípicos porque podrían tener un efecto desproporcionado en los resultados estadísticos.
Existen varios métodos para detectar valores atípicos y remplazar los valores atípicos pero utilizaremos diagramas de cajas para un mejor entendimiento.
De los diagramas de caja anteriores podemos notar unicamente para la variable “age” y “cons.conf.idx” presenta varios valores atípicos.
Ahora, los datos atípicos de las variables anteriores son remplazados obeniendo los siguientes diagramas de caja
Min. 1st Qu. Median Mean 3rd Qu. Max.
17.00 32.00 38.00 40.02 47.00 98.00
V1
Min. :-2.2249
1st Qu.:-0.4748
Median :-0.2803
Mean : 0.0000
3rd Qu.: 0.8864
Max. : 2.9391
Nuestra base de datos tendrá datos cualitativos y cuantitativos, a continuación presentaremos la estadística descriptiva de esos datos.
Realizaremos una rápida exploración de la variable objetivo y
Como podemos notar es mayor la cantidad de observaciones es de NO conceder un crédito notablemente superior a a la cantidad de observaciones de SI conceder un crédito. Ahora, vamos a encontrar las posibles relaciones que existen entre la variable y y otras varibles de la base.
Ahora, crearemos una variable categórica para manejar de mejor manera la variable age de los clientes tomando como base para la transformación los percentiles de la variable numérica, esta transformación conduce a una inevitable perdida de información sin embargo en este trabajo nos es útil pues queremos realizar cruces de esta variable con la variable y, además de que también queremos utilizarla para un análisis de clasificación.
Min. 1st Qu. Median Mean 3rd Qu. Max.
26.00 33.00 39.00 39.62 45.00 58.00
Joven Adulto Senior Veteranos
9510 9999 13462 8217
Como podemos notar en todas las categorías se evidencia que la cantidad de observaciones de NO conceder un crédito es similar. Pero además se puede observar que en las pocas observaciones de SI conceder un crédito a las personas de la categoría Joven es más alta a comparación de las demás.
Continuaremos con la variable housing que indica si el cliente tiene un préstamo de vivienda.para la cual haremos un gráfico de barras para notar su distribución. Es notable que en la categoría de NO conceder un crédito la mayoría si cuenta con un préstamo de vivienda, por lo que podría ser un factor para NO conceder un crédito.Del mismo modo, en la categoría de NO conceder un crédito la relación de no contar con un préstamo de vivienda es similar a la de si tener un préstamo, por lo cual, se debe estudiar otros factores por los que se puede NO conceder un crédito.
Del mismo modo se realiza un análisis para la variable job Como podemos observar en los gráficos los clientes que ha solicitado un crédito en su mayoría pertenecen a un puesto laboral Administrativo, seguido de blue collar y clientes que prestan servicios, tanto para los que se les otorga un crédito como a los que no.
Se sigue con la variable marital que indica el estado civil. Respecto a esta variable idiosincrática, el estar casado predomina en las dos asignaciones de crédito.
Por último se analiza la variable education así podemos observar el nivel de educación de los clientes a los que se les niega un crédito y a los de los que se les concede un crédito.
En su mayoría en las dos categorías cuentan con un grado universitario, seguido de la categoría High school, en nuestro caso bachillerato.
Para empezar con nuestro modelo, en primer lugar notemos que hay variables como job y education las cuales tienen una cardinalidad muy alta, por lo que debemos proceder con la realización de clusters para reducir dicha cardinalidad.
Ahora bien, el criterio que usaremos para realizarlos será el porcentaje de créditos que no han sido aprobados para cada trabajo o cada nivel educativo, como sigue:
Para el caso de job se dividira en 5 clusters:
A partir del porcentaje más alto (\(0.22\)) se realizaran los 4 clusters, cada uno con \(6\%\) de diferencia de otro, es decir, los clusters serán:
Antes del cluster:
Suma Porcentaje b gr
1 9070 0.22 admin. gr1
2 8616 0.21 blue-collar gr1
3 1332 0.03 entrepreneur gr4
4 954 0.02 housemaid gr4
5 2596 0.06 management gr3
6 1286 0.03 retired gr4
7 1272 0.03 self-employed gr4
8 3646 0.09 services gr3
9 600 0.01 student gr4
10 6013 0.15 technician gr2
11 870 0.02 unemployed gr4
12 293 0.01 unknown gr4
Así, los grupos tendrían por elementos:
Después del cluster:
Para el caso de education se dividira en 3 clusters:
A partir del porcentaje más alto (\(0.25\)) se realizaran los 3 clusters, cada uno con \(8\%\) de diferencia de otro, y un cluster adicional para la variable unknown; es decir los clusters serán:
Antes del cluster:
Suma Porcentaje b1 gr
1 3748 0.09 basic.4y media
2 2104 0.05 basic.6y basica
3 5572 0.14 basic.9y media
4 8484 0.21 high.school superior
5 14 0.00 illiterate basica
6 4648 0.11 professional.course media
7 10498 0.25 university.degree superior
8 1480 0.04 unknown basica
Así, los grupos tendrían por elementos:
Después del cluster:
Con los clusters formados prodecemos a reemplazar los valores en nuestra base entrenamiento y además retirar la variable default.
Es necesario utilizar variables categóricas en método que vamos a utilizar, por lo que que será necesario crear variables indicadoras. Con la técnica de Variables Dummies realizamos el siguiente proceso:
tibble [41,188 x 55] (S3: tbl_df/tbl/data.frame)
$ y : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ age : num [1:41188] 56 57 37 40 56 ...
$ duration : num [1:41188] 261 149 226 151 307 198 139 217 380 50 ...
$ campaign : num [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ pdays : num [1:41188] 999 999 999 999 999 999 999 999 999 999 ...
$ previous : num [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ cons.price.idx : num [1:41188] 0.325 0.325 0.325 0.325 0.325 ...
$ euribor3m : num [1:41188] 0.804 0.804 0.804 0.804 0.804 ...
$ nr.employed : num [1:41188] 5191 5191 5191 5191 5191 ...
$ emp.var.rate : num [1:41188] 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 ...
$ cons.conf.idx : num [1:41188] 0.886 0.886 0.886 0.886 0.886 ...
$ job : chr [1:41188] "gr4" "gr3" "gr3" "gr1" ...
$ marital : chr [1:41188] "married" "married" "married" "married" ...
$ education : chr [1:41188] "media" "superior" "superior" "basica" ...
$ housing : chr [1:41188] "no" "no" "yes" "no" ...
$ loan : chr [1:41188] "no" "no" "no" "no" ...
$ contact : chr [1:41188] "telephone" "telephone" "telephone" "telephone" ...
$ month : chr [1:41188] "may" "may" "may" "may" ...
$ day_of_week : chr [1:41188] "mon" "mon" "mon" "mon" ...
$ poutcome : chr [1:41188] "nonexistent" "nonexistent" "nonexistent" "nonexistent" ...
$ age_cat : Factor w/ 4 levels "Joven","Adulto",..: 4 4 2 3 4 3 3 3 3 3 ...
$ job_gr1 : int [1:41188] 0 0 0 1 0 0 1 1 0 0 ...
$ job_gr2 : int [1:41188] 0 0 0 0 0 0 0 0 1 0 ...
$ job_gr3 : int [1:41188] 0 1 1 0 1 1 0 0 0 1 ...
$ job_gr4 : int [1:41188] 1 0 0 0 0 0 0 0 0 0 ...
$ education_basica : int [1:41188] 0 0 0 1 0 0 0 1 0 0 ...
$ education_media : int [1:41188] 1 0 0 0 0 1 1 0 1 0 ...
$ education_superior: int [1:41188] 0 1 1 0 1 0 0 0 0 1 ...
$ marital_divorced : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ marital_married : int [1:41188] 1 1 1 1 1 1 1 1 0 0 ...
$ marital_single : int [1:41188] 0 0 0 0 0 0 0 0 1 1 ...
$ marital_unknown : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ day_of_week_fri : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ day_of_week_mon : int [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ day_of_week_thu : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ day_of_week_tue : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ day_of_week_wed : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_apr : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_aug : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_dec : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_jul : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_jun : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_mar : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_may : int [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ month_nov : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_oct : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ month_sep : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ contact_cellular : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ contact_telephone : int [1:41188] 1 1 1 1 1 1 1 1 1 1 ...
$ loan_no : int [1:41188] 1 1 1 1 0 1 1 1 1 1 ...
$ loan_unknown : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ loan_yes : int [1:41188] 0 0 0 0 1 0 0 0 0 0 ...
$ housing_no : int [1:41188] 1 1 0 1 1 1 1 1 0 0 ...
$ housing_unknown : int [1:41188] 0 0 0 0 0 0 0 0 0 0 ...
$ housing_yes : int [1:41188] 0 0 1 0 0 0 0 0 1 1 ...
- attr(*, ".internal.selfref")=<externalptr>
También debemos tener en cuenta que para poder empezar con nuestro análisis debemos separar nuestra base en entrenamiento y prueba con proporciones \(80\%\) y \(20\%\) respectivamente, y a partir de aquí se trabajará con la base de entrenamiento.
Ahora bien, otro análisis que tenemos pendiente es saber que varibles deberían entrar al modelo, para lo cual realizamos un test de Kolmogrov_Smirnov, y obtenemos lo valores presentados en la tabla siguiente:
nombres valores
1 kage 0.0363
2 kdur 0.0000
3 kcam 0.0317
4 kpda 0.0071
5 kprev 0.0980
6 kcpi 0.2904
7 keur 0.0000
8 knremp 0.2253
9 kevr 0.0620
10 kcci 0.0000
11 kjob1 0.0339
12 kjob2 0.0496
13 kjob3 0.0232
14 kjob4 0.0494
15 ked1 0.0940
16 ked2 0.0468
17 ked3 0.0212
18 kmar1 0.0206
19 kmar2 0.0589
20 kmar3 0.0308
21 kmar4 0.0614
22 kdia1 0.0170
23 kdia2 0.1010
24 kdia3 0.0422
25 kdia4 0.0300
26 kdia5 0.0434
27 kmes3 0.3995
28 kmes4 0.1109
29 kmes5 0.4657
30 kmes6 0.5657
31 kmes7 0.4451
32 kmes8 0.2345
33 kmes9 0.2488
34 kmes10 0.2433
35 kmes11 0.1575
36 kmes12 0.3711
37 kcel 0.0787
38 ktel 0.6924
39 kloanyes 0.0009
40 kloanno 0.0131
41 kloandes 0.0776
42 khouyes 0.0048
43 khouno 0.0730
44 khoudes 0.0776
Con lo cual, definiendo un \(\alpha=0.05\) las variables que ingresarán a nuestro modelo serán todas las categóricas y numéricas que tengan un \(p-valor>0.05\)
Para el modelo inicial usamos la funcion “glm” y a continuación presentamos un resumen de dicho ajuste:
Call:
glm(formula = y ~ marital_married + marital_unknown + education_basica +
education_media + month_mar + month_apr + month_may + month_jun +
month_jul + month_aug + month_sep + month_oct + month_nov +
month_dec + contact_cellular + contact_telephone + loan_unknown +
housing_no + housing_unknown + poutcome + previous + cons.price.idx +
nr.employed + emp.var.rate + day_of_week_tue + day_of_week_fri +
job_gr2 + job_gr4, family = binomial(link = "logit"), data = Datos_entrenamiento1)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.0103 -0.3957 -0.3337 -0.2377 2.7572
Coefficients: (3 not defined because of singularities)
Estimate Std. Error z value Pr(>|z|)
(Intercept) 45.0220577 2.8971138 15.540 < 2e-16 ***
marital_married -0.0148403 0.0403071 -0.368 0.712739
marital_unknown 0.3006795 0.4045543 0.743 0.457339
education_basica 0.0148450 0.0684807 0.217 0.828383
education_media -0.1280947 0.0443810 -2.886 0.003899 **
month_mar 0.6433155 0.2066565 3.113 0.001852 **
month_apr -0.2367298 0.1882934 -1.257 0.208667
month_may -0.8765010 0.1853079 -4.730 2.25e-06 ***
month_jun 0.0519192 0.1908145 0.272 0.785551
month_jul 0.1256124 0.1941106 0.647 0.517556
month_aug -0.0946209 0.1908423 -0.496 0.620031
month_sep -0.3680233 0.2083809 -1.766 0.077378 .
month_oct -0.1264570 0.2007879 -0.630 0.528823
month_nov -0.1684610 0.2101863 -0.801 0.422851
month_dec NA NA NA NA
contact_cellular 0.3473972 0.0590958 5.879 4.14e-09 ***
contact_telephone NA NA NA NA
loan_unknown 0.0720653 0.1281009 0.563 0.573730
housing_no 0.0612223 0.0398197 1.537 0.124174
housing_unknown NA NA NA NA
poutcomenonexistent 0.5138662 0.0950891 5.404 6.52e-08 ***
poutcomesuccess 1.7035918 0.0864178 19.713 < 2e-16 ***
previous 0.0889721 0.0590526 1.507 0.131898
cons.price.idx 0.1004919 0.0430851 2.332 0.019679 *
nr.employed -0.0092817 0.0005605 -16.560 < 2e-16 ***
emp.var.rate -0.1266404 0.0258570 -4.898 9.70e-07 ***
day_of_week_tue 0.0302363 0.0508390 0.595 0.552013
day_of_week_fri -0.0067470 0.0518601 -0.130 0.896487
job_gr2 0.1072957 0.0568258 1.888 0.059005 .
job_gr4 0.1756501 0.0485370 3.619 0.000296 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 23204 on 32953 degrees of freedom
Residual deviance: 18485 on 32927 degrees of freedom
AIC: 18539
Number of Fisher Scoring iterations: 6
De la tabla anterior podemos ver que existen varias variables que no son significativas por lo que nuestro modelo 1 primero eliminamos las variables con NAs obteniendo la siguiente información
Call:
glm(formula = y ~ marital_married + marital_unknown + education_basica +
education_media + month_mar + month_apr + month_may + month_jun +
month_jul + month_aug + month_sep + month_oct + month_nov +
contact_cellular + loan_unknown + housing_no + poutcome +
previous + cons.price.idx + nr.employed + emp.var.rate +
day_of_week_tue + day_of_week_fri + job_gr2 + job_gr4, family = binomial(link = "logit"),
data = Datos_entrenamiento1)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.0103 -0.3957 -0.3337 -0.2377 2.7572
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 45.0220577 2.8971138 15.540 < 2e-16 ***
marital_married -0.0148403 0.0403071 -0.368 0.712739
marital_unknown 0.3006795 0.4045543 0.743 0.457339
education_basica 0.0148450 0.0684807 0.217 0.828383
education_media -0.1280947 0.0443810 -2.886 0.003899 **
month_mar 0.6433155 0.2066565 3.113 0.001852 **
month_apr -0.2367298 0.1882934 -1.257 0.208667
month_may -0.8765010 0.1853079 -4.730 2.25e-06 ***
month_jun 0.0519192 0.1908145 0.272 0.785551
month_jul 0.1256124 0.1941106 0.647 0.517556
month_aug -0.0946209 0.1908423 -0.496 0.620031
month_sep -0.3680233 0.2083809 -1.766 0.077378 .
month_oct -0.1264570 0.2007879 -0.630 0.528823
month_nov -0.1684610 0.2101863 -0.801 0.422851
contact_cellular 0.3473972 0.0590958 5.879 4.14e-09 ***
loan_unknown 0.0720653 0.1281009 0.563 0.573730
housing_no 0.0612223 0.0398197 1.537 0.124174
poutcomenonexistent 0.5138662 0.0950891 5.404 6.52e-08 ***
poutcomesuccess 1.7035918 0.0864178 19.713 < 2e-16 ***
previous 0.0889721 0.0590526 1.507 0.131898
cons.price.idx 0.1004919 0.0430851 2.332 0.019679 *
nr.employed -0.0092817 0.0005605 -16.560 < 2e-16 ***
emp.var.rate -0.1266404 0.0258570 -4.898 9.70e-07 ***
day_of_week_tue 0.0302363 0.0508390 0.595 0.552013
day_of_week_fri -0.0067470 0.0518601 -0.130 0.896487
job_gr2 0.1072957 0.0568258 1.888 0.059005 .
job_gr4 0.1756501 0.0485370 3.619 0.000296 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 23204 on 32953 degrees of freedom
Residual deviance: 18485 on 32927 degrees of freedom
AIC: 18539
Number of Fisher Scoring iterations: 6
Para nuestro segundo modelo procedemos a realizar el mismo análisis y notamos que la variable Educación básica que presenta un p-valor mayor a 0.5 por lo que la eliminamos obteniendo la siguiente información:
Call:
glm(formula = y ~ marital_married + marital_unknown + education_media +
month_mar + month_apr + month_may + month_jun + month_jul +
month_aug + month_sep + month_oct + month_nov + contact_cellular +
loan_unknown + housing_no + poutcome + previous + cons.price.idx +
nr.employed + emp.var.rate + day_of_week_tue + day_of_week_fri +
job_gr2 + job_gr4, family = binomial(link = "logit"), data = Datos_entrenamiento1)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.0116 -0.3960 -0.3333 -0.2371 2.7569
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 45.0181874 2.8970258 15.539 < 2e-16 ***
marital_married -0.0140639 0.0401466 -0.350 0.726104
marital_unknown 0.3012062 0.4046562 0.744 0.456664
education_media -0.1304532 0.0430169 -3.033 0.002425 **
month_mar 0.6435418 0.2066493 3.114 0.001845 **
month_apr -0.2360489 0.1882655 -1.254 0.209912
month_may -0.8756508 0.1852647 -4.726 2.28e-06 ***
month_jun 0.0522652 0.1908063 0.274 0.784148
month_jul 0.1263883 0.1940759 0.651 0.514897
month_aug -0.0946641 0.1908418 -0.496 0.619870
month_sep -0.3673461 0.2083586 -1.763 0.077893 .
month_oct -0.1262877 0.2007864 -0.629 0.529372
month_nov -0.1682713 0.2101827 -0.801 0.423366
contact_cellular 0.3472175 0.0590879 5.876 4.20e-09 ***
loan_unknown 0.0720536 0.1280999 0.562 0.573789
housing_no 0.0612570 0.0398193 1.538 0.123957
poutcomenonexistent 0.5138983 0.0950880 5.404 6.50e-08 ***
poutcomesuccess 1.7035123 0.0864156 19.713 < 2e-16 ***
previous 0.0891490 0.0590463 1.510 0.131091
cons.price.idx 0.1005786 0.0430829 2.335 0.019568 *
nr.employed -0.0092807 0.0005605 -16.559 < 2e-16 ***
emp.var.rate -0.1265988 0.0258560 -4.896 9.77e-07 ***
day_of_week_tue 0.0303265 0.0508370 0.597 0.550812
day_of_week_fri -0.0066142 0.0518563 -0.128 0.898507
job_gr2 0.1073098 0.0568219 1.889 0.058955 .
job_gr4 0.1764345 0.0483982 3.645 0.000267 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 23204 on 32953 degrees of freedom
Residual deviance: 18485 on 32928 degrees of freedom
AIC: 18537
Number of Fisher Scoring iterations: 6
Con el mismo análisis de los modelos anteriores (3:14) se identificaron las variables con un p-valor mayor a 0.05 así se obtuvo un modelo.
Call:
glm(formula = y ~ education_media + month_mar + month_apr + month_may +
month_sep + contact_cellular + poutcome + cons.price.idx +
nr.employed + emp.var.rate + job_gr4, family = binomial(link = "logit"),
data = Datos_entrenamiento1)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.9831 -0.3876 -0.3406 -0.2375 2.7188
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 45.0505379 2.6201447 17.194 < 2e-16 ***
education_media -0.1168464 0.0416376 -2.806 0.005012 **
month_mar 0.6653318 0.1072488 6.204 5.52e-10 ***
month_apr -0.2326433 0.0640759 -3.631 0.000283 ***
month_may -0.8798985 0.0499645 -17.610 < 2e-16 ***
month_sep -0.3331108 0.1134875 -2.935 0.003333 **
contact_cellular 0.3497829 0.0531933 6.576 4.84e-11 ***
poutcomenonexistent 0.4023261 0.0602077 6.682 2.35e-11 ***
poutcomesuccess 1.7181643 0.0856849 20.052 < 2e-16 ***
cons.price.idx 0.1552607 0.0255458 6.078 1.22e-09 ***
nr.employed -0.0092574 0.0005101 -18.148 < 2e-16 ***
emp.var.rate -0.1108903 0.0241999 -4.582 4.60e-06 ***
job_gr4 0.1531803 0.0465785 3.289 0.001007 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 23204 on 32953 degrees of freedom
Residual deviance: 18506 on 32941 degrees of freedom
AIC: 18532
Number of Fisher Scoring iterations: 6
Para validar nuestro modelo 15 se plantean las siguientes hipótesis. \[H_0: \text{Modelo no significativo}\] \[H_a: \text{Modelo significativo}\]
[1] 4697.757
[1] 0
Dado el p-valor obtenido es menor a 0.05 se rechaza \(H_0\) por lo que el modelo 15 es válido.
Se nota que el coeficiente de la variable education_media es negativo, por lo que una persona de esta categoría tiende a disminuir el caer en mora.
Por otro lado, los coeficientes de las variables month en abril, mayo y septiembre son negativos, es decir, la probabilidad de mora disminuye, mientras que la del mes de marzo es positivo, por tanto, la probabilidad de mora aumenta.
Para la variable cons.price.idx es positiva, mientras más aumenta el indicador de precios hay más probabilidad de caer en mora.
El coeficiente de la variable emp.var.rate es negativo lo que indica que a menor tasa de desempleo la probabilidad de mora disminuye.
El coeficiente de la variable job_gr4 es positivo, la probabilidad de mora de que un cliente se encuentre en este grupo de ocupaciones (entrepreneur, housemaid, retired, self-employed, student) aumentará.
Es una representación gráfica de la sensibilidad frente a la especificidad para un sistema clasificador binario según se varía el umbral de discriminación. Otra interpretación de este gráfico es la representación de la razón o ratio de verdaderos positivos (VPR = Razón de Verdaderos Positivos) frente a la razón o ratio de falsos positivos (FPR = Razón de Falsos Positivos) también según se varía el umbral de discriminación (valor a partir del cual decidimos que un caso es un positivo).
Para nuestro modelo el gráfico de la curva Roc es el siguiente
Realizamos el mismo análisis con los datos apartados para la validación del modelo y tenemos los siguientes resultados:
[1] 7239
[1] 184
[1] 743
[1] 68
res2 0 1
0 7239 743
1 68 184
res2 0 1
0 0.879159582 0.090235608
1 0.008258441 0.022346369
[1] 0.901506
Podemos ver que la precisón del modelo es similar, por lo que se valida el modelo.
Para la creación de los gupos homogéneos, en primer lugar, aumentamos las columnas monthd que significa porcentaje de desempleo a nuestra base de entrenamiento, además una columna que tiene las nuevas tasas de mora asignadas a la variable prob, las cuales se han obtenido de nuestro modelo LOGIT.
Ahora, bajo la metodología PIT haremos uso de la Medida de Gower de la función daisy (disponible en el software R), es decir, se calcula todas las diferentes distancias por pares entre observaciones en el conjunto de datos, además usaremos la columna prob como medida de distancia. Y se obtiene los siguientes resultados:
El resultado que se obtiene de este dendograma nos indica que la cantidad adecuada de grupos de riesgos para este modelo son 4. Las probabilidades de nuestro modelo tendrán una relación jerárquica más cercana dependiendo de su probabilidad de la concesión de crédito de cada cliente.
A continuación, se presenta los resultados de como están distribuidos los grupos de riesgo para el modelo PIT:
| Cluster | 0 | 1 |
|---|---|---|
| 1 | 13179 | 684 |
| 2 | 8423 | 2425 |
| 3 | 13747 | 714 |
| 4 | 1133 | 813 |
Después de haber obtenido la clasificación de los grupos, vamos a proceder con la validación para el modelo PIT, pues se debe verificar que la tasa de mora de un grupo homogéneo es diferente a la tasa de mora de otro. Utilizando la prueba de Dunnett T3, donde:
\[H_0= \text{las medias de los grupos son iguales}\] \[H_a= \text{Las medias de los grupos son diferentes}\]
| 1 | 2 | 3 | |
|---|---|---|---|
| 2 | 2e-16 | ||
| 3 | 8.3e-12 | 2e-16 | |
| 4 | 2e-16 | 2e-16 | 2e-16 |
Podemos concluir que los grupos de riesgo del modelo PIT son válidos, puesto que al usar el test de Dunnett T3, de éste se obtiene un pval<0.05 lo que implica que se rechaza “H_0=Las medias de los grupos son iguales”.
prob A continuación, presentamos como están distribuidos los grupos de riesgo para este modelo.
De igual manera que el análisis del dendograma de método PIT, se indica que la cantidad de grupos de riesgo es de 4.
A continuación, se presenta los resultados de como están distribuidos los grupos de riesgo para el modelo TTC:
| Cluster | 0 | 1 |
|---|---|---|
| 1 | 12814 | 649 |
| 2 | 10524 | 3603 |
| 3 | 2256 | 274 |
| 4 | 888 | 110 |
| 1 | 2 | 3 | |
|---|---|---|---|
| 2 | 2e-16 | ||
| 3 | 2e-16 | 1.0e-08 | |
| 4 | 4.3e-09 | 0.0035 | 0.0099 |
De igual forma que el modelo PIT, se realiza un test de Dunnet T3 dónde se muestra que dado el \(pval<0.05\) se rechaza “H_0=Las medias de los grupos son iguales”.