DATA FRAME

datos=read.csv("https://raw.githubusercontent.com/VictorGuevaraP/Mineria-de-datos-2020/master/mora_m.csv", sep = ";")
head(datos)
##     ID Edad Experiencia Ingreso Postal Familia credito educacion
## 1 1550   57          31      45  94305       3    1.40         1
## 2 4703   35           5     108  90630       2    2.75         3
## 3 2478   40          14     179  90025       1    2.60         3
## 4 3109   42          15      21  95678       3    1.00         2
## 5 2733   33           9      38  93106       1    2.10         3
## 6 2372   32           6      NA  95014       2    1.50         3
##   cuenta.de.ahorros servicios.online Mora
## 1                 0                1    0
## 2                 0                0    0
## 3                 1                1    0
## 4                 0                1    0
## 5                 0                0    0
## 6                 0                0    0

Objetivo: Construir un modelo de clasificación de minería de datos que permita clasificar si un cliente de un entidad bancaria va a ser moroso o no

ENTENDIMIENTO DE LA DATA

Data inicial

  • ID: Representa el identificador de cada uno de los clientes
  • Edad: Edad de los clientes del banco en años
  • Experiencia: Años de experiencia del cliente en su labor
  • Ingreso: Ingreso anual de los clientes en miles de S/
  • Postal: Codigo postal del cliente
  • Reducacion: Nivel de educación del cliente
  • Mora: Si un cliente es o no moroso (1 = moroso y 0= no moroso)

Descripción de la data

Se cuenta con un conjunto de datos de 4277 observaciones(fila) y 11 variables (columnas) La variable objetivo es “Mora” por lo que 1 representa si el cliente es moroso y 0 si el cliente no lo es podemos apreciar que hay 1255 morosos y 3022 no morosos El ID es un identificador por los que se no se puede hacer hacer operaciones matemáticas

str(datos)
## 'data.frame':    4277 obs. of  11 variables:
##  $ ID               : int  1550 4703 2478 3109 2733 2372 793 2268 1432 2690 ...
##  $ Edad             : int  57 35 40 42 33 32 41 NA 58 NA ...
##  $ Experiencia      : int  31 5 14 15 9 6 16 13 34 16 ...
##  $ Ingreso          : int  45 108 179 21 38 NA NA 168 128 104 ...
##  $ Postal           : int  94305 90630 90025 95678 93106 95014 93117 92647 90058 91730 ...
##  $ Familia          : int  3 2 1 3 1 2 1 2 1 1 ...
##  $ credito          : num  1.4 2.75 2.6 1 2.1 1.5 4 1.3 7.4 3.4 ...
##  $ educacion        : int  1 3 3 2 3 3 3 3 1 1 ...
##  $ cuenta.de.ahorros: int  0 0 1 0 0 0 1 0 0 0 ...
##  $ servicios.online : int  1 0 1 1 0 0 0 0 0 0 ...
##  $ Mora             : int  0 0 0 0 0 0 1 0 0 0 ...

Coersión

datos$Mora=as.factor(datos$Mora)
datos$ID=as.factor(datos$ID)
datos$Postal=as.factor(datos$Postal)
datos$educacion=as.factor(datos$educacion)
datos$cuenta.de.ahorros=as.factor(datos$cuenta.de.ahorros)
datos$servicios.online=as.factor(datos$servicios.online)

Exploración de datos

library(ggplot2)
ggplot(data=datos)+
  geom_histogram(mapping = aes(x=Edad, color=Mora))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

calidad de datos

En la variable experencia tenemos 344 datos NA´S (nulos o missing) y representa un …% de todos los registros. Tambien en la experiencia encontramos un valor de -3 se tendria que revisar si este dato es inconsistente. En la variable Ingreso tenemos 388 datos NA´S (nulos o missing) Podemos observar que para la variable ingreso existen datos atípicos en la parte superior

#Fase 3: Preparación de los datos

Seleccionamos los datos

Del conjunto de datos, solo no seleccionaremos el ID por ser unica en cada registro

datosnew=datos[,2:11]
head(datosnew)
##   Edad Experiencia Ingreso Postal Familia credito educacion cuenta.de.ahorros
## 1   57          31      45  94305       3    1.40         1                 0
## 2   35           5     108  90630       2    2.75         3                 0
## 3   40          14     179  90025       1    2.60         3                 1
## 4   42          15      21  95678       3    1.00         2                 0
## 5   33           9      38  93106       1    2.10         3                 0
## 6   32           6      NA  95014       2    1.50         3                 0
##   servicios.online Mora
## 1                1    0
## 2                0    0
## 3                1    0
## 4                1    0
## 5                0    0
## 6                0    0

Limpiar data

# install.packages("DMwR")
library(DMwR)
datosnew4=knnImputation(datosnew)
summary(datosnew4)
##       Edad        Experiencia      Ingreso           Postal        Familia     
##  Min.   :23.00   Min.   :-3.0   Min.   :  8.00   94720  : 156   Min.   :1.000  
##  1st Qu.:35.00   1st Qu.:10.0   1st Qu.: 40.00   94305  : 105   1st Qu.:1.000  
##  Median :45.00   Median :20.0   Median : 63.76   95616  : 101   Median :2.000  
##  Mean   :45.33   Mean   :20.1   Mean   : 73.80   90095  :  59   Mean   :2.391  
##  3rd Qu.:55.00   3rd Qu.:30.0   3rd Qu.: 95.00   93106  :  51   3rd Qu.:3.000  
##  Max.   :67.00   Max.   :43.0   Max.   :224.00   92037  :  48   Max.   :4.000  
##                                                  (Other):3757                  
##     credito       educacion cuenta.de.ahorros servicios.online Mora    
##  Min.   : 0.000   1:1806    0:3856            0:1721           0:3022  
##  1st Qu.: 0.700   2:1214    1: 421            1:2556           1:1255  
##  Median : 1.500   3:1257                                               
##  Mean   : 1.939                                                        
##  3rd Qu.: 2.500                                                        
##  Max.   :10.000                                                        
## 

Construir data

# install.packages("arules")
library(arules)
edad_discretizada=discretize(datosnew4$Edad, method = "interval", categories =14 )

Integrar data

datosnew4=cbind(datosnew4, edad_discretizada)
summary(datosnew4)
##       Edad        Experiencia      Ingreso           Postal        Familia     
##  Min.   :23.00   Min.   :-3.0   Min.   :  8.00   94720  : 156   Min.   :1.000  
##  1st Qu.:35.00   1st Qu.:10.0   1st Qu.: 40.00   94305  : 105   1st Qu.:1.000  
##  Median :45.00   Median :20.0   Median : 63.76   95616  : 101   Median :2.000  
##  Mean   :45.33   Mean   :20.1   Mean   : 73.80   90095  :  59   Mean   :2.391  
##  3rd Qu.:55.00   3rd Qu.:30.0   3rd Qu.: 95.00   93106  :  51   3rd Qu.:3.000  
##  Max.   :67.00   Max.   :43.0   Max.   :224.00   92037  :  48   Max.   :4.000  
##                                                  (Other):3757                  
##     credito       educacion cuenta.de.ahorros servicios.online Mora    
##  Min.   : 0.000   1:1806    0:3856            0:1721           0:3022  
##  1st Qu.: 0.700   2:1214    1: 421            1:2556           1:1255  
##  Median : 1.500   3:1257                                               
##  Mean   : 1.939                                                        
##  3rd Qu.: 2.500                                                        
##  Max.   :10.000                                                        
##                                                                        
##    edad_discretizada
##  [45,48.1)  : 426   
##  [57.6,60.7): 363   
##  [32.4,35.6): 354   
##  [51.3,54.4): 341   
##  [41.9,45)  : 337   
##  [29.3,32.4): 333   
##  (Other)    :2123

Formato data

write.csv(datosnew4, file = "datos_listo.csv")
getwd()
## [1] "/cloud/project"

Arboles de desición

Eliminamos las variables que no son necesarias

datosnew4=datosnew4[,c(1:3,5:10)]
head(datosnew4)
##   Edad Experiencia   Ingreso Familia credito educacion cuenta.de.ahorros
## 1   57          31  45.00000       3    1.40         1                 0
## 2   35           5 108.00000       2    2.75         3                 0
## 3   40          14 179.00000       1    2.60         3                 1
## 4   42          15  21.00000       3    1.00         2                 0
## 5   33           9  38.00000       1    2.10         3                 0
## 6   32           6  64.80308       2    1.50         3                 0
##   servicios.online Mora
## 1                1    0
## 2                0    0
## 3                1    0
## 4                1    0
## 5                0    0
## 6                0    0

Construir la data train y test

# install.packages("caret")
library(caret)
particion=createDataPartition(y = datosnew4$Mora, p = 0.70, list = FALSE, times = 1)
train=datosnew4[particion,]
test=datosnew4[-particion,]
dim(train)
## [1] 2995    9
dim(test)
## [1] 1282    9

Modelo árbol por defecto

library(rpart)
modelo1=rpart(Mora~.,data=train,method = "class", minsplit=0, cp=0.001)

library(partykit)
plot(as.party(modelo1))

Evaluación del modelo

head(test)
##        Edad Experiencia Ingreso Familia credito educacion cuenta.de.ahorros
## 8  36.53249          13     168       2     1.3         3                 0
## 15 32.23602           4     154       2     4.5         1                 0
## 19 50.00000          24     124       1     4.9         1                 0
## 25 50.00000          26      88       1     2.7         1                 1
## 32 32.00000           6      25       2     0.3         1                 0
## 35 50.00000          25      44       1     0.3         1                 0
##    servicios.online Mora
## 8                 0    0
## 15                1    0
## 19                1    0
## 25                1    0
## 32                0    1
## 35                1    1

Predecir en data de prueba utilizando el modelo

predichos=predict(modelo1, test, type = "class")
predichos
comparacion=cbind(test$Mora, predichos)

Matriz de confusión

matriz_confusion=table(predichos, test$Mora)
matriz_confusion

Medidas de rendimiento del modelo

library(caret)
medidas=confusionMatrix(predichos, test$Mora)

modelo2=rpart(Mora~.,data=train,method = "class", minsplit=0, cp=0.001)
summary(modelo2)

#Predecir en data de prueba utilizando el modelo
predichos2=predict(modelo2, test, type = "class")
predichos2

#Matriz de confusión
matriz_confusion2=table(predichos2, test$Mora)
matriz_confusion2

medidas2=confusionMatrix(predichos2, test$Mora, positive = "1")$byClass["F1"]
medidas2

Curva roc

str(test)
pred_prob<-predict(modelo2, test, type = "prob")[,2]
pred_prob
library(ROCR)
predR1 <- prediction(pred_prob, test$Mora)
predR2<-performance(predR1, "tpr", "fpr")
plot(predR2, colorize = T)
lines(x=c(0, 1), y=c(0, 1), col=" blue", lwd=1, lty=3);
lines(x=c(1, 0), y=c(0, 1), col="red", lwd=1, lty=4)

Indice GINI

ROCRN <- round(performance(predR1, measure = "auc")@y.values[[1]]*100, 2)
giniRN <- (2*ROCRN - 100)
giniRN

Aplicando SMOTE

library(DMwR)
set.seed(1022)
partition.ids <- createDataPartition(datosnew4$Mora, p = 0.7, list = F)
testing.ids <- datosnew4[partition.ids,]
train.ids <- datosnew4[-partition.ids,]
head(testing.ids)
##   Edad Experiencia   Ingreso Familia credito educacion cuenta.de.ahorros
## 1   57          31  45.00000       3    1.40         1                 0
## 2   35           5 108.00000       2    2.75         3                 0
## 4   42          15  21.00000       3    1.00         2                 0
## 5   33           9  38.00000       1    2.10         3                 0
## 6   32           6  64.80308       2    1.50         3                 0
## 7   41          16  94.03531       1    4.00         3                 1
##   servicios.online Mora
## 1                1    0
## 2                0    0
## 4                1    0
## 5                0    0
## 6                0    0
## 7                0    1
d.smote = SMOTE(train.ids$Mora~., data = train.ids)
tabla = rbind(table(train.ids$Mora),
              table(d.smote$Mora))
rownames(tabla) <- c("Train","SMOTE")
tabla
##          0    1
## Train  906  376
## SMOTE 1504 1128