Datos a utilizar

Se utilizará el archivo transact_v2.txt que se construyó a partir de transacciones de compra durante el mes de abril de 2019 y que contiene los siguientes campos y criterios:

library (ISLR)
library (MASS)
library(data.table)
library(caret)
## Loading required package: lattice
## Loading required package: ggplot2
library(e1071)
library(corrplot)
## corrplot 0.84 loaded
library(RColorBrewer)


# datos <-data.frame(read_delim("C:/Users/milaronix/Desktop/transact_v2.txt", 
#     "|", escape_double = FALSE, trim_ws = TRUE))

datos <- fread(text = "C:/Users/milaronix/Desktop/transact_v2.txt")
datos$COMPRA_MANIANA <-  as.factor(datos$COMPRA_MANIANA)
levels(datos$COMPRA_MANIANA) <- c("NO","SI")

head(datos)
##         FECHA NUM_TELEFONO DISTANCIA_FIN_MES DISTANCIA_PROXIMA_QUINCENA
## 1: 2019-04-01        ID_ 6                29                         14
## 2: 2019-04-01       ID_ 10                29                         14
## 3: 2019-04-01       ID_ 23                29                         14
## 4: 2019-04-01       ID_ 26                29                         14
## 5: 2019-04-01       ID_ 32                29                         14
## 6: 2019-04-01       ID_ 47                29                         14
##    RESENCIA FRECUENCIA MONTO MEDIA_DIAS_INTER MAX_DIAS_INTER
## 1:        2          1    20         0.000000              0
## 2:       11          1    20         0.000000              0
## 3:        0         15   100         2.071429              4
## 4:        6          8    60         3.428571              7
## 5:       20          2    35         4.000000              4
## 6:        2          1    10         0.000000              0
##    MIN_DIAS_INTER COMPRA_MANIANA MTO_PAQ_MANIANA CNT_PAQ_MANIANA
## 1:              0             NO               0               0
## 2:              0             NO               0               0
## 3:              1             NO               0               0
## 4:              1             NO               0               0
## 5:              4             NO               0               0
## 6:              0             NO               0               0
str(datos)
## Classes 'data.table' and 'data.frame':   6105998 obs. of  13 variables:
##  $ FECHA                     : chr  "2019-04-01" "2019-04-01" "2019-04-01" "2019-04-01" ...
##  $ NUM_TELEFONO              : chr  "ID_ 6" "ID_ 10" "ID_ 23" "ID_ 26" ...
##  $ DISTANCIA_FIN_MES         : int  29 29 29 29 29 29 29 29 29 29 ...
##  $ DISTANCIA_PROXIMA_QUINCENA: int  14 14 14 14 14 14 14 14 14 14 ...
##  $ RESENCIA                  : int  2 11 0 6 20 2 25 1 23 1 ...
##  $ FRECUENCIA                : int  1 1 15 8 2 1 1 30 3 4 ...
##  $ MONTO                     : num  20 20 100 60 35 10 10 450 20 120 ...
##  $ MEDIA_DIAS_INTER          : num  0 0 2.07 3.43 4 ...
##  $ MAX_DIAS_INTER            : int  0 0 4 7 4 0 0 1 5 8 ...
##  $ MIN_DIAS_INTER            : int  0 0 1 1 4 0 0 1 1 8 ...
##  $ COMPRA_MANIANA            : Factor w/ 2 levels "NO","SI": 1 1 1 1 1 1 1 1 1 1 ...
##  $ MTO_PAQ_MANIANA           : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ CNT_PAQ_MANIANA           : int  0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, ".internal.selfref")=<externalptr>
summary(datos)
##     FECHA           NUM_TELEFONO       DISTANCIA_FIN_MES
##  Length:6105998     Length:6105998     Min.   : 0.00    
##  Class :character   Class :character   1st Qu.: 7.00    
##  Mode  :character   Mode  :character   Median :14.00    
##                                        Mean   :14.43    
##                                        3rd Qu.:22.00    
##                                        Max.   :29.00    
##  DISTANCIA_PROXIMA_QUINCENA    RESENCIA        FRECUENCIA     
##  Min.   : 0.00              Min.   : 0.000   Min.   :  1.000  
##  1st Qu.: 7.00              1st Qu.: 1.000   1st Qu.:  1.000  
##  Median :15.00              Median : 4.000   Median :  3.000  
##  Mean   :14.53              Mean   : 7.922   Mean   :  5.301  
##  3rd Qu.:22.00              3rd Qu.:13.000   3rd Qu.:  7.000  
##  Max.   :29.00              Max.   :30.000   Max.   :111.000  
##      MONTO         MEDIA_DIAS_INTER  MAX_DIAS_INTER   MIN_DIAS_INTER  
##  Min.   :   0.00   Min.   : 0.0000   Min.   : 0.000   Min.   : 0.000  
##  1st Qu.:  10.00   1st Qu.: 0.0000   1st Qu.: 0.000   1st Qu.: 0.000  
##  Median :  35.00   Median : 0.6897   Median : 3.000   Median : 0.000  
##  Mean   :  56.82   Mean   : 2.2567   Mean   : 4.466   Mean   : 1.295  
##  3rd Qu.:  90.00   3rd Qu.: 3.2857   3rd Qu.: 7.000   3rd Qu.: 1.000  
##  Max.   :1600.00   Max.   :34.0000   Max.   :34.000   Max.   :34.000  
##  COMPRA_MANIANA MTO_PAQ_MANIANA   CNT_PAQ_MANIANA 
##  NO:5183627     Min.   :  0.000   Min.   :0.0000  
##  SI: 922371     1st Qu.:  0.000   1st Qu.:0.0000  
##                 Median :  0.000   Median :0.0000  
##                 Mean   :  1.693   Mean   :0.1584  
##                 3rd Qu.:  0.000   3rd Qu.:0.0000  
##                 Max.   :390.000   Max.   :8.0000

Separando datos de entrenamiento y prueba

Se dividirán los datos buscando mantener la relación de las variables FECHA y COMPRA_MANIANA en proporciones de 30% para train y 70% para test

temp <- as.factor(paste(datos$FECHA,datos$COMPRA_MANIANA))

indice_train <-
  createDataPartition(temp,
                      p = 0.3,
                      list = F)

train <- datos[indice_train,]
table(train$FECHA,train$COMPRA_MANIANA)
##             
##                 NO    SI
##   2019-04-01 51073  9261
##   2019-04-02 51410  8837
##   2019-04-03 51582  8737
##   2019-04-04 50320 10000
##   2019-04-05 50222 10169
##   2019-04-06 52359  8259
##   2019-04-07 50928  9700
##   2019-04-08 51628  8947
##   2019-04-09 51470  8997
##   2019-04-10 51680  8928
##   2019-04-11 50612 10099
##   2019-04-12 50599 10282
##   2019-04-13 52755  8417
##   2019-04-14 51157 10080
##   2019-04-15 51153 10053
##   2019-04-16 50782 10430
##   2019-04-17 52740  8789
##   2019-04-18 53915  7741
##   2019-04-19 53812  7654
##   2019-04-20 53389  7906
##   2019-04-21 51028 10053
##   2019-04-22 51952  9185
##   2019-04-23 52392  8709
##   2019-04-24 52536  8780
##   2019-04-25 51398 10027
##   2019-04-26 51386 10215
##   2019-04-27 53568  8309
##   2019-04-28 53151  8737
##   2019-04-29 51574 10209
##   2019-04-30 52530  9212
test <- datos[-indice_train,]
table(test$FECHA,test$COMPRA_MANIANA)
##             
##                  NO     SI
##   2019-04-01 119169  21609
##   2019-04-02 119955  20619
##   2019-04-03 120355  20385
##   2019-04-04 117411  23333
##   2019-04-05 117184  23727
##   2019-04-06 122169  19271
##   2019-04-07 118831  22631
##   2019-04-08 120465  20876
##   2019-04-09 120095  20991
##   2019-04-10 120586  20832
##   2019-04-11 118094  23563
##   2019-04-12 118064  23990
##   2019-04-13 123092  19638
##   2019-04-14 119365  23519
##   2019-04-15 119355  23456
##   2019-04-16 118491  24336
##   2019-04-17 123059  20506
##   2019-04-18 125800  18060
##   2019-04-19 125561  17858
##   2019-04-20 124573  18447
##   2019-04-21 119063  23456
##   2019-04-22 121220  21430
##   2019-04-23 122247  20318
##   2019-04-24 122583  20486
##   2019-04-25 119927  23395
##   2019-04-26 119899  23835
##   2019-04-27 124990  19385
##   2019-04-28 124017  20385
##   2019-04-29 120337  23819
##   2019-04-30 122569  21493
indice_paint <-
  createDataPartition(temp,
                      p = 0.01,
                      list = F)
paint <- datos[indice_paint,]

Comprendiendo los datos

Se creo un subset de datos llamado paint que representa el 1% de los datos para evaluar de forma grafica las variables a utilizar

ggplot(data = paint, aes(x = RESENCIA, fill = COMPRA_MANIANA)) +
      geom_histogram(position = "identity", alpha = 0.5)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(data = paint, aes(x = FRECUENCIA, fill = COMPRA_MANIANA)) +
      geom_histogram(position = "identity", alpha = 0.5)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(data = paint, aes(x = MONTO, fill = COMPRA_MANIANA)) +
      geom_histogram(position = "identity", alpha = 0.5)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(data = paint, aes(x = MEDIA_DIAS_INTER, fill = COMPRA_MANIANA)) +
      geom_histogram(position = "identity", alpha = 0.5)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

pairs(x = paint[, c("RESENCIA","FRECUENCIA","MONTO")],
      col = c("firebrick", "green3")[paint$COMPRA_MANIANA], pch = 19)

correlacion <- cor(paint[,3:10])
corrplot(
  correlacion,
  type = "upper",
  order = "hclust",
  col=brewer.pal(n=8, name="RdYlBu")
)

Logistic Regresssion

glm.fit <- glm(
  formula = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER ,
  data = train ,
  family = binomial
)

summary (glm.fit)
## 
## Call:
## glm(formula = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + 
##     DISTANCIA_FIN_MES + MEDIA_DIAS_INTER, family = binomial, 
##     data = train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -4.4934  -0.5563  -0.4058  -0.2534   2.8442  
## 
## Coefficients:
##                     Estimate Std. Error  z value Pr(>|z|)    
## (Intercept)       -2.332e+00  6.612e-03 -352.721   <2e-16 ***
## RESENCIA          -5.539e-02  4.592e-04 -120.622   <2e-16 ***
## FRECUENCIA         1.418e-01  5.561e-04  254.943   <2e-16 ***
## MONTO             -8.987e-04  5.507e-05  -16.318   <2e-16 ***
## DISTANCIA_FIN_MES -2.924e-03  2.943e-04   -9.938   <2e-16 ***
## MEDIA_DIAS_INTER   2.033e-02  7.607e-04   26.725   <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: 1555400  on 1831822  degrees of freedom
## Residual deviance: 1298397  on 1831817  degrees of freedom
## AIC: 1298409
## 
## Number of Fisher Scoring iterations: 6
coef(glm.fit)
##       (Intercept)          RESENCIA        FRECUENCIA             MONTO 
##      -2.332349502      -0.055389972       0.141764581      -0.000898664 
## DISTANCIA_FIN_MES  MEDIA_DIAS_INTER 
##      -0.002924373       0.020328794
glm.prob =predict(glm.fit,  train, type ="response")
contrasts(datos$COMPRA_MANIANA)
##    SI
## NO  0
## SI  1

el parametro type = “response” hace que r nos devuelva un probabilidad de la forma P(Y = 1|X). la función contrasts() nos indica que r creó una variable genérica con 1 para COMPRA_MANIANA = SI.

En este caso cosideraremos como “SI” los registros con una probabilidad >0.5

glm.pred=rep("NO" ,nrow(train))
glm.pred[glm.prob > .5]="SI"
glm.pred <- as.factor(glm.pred)

confusionMatrix(table(glm.pred, train$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##         
## glm.pred      NO      SI
##       NO 1525183  229064
##       SI   29918   47658
##                                           
##                Accuracy : 0.8586          
##                  95% CI : (0.8581, 0.8591)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.2172          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.17222         
##             Specificity : 0.98076         
##          Pos Pred Value : 0.61434         
##          Neg Pred Value : 0.86942         
##              Prevalence : 0.15106         
##          Detection Rate : 0.02602         
##    Detection Prevalence : 0.04235         
##       Balanced Accuracy : 0.57649         
##                                           
##        'Positive' Class : SI              
## 

El modelo nos devuelve 85.84% de exactitud general pero se está comportando mejor para predecir a alguien que NO va consumir (98% exactitud) que para alguien que SI va a consumir (17%)

LDA

lda.fit <-
  lda(
    formula = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER,
    data = train
  )

lda.fit
## Call:
## lda(COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + 
##     MEDIA_DIAS_INTER, data = train)
## 
## Prior probabilities of groups:
##        NO        SI 
## 0.8489363 0.1510637 
## 
## Group means:
##    RESENCIA FRECUENCIA    MONTO DISTANCIA_FIN_MES MEDIA_DIAS_INTER
## NO 8.743995   4.350988 50.12946          14.41565         2.261214
## SI 3.287617  10.637636 94.54670          14.53273         2.243870
## 
## Coefficients of linear discriminants:
##                             LD1
## RESENCIA          -0.0164226412
## FRECUENCIA         0.1952055343
## MONTO             -0.0018099931
## DISTANCIA_FIN_MES -0.0002514424
## MEDIA_DIAS_INTER   0.0059080612
plot(lda.fit)

lda.pred = predict(lda.fit , train)

confusionMatrix(table(lda.pred$class, train$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##     
##           NO      SI
##   NO 1495556  206828
##   SI   59545   69894
##                                           
##                Accuracy : 0.8546          
##                  95% CI : (0.8541, 0.8551)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.2743          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.25258         
##             Specificity : 0.96171         
##          Pos Pred Value : 0.53998         
##          Neg Pred Value : 0.87851         
##              Prevalence : 0.15106         
##          Detection Rate : 0.03816         
##    Detection Prevalence : 0.07066         
##       Balanced Accuracy : 0.60714         
##                                           
##        'Positive' Class : SI              
## 

El modelo nos devuelve 85.43% de exactitud general (levemente menor a la regresión) y se repite el escenario de que se está comportando mejor para predecir a alguien que NO va consumir (96% de aciertos) que para alguien que SI va a consumir (25% de aciertos), es decir que se comporta mejor que la regresión.

QDA

qda.fit = qda(
  formula = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER,
  data = train
)

qda.fit
## Call:
## qda(COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + 
##     MEDIA_DIAS_INTER, data = train)
## 
## Prior probabilities of groups:
##        NO        SI 
## 0.8489363 0.1510637 
## 
## Group means:
##    RESENCIA FRECUENCIA    MONTO DISTANCIA_FIN_MES MEDIA_DIAS_INTER
## NO 8.743995   4.350988 50.12946          14.41565         2.261214
## SI 3.287617  10.637636 94.54670          14.53273         2.243870
qda.pred <- predict(qda.fit,train)

confusionMatrix(table(qda.pred$class, train$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##     
##           NO      SI
##   NO 1441147  179413
##   SI  113954   97309
##                                           
##                Accuracy : 0.8398          
##                  95% CI : (0.8393, 0.8404)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.3084          
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.35165         
##             Specificity : 0.92672         
##          Pos Pred Value : 0.46061         
##          Neg Pred Value : 0.88929         
##              Prevalence : 0.15106         
##          Detection Rate : 0.05312         
##    Detection Prevalence : 0.11533         
##       Balanced Accuracy : 0.63919         
##                                           
##        'Positive' Class : SI              
## 

El modelo nos devuelve 83.98% de exactitud general (el más bajo de los 3 hasta el momento) pero mejora considerablemente reduciendo los falsos positivos y ahora tenemos un ratio de 35% para los positivos reales y los negativos reales quedan en 92%, conviertiendo al modelo en el mejor hasta el momento.

DownSample

Si revisamos la distribución vemos que se mantiene una tendencia de SI = 15% y NO = 85% en promedio para cada una de las fechas que estamos trabajando, una opción para intentar mejorar los resultados es hacer un SubSampling y en este caso he elegido Down-Sampling que consiste en reducir las observaciones de la etiqueta con mayor frequencia para igualarla a la que tiene menos observaciones, buscando una relación de 50% - 50%.

train.ds <- downSample(train,
           train$COMPRA_MANIANA,
           list = TRUE)$x

table(train.ds$FECHA,train.ds$COMPRA_MANIANA)
##             
##                 NO    SI
##   2019-04-01  9123  9261
##   2019-04-02  9189  8837
##   2019-04-03  9145  8737
##   2019-04-04  8799 10000
##   2019-04-05  8900 10169
##   2019-04-06  9329  8259
##   2019-04-07  9061  9700
##   2019-04-08  9240  8947
##   2019-04-09  9339  8997
##   2019-04-10  9091  8928
##   2019-04-11  9047 10099
##   2019-04-12  9026 10282
##   2019-04-13  9350  8417
##   2019-04-14  9233 10080
##   2019-04-15  9200 10053
##   2019-04-16  8986 10430
##   2019-04-17  9389  8789
##   2019-04-18  9429  7741
##   2019-04-19  9530  7654
##   2019-04-20  9574  7906
##   2019-04-21  9141 10053
##   2019-04-22  9370  9185
##   2019-04-23  9218  8709
##   2019-04-24  9463  8780
##   2019-04-25  9105 10027
##   2019-04-26  8984 10215
##   2019-04-27  9427  8309
##   2019-04-28  9457  8737
##   2019-04-29  9116 10209
##   2019-04-30  9461  9212
qda.fit = qda(
  formula = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER,
  data = train.ds
)

qda.fit
## Call:
## qda(COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + 
##     MEDIA_DIAS_INTER, data = train.ds)
## 
## Prior probabilities of groups:
##  NO  SI 
## 0.5 0.5 
## 
## Group means:
##    RESENCIA FRECUENCIA   MONTO DISTANCIA_FIN_MES MEDIA_DIAS_INTER
## NO 8.731424   4.350894 50.0626          14.42057         2.259016
## SI 3.287617  10.637636 94.5467          14.53273         2.243870
qda.pred <- predict(qda.fit,train.ds)

confusionMatrix(table(qda.pred$class, train.ds$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##     
##          NO     SI
##   NO 189406  74681
##   SI  87316 202041
##                                           
##                Accuracy : 0.7073          
##                  95% CI : (0.7061, 0.7085)
##     No Information Rate : 0.5             
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.4146          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.7301          
##             Specificity : 0.6845          
##          Pos Pred Value : 0.6982          
##          Neg Pred Value : 0.7172          
##              Prevalence : 0.5000          
##          Detection Rate : 0.3651          
##    Detection Prevalence : 0.5228          
##       Balanced Accuracy : 0.7073          
##                                           
##        'Positive' Class : SI              
## 

La exactitud general del modelo se reduce a 70.7% pero ahora los positivos reales tienen un ratio de 73% y los negativos reales tienen un 68% que es mucho mejor que cualquiera de los resultados anteriores.

Ahora realizaremos la predicción utilizando este modelo sobre los datos test que creamos anteriormente.

qda.pred <- predict(qda.fit,test)

confusionMatrix(table(qda.pred$class, test$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##     
##           NO      SI
##   NO 2481467  174545
##   SI 1147059  471104
##                                           
##                Accuracy : 0.6908          
##                  95% CI : (0.6904, 0.6912)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.2554          
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.7297          
##             Specificity : 0.6839          
##          Pos Pred Value : 0.2911          
##          Neg Pred Value : 0.9343          
##              Prevalence : 0.1511          
##          Detection Rate : 0.1102          
##    Detection Prevalence : 0.3786          
##       Balanced Accuracy : 0.7068          
##                                           
##        'Positive' Class : SI              
## 

La tendencia de los positivos y negativos reales se mantienen pero hay un deterioro muy fuerte en los falsos positivos.

QDA utilizando la libreria caret

Con la libreria caret y la función train podemos encontrar la posibilidad de particionar nuestros datos utilizando k-fold cross validation utilizando el mismo modelo QDA que utilizamos anteriormente.

getModelInfo("qda")
## $qda
## $qda$label
## [1] "Quadratic Discriminant Analysis"
## 
## $qda$library
## [1] "MASS"
## 
## $qda$loop
## NULL
## 
## $qda$type
## [1] "Classification"
## 
## $qda$parameters
##   parameter     class     label
## 1 parameter character parameter
## 
## $qda$grid
## function (x, y, len = NULL, search = "grid") 
## data.frame(parameter = "none")
## 
## $qda$fit
## function (x, y, wts, param, lev, last, classProbs, ...) 
## MASS::qda(x, y, ...)
## 
## $qda$predict
## function (modelFit, newdata, submodels = NULL) 
## predict(modelFit, newdata)$class
## 
## $qda$prob
## function (modelFit, newdata, submodels = NULL) 
## predict(modelFit, newdata)$posterior
## 
## $qda$predictors
## function (x, ...) 
## if (hasTerms(x)) predictors(x$terms) else colnames(x$means)
## 
## $qda$tags
## [1] "Discriminant Analysis" "Polynomial Model"     
## 
## $qda$levels
## function (x) 
## names(x$prior)
## 
## $qda$sort
## function (x) 
## x
train_control <-
  trainControl(
    method = "cv",
    number = 10,
    savePredictions = TRUE,
    p = 0.95
  )

qda.fit <-
  train(form = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER
    ,data = datos,
    method = "qda"
    ,trControl = train_control
  )

qda.fit
## Quadratic Discriminant Analysis 
## 
## 6105998 samples
##       5 predictor
##       2 classes: 'NO', 'SI' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 5495398, 5495399, 5495399, 5495398, 5495398, 5495399, ... 
## Resampling results:
## 
##   Accuracy   Kappa   
##   0.8397056  0.308114
qda.pred <- predict(qda.fit,datos)
confusionMatrix(table(qda.pred, datos$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##         
## qda.pred      NO      SI
##       NO 4802746  597875
##       SI  380881  324496
##                                         
##                Accuracy : 0.8397        
##                  95% CI : (0.8394, 0.84)
##     No Information Rate : 0.8489        
##     P-Value [Acc > NIR] : 1             
##                                         
##                   Kappa : 0.3081        
##                                         
##  Mcnemar's Test P-Value : <2e-16        
##                                         
##             Sensitivity : 0.35181       
##             Specificity : 0.92652       
##          Pos Pred Value : 0.46003       
##          Neg Pred Value : 0.88930       
##              Prevalence : 0.15106       
##          Detection Rate : 0.05314       
##    Detection Prevalence : 0.11552       
##       Balanced Accuracy : 0.63916       
##                                         
##        'Positive' Class : SI            
## 
qda.pred <- predict(qda.fit,test)
confusionMatrix(table(qda.pred, test$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##         
## qda.pred      NO      SI
##       NO 3361772  418444
##       SI  266754  227205
##                                         
##                Accuracy : 0.8397        
##                  95% CI : (0.8393, 0.84)
##     No Information Rate : 0.8489        
##     P-Value [Acc > NIR] : 1             
##                                         
##                   Kappa : 0.3081        
##                                         
##  Mcnemar's Test P-Value : <2e-16        
##                                         
##             Sensitivity : 0.35190       
##             Specificity : 0.92648       
##          Pos Pred Value : 0.45997       
##          Neg Pred Value : 0.88931       
##              Prevalence : 0.15106       
##          Detection Rate : 0.05316       
##    Detection Prevalence : 0.11557       
##       Balanced Accuracy : 0.63919       
##                                         
##        'Positive' Class : SI            
## 

La exactitud del modelo es de 84.96% que es mucho mejor pero el inconveniente se refleja en los falsos positivos que está prediciendo el modelo y que nos deja solo con el 35% de positivos reales predichos.

Anteriormente realizar Down Sampling nos ayudó a mejorar el desempeno, veamos que sucede al combinarlo con 10-fold CV.

datos.ds <- downSample(datos,
           datos$COMPRA_MANIANA,
           list = TRUE)$x

table(datos.ds$FECHA,datos.ds$COMPRA_MANIANA)
##             
##                 NO    SI
##   2019-04-01 30503 30870
##   2019-04-02 30588 29456
##   2019-04-03 30797 29122
##   2019-04-04 29643 33333
##   2019-04-05 30063 33896
##   2019-04-06 31209 27530
##   2019-04-07 30342 32331
##   2019-04-08 30548 29823
##   2019-04-09 30448 29988
##   2019-04-10 30664 29760
##   2019-04-11 30051 33662
##   2019-04-12 29971 34272
##   2019-04-13 31218 28055
##   2019-04-14 30248 33599
##   2019-04-15 30341 33509
##   2019-04-16 30310 34766
##   2019-04-17 31380 29295
##   2019-04-18 31918 25801
##   2019-04-19 31608 25512
##   2019-04-20 31564 26353
##   2019-04-21 30104 33509
##   2019-04-22 30950 30615
##   2019-04-23 30978 29027
##   2019-04-24 31250 29266
##   2019-04-25 30605 33422
##   2019-04-26 30417 34050
##   2019-04-27 31665 27694
##   2019-04-28 31585 29122
##   2019-04-29 30502 34028
##   2019-04-30 30901 30705
qda.fit <-
  train(form = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER
    ,data = datos.ds,
    method = "qda"
    ,trControl = train_control
  )

qda.fit
## Quadratic Discriminant Analysis 
## 
## 1844742 samples
##       5 predictor
##       2 classes: 'NO', 'SI' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 1660267, 1660268, 1660268, 1660268, 1660268, 1660268, ... 
## Resampling results:
## 
##   Accuracy   Kappa   
##   0.7063595  0.412719
qda.pred <- predict(qda.fit,datos.ds)
confusionMatrix(table(qda.pred, datos.ds$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##         
## qda.pred     NO     SI
##       NO 632044 251275
##       SI 290327 671096
##                                           
##                Accuracy : 0.7064          
##                  95% CI : (0.7057, 0.7071)
##     No Information Rate : 0.5             
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.4128          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.7276          
##             Specificity : 0.6852          
##          Pos Pred Value : 0.6980          
##          Neg Pred Value : 0.7155          
##              Prevalence : 0.5000          
##          Detection Rate : 0.3638          
##    Detection Prevalence : 0.5212          
##       Balanced Accuracy : 0.7064          
##                                           
##        'Positive' Class : SI              
## 
qda.pred <- predict(qda.fit,test)
confusionMatrix(table(qda.pred, test$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##         
## qda.pred      NO      SI
##       NO 2486841  176008
##       SI 1141685  469641
##                                           
##                Accuracy : 0.6917          
##                  95% CI : (0.6913, 0.6921)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.2556          
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.7274          
##             Specificity : 0.6854          
##          Pos Pred Value : 0.2915          
##          Neg Pred Value : 0.9339          
##              Prevalence : 0.1511          
##          Detection Rate : 0.1099          
##    Detection Prevalence : 0.3770          
##       Balanced Accuracy : 0.7064          
##                                           
##        'Positive' Class : SI              
## 

Al comprobar los datos con el dataset completo la exactitud total baja a 70.69% y con 69.95% de positivos reales, pero al utilizar el subset de datos test que generamos antes y probar este fit nuestros positivos reales bajan a solo del 29.25%

C5.0 TREE

Por último probaremos con un arból C5.0 que también se encuentra disponible en el paquete caret

train_control <-
  trainControl(
    method = "cv",
    number = 3,
    returnResamp = "all",
    classProbs = TRUE,
    search = "random"
  )

tree.fit <-
  train(
    form = COMPRA_MANIANA ~ RESENCIA + FRECUENCIA + MONTO + DISTANCIA_FIN_MES + MEDIA_DIAS_INTER
    ,data = paint
    ,method = 'C5.0'
    ,trControl = train_control
    # ,metric = "ROC" 
    ,control = C50::C5.0Control(seed = 1)
    ,preProc = c("center", "scale")
  )
## Warning: 'trials' should be <= 14 for this object. Predictions generated
## using 14 trials

## Warning: 'trials' should be <= 14 for this object. Predictions generated
## using 14 trials
## Warning: 'trials' should be <= 12 for this object. Predictions generated
## using 12 trials

## Warning: 'trials' should be <= 12 for this object. Predictions generated
## using 12 trials
## Warning: 'trials' should be <= 11 for this object. Predictions generated
## using 11 trials

## Warning: 'trials' should be <= 11 for this object. Predictions generated
## using 11 trials
summary(tree.fit)
## 
## Call:
## (function (x, y, trials = 1, rules = FALSE, weights = NULL, control
##  2.13208243150645, -0.700539714378625,
##  -0.346461946142992, -0.464487868888203, 0.00761582209264246, -0.8185
## 
## 
## C5.0 [Release 2.07 GPL Edition]      Thu Jul 04 23:48:01 2019
## -------------------------------
## 
## Class specified by attribute `outcome'
## 
## Read 61091 cases (6 attributes) from undefined.data
## 
## 2 attributes winnowed
## Estimated importance of remaining attributes:
## 
##       9%  FRECUENCIA
##       2%  RESENCIA
##      <1%  DISTANCIA_FIN_MES
## 
## -----  Trial 0:  -----
## 
## Rules:
## 
## Rule 0/1: (33888/2792, lift 1.1)
##  RESENCIA > -0.5825138
##  ->  class NO  [0.918]
## 
## Rule 0/2: (59104/7938, lift 1.0)
##  FRECUENCIA <= 2.466804
##  ->  class NO  [0.866]
## 
## Rule 0/3: (1276/490, lift 4.1)
##  RESENCIA > -0.9365916
##  RESENCIA <= -0.5825138
##  FRECUENCIA > 1.747467
##  ->  class SI  [0.616]
## 
## Rule 0/4: (3682/1599, lift 3.7)
##  FRECUENCIA > 1.747467
##  ->  class SI  [0.566]
## 
## Default class: NO
## 
## -----  Trial 1:  -----
## 
## Rules:
## 
## Rule 1/1: (19511/2252.9, lift 1.3)
##  RESENCIA > -0.1104101
##  ->  class NO  [0.884]
## 
## Rule 1/2: (43020/9253.7, lift 1.1)
##  FRECUENCIA <= 0.3087949
##  ->  class NO  [0.785]
## 
## Rule 1/3: (18071/8617.4, lift 1.7)
##  FRECUENCIA > 0.3087949
##  ->  class SI  [0.523]
## 
## Default class: NO
## 
## -----  Trial 2:  -----
## 
## Rules:
## 
## Rule 2/1: (10574.6/1080.9, lift 1.3)
##  RESENCIA > 0.5977454
##  ->  class NO  [0.898]
## 
## Rule 2/2: (2163.3/609.1, lift 1.1)
##  RESENCIA > -0.9365916
##  FRECUENCIA > 1.747467
##  ->  class NO  [0.718]
## 
## Rule 2/3: (50368.4/15032.6, lift 1.0)
##  FRECUENCIA <= 1.028131
##  ->  class NO  [0.702]
## 
## Rule 2/4: (11877.4/3919.2, lift 1.0)
##  RESENCIA <= -0.9365916
##  ->  class NO  [0.670]
## 
## Rule 2/5: (3304.2/1539.8, lift 1.7)
##  RESENCIA > -0.9365916
##  RESENCIA <= 0.5977454
##  FRECUENCIA > 1.028131
##  FRECUENCIA <= 1.747467
##  ->  class SI  [0.534]
## 
## Default class: NO
## 
## -----  Trial 3:  -----
## 
## Rules:
## 
## Rule 3/1: (59994.8/23457.7, lift 1.0)
##  FRECUENCIA <= 3.545808
##  ->  class NO  [0.609]
## 
## Rule 3/2: (1092.8/416.7, lift 1.6)
##  RESENCIA <= -0.4644879
##  FRECUENCIA > 3.545808
##  ->  class SI  [0.618]
## 
## Rule 3/3: (7458.4/3227.9, lift 1.4)
##  RESENCIA > -0.4644879
##  RESENCIA <= 0.7157714
##  FRECUENCIA > -0.4105413
##  ->  class SI  [0.567]
## 
## Rule 3/4: (13216.3/5871, lift 1.4)
##  RESENCIA > -0.9365916
##  RESENCIA <= 0.7157714
##  FRECUENCIA > -0.05087316
##  FRECUENCIA <= 1.028131
##  ->  class SI  [0.556]
## 
## Rule 3/5: (21014.9/9597.6, lift 1.4)
##  RESENCIA > -0.9365916
##  RESENCIA <= 0.7157714
##  FRECUENCIA > -0.4105413
##  FRECUENCIA <= 1.028131
##  ->  class SI  [0.543]
## 
## Default class: NO
## 
## -----  Trial 4:  -----
## 
## Rules:
## 
## Rule 4/1: (13907.1/2892.1, lift 1.3)
##  RESENCIA > 0.007615822
##  ->  class NO  [0.792]
## 
## Rule 4/2: (52263/19763.5, lift 1.0)
##  FRECUENCIA <= 1.387799
##  ->  class NO  [0.622]
## 
## Rule 4/3: (8777.6/3980.8, lift 1.4)
##  RESENCIA <= 0.007615822
##  FRECUENCIA > 1.387799
##  ->  class SI  [0.546]
## 
## Default class: NO
## 
## -----  Trial 5:  -----
## 
## Rules:
## 
## Rule 5/1: (14657.9/3781.5, lift 1.3)
##  RESENCIA > -0.1104101
##  ->  class NO  [0.742]
## 
## Rule 5/2: (25244/8769.5, lift 1.2)
##  FRECUENCIA <= -0.2307072
##  ->  class NO  [0.653]
## 
## Rule 5/3: (28527.1/12135.9, lift 1.0)
##  DISTANCIA_FIN_MES <= -0.1656509
##  ->  class NO  [0.575]
## 
## Rule 5/4: (4514.6/1837.1, lift 1.4)
##  RESENCIA > -0.346462
##  RESENCIA <= -0.1104101
##  FRECUENCIA > -0.7702094
##  ->  class SI  [0.593]
## 
## Rule 5/5: (10615.3/4669.6, lift 1.3)
##  RESENCIA <= -0.1104101
##  FRECUENCIA > -0.2307072
##  FRECUENCIA <= 0.3087949
##  ->  class SI  [0.560]
## 
## Rule 5/6: (43123.3/21302.5, lift 1.2)
##  RESENCIA <= -0.1104101
##  FRECUENCIA > -0.7702094
##  ->  class SI  [0.506]
## 
## Default class: NO
## 
## -----  Trial 6:  -----
## 
## Rules:
## 
## Rule 6/1: (10061.5/2243.4, lift 1.4)
##  FRECUENCIA <= -0.7702094
##  ->  class NO  [0.777]
## 
## Rule 6/2: (12586.3/3325.7, lift 1.3)
##  RESENCIA > 0.007615822
##  ->  class NO  [0.736]
## 
## Rule 6/3: (40606.1/17074.7, lift 1.0)
##  DISTANCIA_FIN_MES > -0.6279472
##  ->  class NO  [0.579]
## 
## Rule 6/4: (14976.2/7288.5, lift 1.2)
##  RESENCIA <= 0.007615822
##  FRECUENCIA > -0.7702094
##  DISTANCIA_FIN_MES <= -0.6279472
##  ->  class SI  [0.513]
## 
## Default class: NO
## 
## -----  Trial 7:  -----
## 
## Rules:
## 
## Rule 7/1: (7424/1672, lift 1.4)
##  RESENCIA > 0.5977454
##  ->  class NO  [0.775]
## 
## Rule 7/2: (9627.3/2324.4, lift 1.4)
##  FRECUENCIA <= -0.7702094
##  ->  class NO  [0.759]
## 
## Rule 7/3: (26854.8/11228.2, lift 1.0)
##  DISTANCIA_FIN_MES <= -0.281225
##  ->  class NO  [0.582]
## 
## Rule 7/4: (27289.8/13513.1, lift 1.2)
##  RESENCIA <= 0.5977454
##  FRECUENCIA > -0.7702094
##  DISTANCIA_FIN_MES > -0.281225
##  ->  class SI  [0.505]
## 
## Default class: NO
## 
## -----  Trial 8:  -----
## 
## Rules:
## 
## Rule 8/1: (59426.7/25497.4, lift 1.0)
##  FRECUENCIA <= 3.18614
##  ->  class NO  [0.571]
## 
## Rule 8/2: (1664.3/748, lift 1.3)
##  FRECUENCIA > 3.18614
##  ->  class SI  [0.550]
## 
## Default class: NO
## 
## -----  Trial 9:  -----
## 
## Rules:
## 
## Rule 9/1: (6886.6/1802.9, lift 1.4)
##  RESENCIA > 0.5977454
##  ->  class NO  [0.738]
## 
## Rule 9/2: (54204.4/26636.4, lift 1.0)
##  RESENCIA <= 0.5977454
##  ->  class NO  [0.509]
## 
## Rule 9/3: (13031.8/5955.1, lift 1.2)
##  RESENCIA <= -0.7005397
##  FRECUENCIA > 0.8482971
##  ->  class SI  [0.543]
## 
## Rule 9/4: (20225/9603, lift 1.1)
##  RESENCIA > -0.8185657
##  RESENCIA <= 0.5977454
##  FRECUENCIA > -0.5903754
##  FRECUENCIA <= 0.8482971
##  ->  class SI  [0.525]
## 
## Default class: NO
## 
## -----  Trial 10:  -----
## 
## Rules:
## 
## Rule 10/1: (12777.5/4273.1, lift 1.2)
##  RESENCIA > -0.1104101
##  ->  class NO  [0.666]
## 
## Rule 10/2: (40141.8/17221.8, lift 1.0)
##  FRECUENCIA <= 0.488629
##  ->  class NO  [0.571]
## 
## Rule 10/3: (36661.4/16415.4, lift 1.0)
##  DISTANCIA_FIN_MES > -0.3967991
##  ->  class NO  [0.552]
## 
## Rule 10/4: (4790.6/2215.7, lift 1.2)
##  RESENCIA > -0.346462
##  RESENCIA <= -0.1104101
##  FRECUENCIA > -0.7702094
##  ->  class SI  [0.537]
## 
## Rule 10/5: (7764.5/3668.6, lift 1.2)
##  RESENCIA <= -0.346462
##  FRECUENCIA > 0.488629
##  DISTANCIA_FIN_MES <= -0.3967991
##  ->  class SI  [0.528]
## 
## Default class: NO
## 
## -----  Trial 11:  -----
## 
## Rules:
## 
## Rule 11/1: (5891.5, lift 1.8)
##  FRECUENCIA <= -0.7702094
##  ->  class NO  [1.000]
## 
## Rule 11/2: (8964.8/1506.4, lift 1.5)
##  RESENCIA > 0.007615822
##  ->  class NO  [0.832]
## 
## Rule 11/3: (5230.6/2047.9, lift 1.1)
##  FRECUENCIA <= 0.6684631
##  DISTANCIA_FIN_MES > 1.221238
##  ->  class NO  [0.608]
## 
## Rule 11/4: (25940.6/10994.4, lift 1.0)
##  DISTANCIA_FIN_MES <= -0.281225
##  ->  class NO  [0.576]
## 
## Rule 11/5: (6327.3/2826.7, lift 1.3)
##  RESENCIA > -0.346462
##  RESENCIA <= 0.007615822
##  FRECUENCIA > -0.7702094
##  ->  class SI  [0.553]
## 
## Rule 11/6: (49549/24348.3, lift 1.2)
##  RESENCIA <= 0.007615822
##  FRECUENCIA > -0.7702094
##  ->  class SI  [0.509]
## 
## Default class: NO
## 
## -----  Trial 12:  -----
## 
## Rules:
## 
## Rule 12/1: (5521.2, lift 1.7)
##  FRECUENCIA <= -0.7702094
##  ->  class NO  [1.000]
## 
## Rule 12/2: (54268.8/24239.7, lift 1.0)
##  FRECUENCIA > -0.7702094
##  ->  class NO  [0.553]
## 
## Rule 12/3: (2506.6/1072.9, lift 1.4)
##  RESENCIA > -0.346462
##  RESENCIA <= -0.228436
##  FRECUENCIA > -0.4105413
##  ->  class SI  [0.572]
## 
## Rule 12/4: (13918.8/6625.1, lift 1.3)
##  RESENCIA > -0.9365916
##  RESENCIA <= -0.346462
##  FRECUENCIA > -0.2307072
##  DISTANCIA_FIN_MES <= 0.1810713
##  ->  class SI  [0.524]
## 
## Rule 12/5: (23606/11656.1, lift 1.3)
##  RESENCIA <= -0.228436
##  FRECUENCIA > -0.4105413
##  DISTANCIA_FIN_MES <= 0.1810713
##  ->  class SI  [0.506]
## 
## Default class: NO
## 
## -----  Trial 13:  -----
## 
## Rules:
## 
## Rule 13/1: (40652.4/12949.3, lift 1.1)
##  FRECUENCIA <= 0.8482971
##  ->  class NO  [0.681]
## 
## Rule 13/2: (34890.2/11423.9, lift 1.1)
##  RESENCIA > -0.8185657
##  ->  class NO  [0.673]
## 
## Rule 13/3: (13438.4/5985.6, lift 1.5)
##  RESENCIA <= -0.8185657
##  FRECUENCIA > 0.8482971
##  ->  class SI  [0.555]
## 
## Default class: NO
## 
## -----  Trial 14:  -----
## 
## Rules:
## 
## Rule 14/1: (6873.4, lift 1.6)
##  RESENCIA > -0.1104101
##  ->  class NO  [1.000]
## 
## Rule 14/2: (17380/1913.3, lift 1.4)
##  FRECUENCIA <= -0.05087316
##  ->  class NO  [0.890]
## 
## Rule 14/3: (24338.8/7970.4, lift 1.1)
##  RESENCIA <= -0.8185657
##  ->  class NO  [0.673]
## 
## Rule 14/4: (17648.4/8023.3, lift 1.7)
##  RESENCIA > -0.8185657
##  RESENCIA <= -0.1104101
##  FRECUENCIA > -0.05087316
##  ->  class SI  [0.545]
## 
## Default class: NO
## 
## -----  Trial 15:  -----
## 
## Rules:
## 
## Rule 15/1: (6036.6, lift 1.6)
##  RESENCIA > -0.1104101
##  ->  class NO  [1.000]
## 
## Rule 15/2: (46247.1/12251.9, lift 1.2)
##  FRECUENCIA <= 1.747467
##  ->  class NO  [0.735]
## 
## Rule 15/3: (10752.2/4814.1, lift 1.9)
##  RESENCIA <= -0.1104101
##  FRECUENCIA > 1.747467
##  ->  class SI  [0.552]
## 
## Default class: NO
## 
## -----  Trial 16:  -----
## 
## Rules:
## 
## Rule 16/1: (52438.7/9228.3, lift 1.1)
##  FRECUENCIA <= 3.545808
##  ->  class NO  [0.824]
## 
## Rule 16/2: (1934.3/757.1, lift 3.6)
##  FRECUENCIA > 3.545808
##  ->  class SI  [0.609]
## 
## Default class: NO
## 
## -----  Trial 17:  -----
## 
## Rules:
## 
## Rule 17/1: (25473.1/275.6, lift 1.6)
##  FRECUENCIA <= 1.387799
##  ->  class NO  [0.989]
## 
## Rule 17/2: (16418.8/485.2, lift 1.6)
##  RESENCIA > -0.7005397
##  ->  class NO  [0.970]
## 
## Rule 17/3: (16002.3/5581.4, lift 1.1)
##  RESENCIA <= -0.9365916
##  ->  class NO  [0.651]
## 
## Rule 17/4: (13263.8/3774.9, lift 2.8)
##  RESENCIA > -0.9365916
##  RESENCIA <= -0.7005397
##  FRECUENCIA > 1.387799
##  ->  class SI  [0.715]
## 
## Default class: NO
## 
## 
## Evaluation on training data (61091 cases):
## 
## Trial            Rules     
## -----      ----------------
##      No      Errors
## 
##    0      4 8457(13.8%)
##    1      3 12597(20.6%)
##    2      5 9558(15.6%)
##    3      5 15331(25.1%)
##    4      3 9083(14.9%)
##    5      6 17233(28.2%)
##    6      4 15132(24.8%)
##    7      4 20701(33.9%)
##    8      2 8779(14.4%)
##    9      4 19495(31.9%)
##   10      5 10211(16.7%)
##   11      6 18294(29.9%)
##   12      5 12686(20.8%)
##   13      3 9569(15.7%)
##   14      4 12139(19.9%)
##   15      3 8720(14.3%)
##   16      2 8884(14.5%)
##   17      4 8927(14.6%)
## boost           8581(14.0%)   <<
## 
## 
##     (a)   (b)    <-classified as
##    ----  ----
##   51292   559    (a): class NO
##    8022  1218    (b): class SI
## 
## 
##  Attribute usage:
## 
##  100.00% RESENCIA
##  100.00% FRECUENCIA
##  100.00% DISTANCIA_FIN_MES
## 
## 
## Time: 1.9 secs
tree.pred <- predict(tree.fit,paint)
confusionMatrix(table(tree.pred, paint$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##          
## tree.pred    NO    SI
##        NO 51292  8022
##        SI   559  1218
##                                           
##                Accuracy : 0.8595          
##                  95% CI : (0.8568, 0.8623)
##     No Information Rate : 0.8488          
##     P-Value [Acc > NIR] : 2.967e-14       
##                                           
##                   Kappa : 0.1812          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.13182         
##             Specificity : 0.98922         
##          Pos Pred Value : 0.68542         
##          Neg Pred Value : 0.86475         
##              Prevalence : 0.15125         
##          Detection Rate : 0.01994         
##    Detection Prevalence : 0.02909         
##       Balanced Accuracy : 0.56052         
##                                           
##        'Positive' Class : SI              
## 
tree.pred <- predict(tree.fit,test)
confusionMatrix(table(tree.pred, test$COMPRA_MANIANA), positive = "SI")
## Confusion Matrix and Statistics
## 
##          
## tree.pred      NO      SI
##        NO 3586933  558545
##        SI   41593   87104
##                                           
##                Accuracy : 0.8596          
##                  95% CI : (0.8593, 0.8599)
##     No Information Rate : 0.8489          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.184           
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.13491         
##             Specificity : 0.98854         
##          Pos Pred Value : 0.67681         
##          Neg Pred Value : 0.86526         
##              Prevalence : 0.15106         
##          Detection Rate : 0.02038         
##    Detection Prevalence : 0.03011         
##       Balanced Accuracy : 0.56172         
##                                           
##        'Positive' Class : SI              
## 

Por temas de rendimiento solo se pudo entrenar el arbol C5.0 con el subset de datos que se utilizó para las gráficas pero al probarlo con el set de datos test se consiguieron los mejores hasta el momento con una exactitud general de 85.87% y positivos reales de 57%, definitivamente no se han alcanzado los resultados esperados pero si se ve una mejora considerable.

Conclusiones

Comencemos con un resumen de todos los resultados obtenidos

Linear Regression Sensitivity : 0.1734
Specificity : 0.9807
Pos Pred Value : 0.6150
Neg Pred Value : 0.8696

LDA Sensitivity : 0.25393
Specificity : 0.96160
Pos Pred Value : 0.54056
Neg Pred Value : 0.87869

QDA Sensitivity : 0.35264
Specificity : 0.92662
Pos Pred Value : 0.46095
Neg Pred Value : 0.88943

QDA DownSampled Sensitivity : 0.7234
Specificity : 0.6915
Pos Pred Value : 0.7010
Neg Pred Value : 0.7143

QDA DownSampled - TEST Sensitivity : 0.7238
Specificity : 0.6894
Pos Pred Value : 0.2931
Neg Pred Value : 0.9335

QDA K-Fold Sensitivity : 0.35181
Specificity : 0.92652
Pos Pred Value : 0.46003
Neg Pred Value : 0.88930

QDA DownSampled K-Fold Sensitivity : 0.7268
Specificity : 0.6866
Pos Pred Value : 0.6987
Neg Pred Value : 0.7154

QDA DownSampled K-Fold - TEST Sensitivity : 0.7269
Specificity : 0.6864
Pos Pred Value : 0.2920
Neg Pred Value : 0.9339

C5.0 Sensitivity : 0.22175
Specificity : 0.97541
Pos Pred Value : 0.61643
Neg Pred Value : 0.87552

C5.0 - TEST Sensitivity : 0.21553
Specificity : 0.97519
Pos Pred Value : 0.60718
Neg Pred Value : 0.87479

La exactitud general del modelo nos puede dar una guía de la eficiencia con la que funciona pero no lo es todo y por ello consideramos más a los indicadores siguientes:

  • Sensitiviyty: Indica la cantidad de aciertos positivos entre el total de positivos reales
  • Specificity: Indica la cantidad de aciertos negativos entre el total de negativos reales
  • Pos pred value: Indica la cantidad de predicciones positivas que fueron correctas
  • Neg pred value: Indica la cantidad de predicciones negativas que fueron correctas

y basados en esto vemos que el modelo QDA con down sampling es el de mejor resultados, superado levemente por la version del mismo QDA pero con K-fold con k=10, sin embargo al utilizar estos 2 modelos sobre una muestra aleatoria llamada test los resultados se deterioran pero es algo que veremos en proximo estudio.

Libera memoria

Evita error en pandoc al generar el rmarkdown como HTML

rm(datos)
gc()
##             used   (Mb) gc trigger (Mb)  max used   (Mb)
## Ncells   4981649  266.1   14866301  794  30180467 1611.9
## Vcells 173160624 1321.2  552853024 4218 691066281 5272.5
gc()
##             used   (Mb) gc trigger (Mb)  max used   (Mb)
## Ncells   4981646  266.1   14866301  794  30180467 1611.9
## Vcells 173158551 1321.1  552853024 4218 691066281 5272.5
gc()
##             used   (Mb) gc trigger (Mb)  max used   (Mb)
## Ncells   4981654  266.1   14866301  794  30180467 1611.9
## Vcells 173158579 1321.1  552853024 4218 691066281 5272.5