Sesión 04

Sesión: Valores ausentes y valores outliers

modificar el directorio de trabajo

setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

Caso: Suscripción bancaria

Hoy en día las entidades bancarias constantemente ofrecen diversos productos o servicios a sus clientes, entre estos se tiene a: lineas de crédito, tarjetas, seguros, cuentas de ahorro, etc. El caso presentado corresponde a una campaña realizado por una entidad local, para la suscripción de un servicio especial de crédito. La columna suscrito, representa al resultado de la campaña, 1. Si el cliente se suscribió al servicio y 0. Si el cliente no se suscribió La entidad guarda información de cada uno de sus clientes. El detalle de las varibles es:

Carga de datos

url<-"https://raw.githubusercontent.com/VictorGuevaraP/ME-Machine-Learning/master/banco%20mod.csv"
banco_df<-read.csv(url, sep = ",", stringsAsFactors = T, encoding = "latin1")

Mostrar los primeros registros

head(banco_df)

Verificar si hay patrones con librerias

library(VIM)
library(mice)
grafico_miss <- aggr(banco_df, numbers =T)

grafico_miss
## 
##  Missings in variables:
##      Variable Count
##      duracion    17
##  Nueva_cuenta    56
##        empleo    32
summary(grafico_miss)
## 
##  Missings per variable: 
##        Variable Count
##               X     0
##        duracion    17
##           monto     0
##            tasa     0
##      Residencia     0
##            Edad     0
##        tarjetas     0
##     NroUsuarios     0
##  Limite_Credito     0
##    Nueva_cuenta    56
##   razonPrestamo     0
##      expiración     0
##     EstadoCivil     0
##           deuda     0
##     propiedades     0
##   creditos_otro     0
##        vivienda     0
##          empleo    32
##        telefono     0
##        suscrito     0
## 
##  Missings in combinations of variables: 
##                             Combinations Count     Percent
##  0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0  1119 91.79655455
##  0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:1:0:0    28  2.29696473
##  0:0:0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:0:0:0    53  4.34782609
##  0:0:0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:1:0:0     2  0.16406891
##  0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0    14  1.14848236
##  0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:1:0:0     2  0.16406891
##  0:1:0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:0:0:0     1  0.08203445

Representación matricial

matrixplot(banco_df)

M. KNN (Vecinos más cercanos)

Se va a utilizar imputación con el método de vecionos más cercanos …

library(DMwR2)
banco_imp_knn <- knnImputation(banco_df, k=10)
dim(banco_imp_knn)
## [1] 1219   20

Evaluación y tratamiento de valores outliers

banco_c <- banco_imp_knn 
str(banco_c)
## 'data.frame':    1219 obs. of  20 variables:
##  $ X             : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ duracion      : num  6 48 12 42 24 36 24 36 12 30 ...
##  $ monto         : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ tasa          : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ Residencia    : int  4 2 3 4 4 4 4 2 4 2 ...
##  $ Edad          : int  67 22 49 45 53 35 53 35 61 28 ...
##  $ tarjetas      : int  2 1 1 1 2 1 1 1 1 2 ...
##  $ NroUsuarios   : int  1 1 2 2 2 2 1 1 1 1 ...
##  $ Limite_Credito: Factor w/ 4 levels "entre 0-5000",..: 4 1 3 4 4 3 3 1 3 1 ...
##  $ Nueva_cuenta  : Factor w/ 4 levels "Cuenta crítica",..: 1 3 1 3 4 3 3 3 3 1 ...
##  $ razonPrestamo : Factor w/ 10 levels "Divisas ","Electrodomésticos",..: 9 9 3 5 10 3 5 1 9 10 ...
##  $ expiración    : Factor w/ 5 levels "1-4 años ","4-7 años",..: 5 1 2 2 1 4 5 1 2 4 ...
##  $ EstadoCivil   : Factor w/ 4 levels "F Divorciadas/casada ",..: 4 1 4 4 4 4 4 4 3 2 ...
##  $ deuda         : Factor w/ 3 levels "0 co-deudor",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ propiedades   : Factor w/ 4 levels "desconocido/ninguno",..: 4 4 4 2 1 1 2 3 4 3 ...
##  $ creditos_otro : Factor w/ 3 levels "Bancario","ninguno",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ vivienda      : Factor w/ 3 levels "Alquiler","Contrato A",..: 3 3 3 2 2 2 3 1 3 3 ...
##  $ empleo        : Factor w/ 4 levels "Dependiente",..: 1 1 4 1 1 4 1 2 4 2 ...
##  $ telefono      : Factor w/ 2 levels "No","Si": 1 2 2 2 2 1 2 1 2 2 ...
##  $ suscrito      : int  0 1 0 0 1 0 0 0 0 1 ...
# Eliminar la columna X
banco_c <- banco_c[,2:20]
str(banco_c)
## 'data.frame':    1219 obs. of  19 variables:
##  $ duracion      : num  6 48 12 42 24 36 24 36 12 30 ...
##  $ monto         : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ tasa          : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ Residencia    : int  4 2 3 4 4 4 4 2 4 2 ...
##  $ Edad          : int  67 22 49 45 53 35 53 35 61 28 ...
##  $ tarjetas      : int  2 1 1 1 2 1 1 1 1 2 ...
##  $ NroUsuarios   : int  1 1 2 2 2 2 1 1 1 1 ...
##  $ Limite_Credito: Factor w/ 4 levels "entre 0-5000",..: 4 1 3 4 4 3 3 1 3 1 ...
##  $ Nueva_cuenta  : Factor w/ 4 levels "Cuenta crítica",..: 1 3 1 3 4 3 3 3 3 1 ...
##  $ razonPrestamo : Factor w/ 10 levels "Divisas ","Electrodomésticos",..: 9 9 3 5 10 3 5 1 9 10 ...
##  $ expiración    : Factor w/ 5 levels "1-4 años ","4-7 años",..: 5 1 2 2 1 4 5 1 2 4 ...
##  $ EstadoCivil   : Factor w/ 4 levels "F Divorciadas/casada ",..: 4 1 4 4 4 4 4 4 3 2 ...
##  $ deuda         : Factor w/ 3 levels "0 co-deudor",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ propiedades   : Factor w/ 4 levels "desconocido/ninguno",..: 4 4 4 2 1 1 2 3 4 3 ...
##  $ creditos_otro : Factor w/ 3 levels "Bancario","ninguno",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ vivienda      : Factor w/ 3 levels "Alquiler","Contrato A",..: 3 3 3 2 2 2 3 1 3 3 ...
##  $ empleo        : Factor w/ 4 levels "Dependiente",..: 1 1 4 1 1 4 1 2 4 2 ...
##  $ telefono      : Factor w/ 2 levels "No","Si": 1 2 2 2 2 1 2 1 2 2 ...
##  $ suscrito      : int  0 1 0 0 1 0 0 0 0 1 ...
# outliers univariado
boxplot(banco_c$duracion)

boxplot(banco_c[,1:7])

# transformación o estandarización de datos
head((banco_c$duracion-mean(banco_c$duracion))/sd(banco_c$duracion))
## [1] -1.2149846  2.3107706 -0.7113053  1.8070913  0.2960533  1.3034120
# scale(banco_c$duracion)
head(banco_c)
# Estandarizar solo las variables cuantitativas y juntarlo con las cualitativas
banco_estandar<- cbind(scale(banco_c[,1:7]),banco_c[,8:19])
head(banco_estandar)
boxplot(banco_estandar[,1:7])

# Identificando valores outliers a partir de los estandarizados
rownames(banco_estandar[abs(banco_estandar[,1])>3,])
##  [1] "30"   "133"  "254"  "330"  "371"  "372"  "635"  "670"  "675"  "683" 
## [11] "712"  "932"  "963"  "1086" "1177"
banco_estandar[27:34,]
# Valores outliers a partir de percentiles
outlier<-boxplot(banco_c$duracion)$out
head(outlier)
## [1] 48 48 60 45 48 48
outtext<-as.character(outlier)
boxplot(banco_c$duracion)
for(i in 1:length(outlier))
{
  text(outlier[i],as.character(which(banco_c$duracion==outlier[i])), 
       cex = 0.6, pos=2)
}

banco_c[672:680,]
# outliers bivariado
plot(banco_c$duracion, banco_c$monto)
identify(banco_c$duracion, banco_c$monto)

## integer(0)
banco_c[812:820,]
# Outliers multivariado (distancia de mahalanobis)
out<-mahalanobis(banco_c[,1:7],colMeans(banco_c[,1:7]),cov(banco_c[,1:7]))
head(out)
##         1         2         3         4         5         6 
## 10.317901  8.872479  8.809891 12.083069  8.208748 12.143772
barplot(out)

which.max(out)
## 1208 
## 1208
boxplot(out, ylab = "Distancias de Mahalanobis")

outtext<-as.character(out)
boxplot(out)
for(i in 1:length(out))
{
  text(out[i],as.character(which(out==out[i])), 
       cex = 0.6, pos=2)
}

banco_c[c(232:238,1205:1210),]
# Mahalanobis tiene una distribución Chi Cuadrado con g.l. igual al número de variables analizadas
# Los datos atipicos, seran considerados aquellos que su probabilidad sean menores a 0.001
head(pchisq(out,7))
##         1         2         3         4         5         6 
## 0.8287374 0.7380583 0.7334052 0.9021400 0.6854527 0.9040711
options(digits = 5)
# Combinamos los datos originales con la distancia de Mahalanobis y la probablidad chi-cuadrada
outliers_multi<-cbind(banco_c[,1:7],"Mahalanobis"=out, "p-valor"=round(pchisq(out,7),5))
head(outliers_multi)
# Mostrar solo atípicos
atipicos = subset(outliers_multi,  outliers_multi[9] < 0.01)
atipicos
atipicos[order(atipicos$Mahalanobis,decreasing = TRUE),]