library(readr)
base <- read_csv("C:/Users/Jamileth/Downloads/Actividad02_ADM/Actividad02_ADM/datos_teleco(1).csv")
## New names:
## Rows: 7032 Columns: 23
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (18): ID_cliente, Sexo, Socio, Empleado, Servicio_telefonico, Lineas_mul... dbl
## (5): ...1, Jubilado, Meses_alta, Gasto_mensual, Gasto_total
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
La base consta de 7.032 observaciones y 23 variables
#Verificamos que no existen datos faltantes en la base
which(is.na(base))
## integer(0)
# y lo comprobamos ya que todas las variables tienen 7.032 observaciones
str(base)
## spc_tbl_ [7,032 × 23] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ ...1 : num [1:7032] 1 2 3 4 5 6 7 8 9 10 ...
## $ ID_cliente : chr [1:7032] "7590-VHVEG" "5575-GNVDE" "3668-QPYBK" "7795-CFOCW" ...
## $ Sexo : chr [1:7032] "Female" "Male" "Male" "Male" ...
## $ Jubilado : num [1:7032] 0 0 0 0 0 0 0 0 0 0 ...
## $ Socio : chr [1:7032] "Yes" "No" "No" "No" ...
## $ Empleado : chr [1:7032] "No" "No" "No" "No" ...
## $ Meses_alta : num [1:7032] 1 34 2 45 2 8 22 10 28 62 ...
## $ Servicio_telefonico : chr [1:7032] "No" "Yes" "Yes" "No" ...
## $ Lineas_multiples : chr [1:7032] "No phone service" "No" "No" "No phone service" ...
## $ Servicio_Internet : chr [1:7032] "DSL" "DSL" "DSL" "DSL" ...
## $ Seguridad_Online : chr [1:7032] "No" "Yes" "Yes" "Yes" ...
## $ CopiaSeguridad_Online : chr [1:7032] "Yes" "No" "Yes" "No" ...
## $ Proteccion_dispositivo: chr [1:7032] "No" "Yes" "No" "Yes" ...
## $ Soporte_tecnico : chr [1:7032] "No" "No" "No" "Yes" ...
## $ Television_carta : chr [1:7032] "No" "No" "No" "No" ...
## $ Peliculas_carta : chr [1:7032] "No" "No" "No" "No" ...
## $ Contrato : chr [1:7032] "Month-to-month" "One year" "Month-to-month" "One year" ...
## $ Factura_digital : chr [1:7032] "Yes" "No" "Yes" "No" ...
## $ Metodo_pago : chr [1:7032] "Electronic check" "Mailed check" "Mailed check" "Bank transfer (automatic)" ...
## $ Gasto_mensual : num [1:7032] 29.9 57 53.9 42.3 70.7 ...
## $ Gasto_total : num [1:7032] 29.9 1889.5 108.2 1840.8 151.7 ...
## $ Abandono : chr [1:7032] "No" "No" "Yes" "No" ...
## $ meses_alta_cut : chr [1:7032] "<1" "18-42" "1-6" "42-60" ...
## - attr(*, "spec")=
## .. cols(
## .. ...1 = col_double(),
## .. ID_cliente = col_character(),
## .. Sexo = col_character(),
## .. Jubilado = col_double(),
## .. Socio = col_character(),
## .. Empleado = col_character(),
## .. Meses_alta = col_double(),
## .. Servicio_telefonico = col_character(),
## .. Lineas_multiples = col_character(),
## .. Servicio_Internet = col_character(),
## .. Seguridad_Online = col_character(),
## .. CopiaSeguridad_Online = col_character(),
## .. Proteccion_dispositivo = col_character(),
## .. Soporte_tecnico = col_character(),
## .. Television_carta = col_character(),
## .. Peliculas_carta = col_character(),
## .. Contrato = col_character(),
## .. Factura_digital = col_character(),
## .. Metodo_pago = col_character(),
## .. Gasto_mensual = col_double(),
## .. Gasto_total = col_double(),
## .. Abandono = col_character(),
## .. meses_alta_cut = col_character()
## .. )
## - attr(*, "problems")=<externalptr>
#Analizamos la composición de la variable dependiente
table(base$Abandono)
##
## No Yes
## 5163 1869
Modificamos variable dependiente a 0 y 1 library (dplyr)
base$Abandono <- ifelse (base$Abandono =="Yes",1,0)
table(base$Abandono)
##
## 0 1
## 5163 1869
prop.table(table(base$Abandono))
##
## 0 1
## 0.734215 0.265785
Creamos los dos submuestras una de entrenamiento (80%) y una de validación (20%), pero primero fijamos una semilla para que la muestra siempre que se ejecute sea la misma
library(caTools)
set.seed(12345)
division <- sample.split(base$Abandono, SplitRatio = 0.8)
entrenamiento <- subset (base, division==TRUE)
validacion <- subset (base, division==FALSE)
Verificamos que está equilibrado
prop.table(table(entrenamiento$Abandono))
##
## 0 1
## 0.7342222 0.2657778
prop.table(table(validacion$Abandono))
##
## 0 1
## 0.7341862 0.2658138
CREAMOS EL MODELO LOGIT
Mdentrenamiento <- glm (Abandono ~ as.factor(Contrato) + Factura_digital + as.factor(Servicio_Internet) + as.factor(Soporte_tecnico) + as.factor(CopiaSeguridad_Online) +
as.factor(Television_carta) + Meses_alta, data=entrenamiento, family ="binomial")
summary(Mdentrenamiento)
##
## Call:
## glm(formula = Abandono ~ as.factor(Contrato) + Factura_digital +
## as.factor(Servicio_Internet) + as.factor(Soporte_tecnico) +
## as.factor(CopiaSeguridad_Online) + as.factor(Television_carta) +
## Meses_alta, family = "binomial", data = entrenamiento)
##
## Coefficients: (3 not defined because of singularities)
## Estimate Std. Error z value
## (Intercept) -0.56881 0.09013 -6.311
## as.factor(Contrato)One year -0.77037 0.11617 -6.632
## as.factor(Contrato)Two year -1.51997 0.19289 -7.880
## Factura_digitalYes 0.47773 0.08189 5.834
## as.factor(Servicio_Internet)Fiber optic 0.98858 0.08419 11.743
## as.factor(Servicio_Internet)No -0.96371 0.13992 -6.888
## as.factor(Soporte_tecnico)No internet service NA NA NA
## as.factor(Soporte_tecnico)Yes -0.39071 0.09361 -4.174
## as.factor(CopiaSeguridad_Online)No internet service NA NA NA
## as.factor(CopiaSeguridad_Online)Yes -0.09640 0.08438 -1.142
## as.factor(Television_carta)No internet service NA NA NA
## as.factor(Television_carta)Yes 0.49610 0.08240 6.021
## Meses_alta -0.03417 0.00236 -14.475
## Pr(>|z|)
## (Intercept) 2.77e-10 ***
## as.factor(Contrato)One year 3.32e-11 ***
## as.factor(Contrato)Two year 3.27e-15 ***
## Factura_digitalYes 5.42e-09 ***
## as.factor(Servicio_Internet)Fiber optic < 2e-16 ***
## as.factor(Servicio_Internet)No 5.67e-12 ***
## as.factor(Soporte_tecnico)No internet service NA
## as.factor(Soporte_tecnico)Yes 3.00e-05 ***
## as.factor(CopiaSeguridad_Online)No internet service NA
## as.factor(CopiaSeguridad_Online)Yes 0.253
## as.factor(Television_carta)No internet service NA
## as.factor(Television_carta)Yes 1.74e-09 ***
## Meses_alta < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 6513.9 on 5624 degrees of freedom
## Residual deviance: 4763.8 on 5615 degrees of freedom
## AIC: 4783.8
##
## Number of Fisher Scoring iterations: 6
Se observa que todas las variables son significativas, incluido el intercepto
#Hacemos la predicción
predicentrenamiento <- predict(Mdentrenamiento,type = "response" )
# Codificamos la predicción
predicentren <- ifelse (predicentrenamiento > 0.5, 1, 0)
MATRIZ DE CONFUSIÓN
library (caret)
## Cargando paquete requerido: ggplot2
## Cargando paquete requerido: lattice
confusionMatrix(as.factor(entrenamiento$Abandono), as.factor(predicentren))
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 3710 420
## 1 746 749
##
## Accuracy : 0.7927
## 95% CI : (0.7819, 0.8032)
## No Information Rate : 0.7922
## P-Value [Acc > NIR] : 0.4685
##
## Kappa : 0.4292
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.8326
## Specificity : 0.6407
## Pos Pred Value : 0.8983
## Neg Pred Value : 0.5010
## Prevalence : 0.7922
## Detection Rate : 0.6596
## Detection Prevalence : 0.7342
## Balanced Accuracy : 0.7367
##
## 'Positive' Class : 0
##
Los datos reflejan que el modelo acierta el 79,27% de las veces
Realizamos la predicción con los datos de validación
predicval <- predict (Mdentrenamiento, newdata = validacion, type="response")
predicvalcodi<- ifelse (predicval > 0.5,1,0)
confusionMatrix(as.factor(validacion$Abandono), as.factor(predicvalcodi))
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 932 101
## 1 199 175
##
## Accuracy : 0.7868
## 95% CI : (0.7644, 0.8079)
## No Information Rate : 0.8038
## P-Value [Acc > NIR] : 0.9489
##
## Kappa : 0.4039
##
## Mcnemar's Test P-Value : 2.14e-08
##
## Sensitivity : 0.8240
## Specificity : 0.6341
## Pos Pred Value : 0.9022
## Neg Pred Value : 0.4679
## Prevalence : 0.8038
## Detection Rate : 0.6624
## Detection Prevalence : 0.7342
## Balanced Accuracy : 0.7291
##
## 'Positive' Class : 0
##
Con los datos de validación la exactitud ha disminuido de 79,27% a 78,68%.
ARBÓL DE DECISIÓN
library (rpart)
library (rpart.plot)
MArbolentre <- rpart (Abandono ~ as.factor(Contrato) + Factura_digital + as.factor(Servicio_Internet) + as.factor(Soporte_tecnico) + as.factor(CopiaSeguridad_Online) +
as.factor(Television_carta) + Meses_alta, data=entrenamiento, method ="class")
summary(MArbolentre)
## Call:
## rpart(formula = Abandono ~ as.factor(Contrato) + Factura_digital +
## as.factor(Servicio_Internet) + as.factor(Soporte_tecnico) +
## as.factor(CopiaSeguridad_Online) + as.factor(Television_carta) +
## Meses_alta, data = entrenamiento, method = "class")
## n= 5625
##
## CP nsplit rel error xerror xstd
## 1 0.07068004 0 1.0000000 1.0000000 0.02216119
## 2 0.01000000 3 0.7879599 0.7966555 0.02049516
##
## Variable importance
## as.factor(Contrato) Meses_alta
## 29 22
## as.factor(Servicio_Internet) as.factor(Soporte_tecnico)
## 14 13
## as.factor(CopiaSeguridad_Online) as.factor(Television_carta)
## 10 9
## Factura_digital
## 2
##
## Node number 1: 5625 observations, complexity param=0.07068004
## predicted class=0 expected loss=0.2657778 P(node) =1
## class counts: 4130 1495
## probabilities: 0.734 0.266
## left son=2 (2505 obs) right son=3 (3120 obs)
## Primary splits:
## as.factor(Contrato) splits as RLL, improve=350.9502, (0 missing)
## as.factor(Soporte_tecnico) splits as RLL, improve=239.1210, (0 missing)
## Meses_alta < 16.5 to the right, improve=238.6637, (0 missing)
## as.factor(Servicio_Internet) splits as LRL, improve=202.4936, (0 missing)
## as.factor(CopiaSeguridad_Online) splits as RLL, improve=153.7134, (0 missing)
## Surrogate splits:
## Meses_alta < 37.5 to the right, agree=0.789, adj=0.525, (0 split)
## as.factor(Soporte_tecnico) splits as RLL, agree=0.715, adj=0.360, (0 split)
## as.factor(CopiaSeguridad_Online) splits as RLL, agree=0.659, adj=0.234, (0 split)
## as.factor(Television_carta) splits as RLL, agree=0.634, adj=0.178, (0 split)
## as.factor(Servicio_Internet) splits as RRL, agree=0.619, adj=0.144, (0 split)
##
## Node number 2: 2505 observations
## predicted class=0 expected loss=0.06866267 P(node) =0.4453333
## class counts: 2333 172
## probabilities: 0.931 0.069
##
## Node number 3: 3120 observations, complexity param=0.07068004
## predicted class=0 expected loss=0.4240385 P(node) =0.5546667
## class counts: 1797 1323
## probabilities: 0.576 0.424
## left son=6 (1406 obs) right son=7 (1714 obs)
## Primary splits:
## as.factor(Servicio_Internet) splits as LRL, improve=111.16290, (0 missing)
## as.factor(Soporte_tecnico) splits as RLL, improve= 81.00356, (0 missing)
## Meses_alta < 5.5 to the right, improve= 60.96558, (0 missing)
## as.factor(CopiaSeguridad_Online) splits as RLR, improve= 54.74515, (0 missing)
## as.factor(Television_carta) splits as RLR, improve= 54.74515, (0 missing)
## Surrogate splits:
## as.factor(Soporte_tecnico) splits as RLL, agree=0.685, adj=0.302, (0 split)
## as.factor(CopiaSeguridad_Online) splits as RLR, agree=0.685, adj=0.300, (0 split)
## as.factor(Television_carta) splits as RLR, agree=0.685, adj=0.300, (0 split)
## Factura_digital splits as LR, agree=0.659, adj=0.243, (0 split)
## Meses_alta < 6.5 to the left, agree=0.594, adj=0.098, (0 split)
##
## Node number 6: 1406 observations
## predicted class=0 expected loss=0.2766714 P(node) =0.2499556
## class counts: 1017 389
## probabilities: 0.723 0.277
##
## Node number 7: 1714 observations, complexity param=0.07068004
## predicted class=1 expected loss=0.4550758 P(node) =0.3047111
## class counts: 780 934
## probabilities: 0.455 0.545
## left son=14 (945 obs) right son=15 (769 obs)
## Primary splits:
## Meses_alta < 13.5 to the right, improve=72.476800, (0 missing)
## as.factor(Soporte_tecnico) splits as R-L, improve=14.950820, (0 missing)
## Factura_digital splits as LR, improve= 8.897683, (0 missing)
## as.factor(CopiaSeguridad_Online) splits as R-L, improve= 7.151263, (0 missing)
## as.factor(Television_carta) splits as L-R, improve= 2.513415, (0 missing)
## Surrogate splits:
## as.factor(CopiaSeguridad_Online) splits as R-L, agree=0.609, adj=0.127, (0 split)
## as.factor(Television_carta) splits as R-L, agree=0.591, adj=0.088, (0 split)
##
## Node number 14: 945 observations
## predicted class=0 expected loss=0.4137566 P(node) =0.168
## class counts: 554 391
## probabilities: 0.586 0.414
##
## Node number 15: 769 observations
## predicted class=1 expected loss=0.2938882 P(node) =0.1367111
## class counts: 226 543
## probabilities: 0.294 0.706
rpart.plot (MArbolentre)
predictarbol <- predict(MArbolentre, type = "class")
confusionMatrix(as.factor(entrenamiento$Abandono), as.factor(predictarbol))
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 3904 226
## 1 952 543
##
## Accuracy : 0.7906
## 95% CI : (0.7797, 0.8011)
## No Information Rate : 0.8633
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.365
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.8040
## Specificity : 0.7061
## Pos Pred Value : 0.9453
## Neg Pred Value : 0.3632
## Prevalence : 0.8633
## Detection Rate : 0.6940
## Detection Prevalence : 0.7342
## Balanced Accuracy : 0.7550
##
## 'Positive' Class : 0
##
La exactitud del modelo es de 79,06% (Accuracy)
Realizamos la predicción con los datos de validación
predicarbolval <- predict (MArbolentre, newdata = validacion, type="class")
confusionMatrix(as.factor(validacion$Abandono), as.factor(predicarbolval))
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 973 60
## 1 244 130
##
## Accuracy : 0.7839
## 95% CI : (0.7615, 0.8052)
## No Information Rate : 0.865
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.3434
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.7995
## Specificity : 0.6842
## Pos Pred Value : 0.9419
## Neg Pred Value : 0.3476
## Prevalence : 0.8650
## Detection Rate : 0.6915
## Detection Prevalence : 0.7342
## Balanced Accuracy : 0.7419
##
## 'Positive' Class : 0
##
La exactitud del modelo con los datos de validación bajo de 79,06% a 78,39%.
Si bien la diferencia entre el accuracy de los dos modelos realizados no es alta, el modelo logit tiene mayor precisión tanto en el modelo de entrenamiento como en el modelo de validación.
Adicional, para obtener una clasificación de la importancia de las variables, se puede analizar la correlación con el fin de identificar aquellas que están completamente relacionadas y que pueden generar multicolinealidad dentro del modelo. Por otra parte, una técnica que también se utiliza en la práctica es Análisis de Componentes Principales que permite reducir la dimensionalidad, es decir, simplificar la base de datos, y así elegir un menor número de predictores (variables independientes) para pronosticar una variable objetivo (variable dependiente).