Descripción de la base de datos

Los datos están relacionados con las campañas de marketing de una institución bancaria de Portugal. Abarca 17 campañas que ocurrieron entre mayo 2008 y noviembre 2010, las campañas consisten en llamadas a clientes sumando 40,690 contactos en esta base de datos. En las llamadas se ofrecía un contrato a largo plazo para invertir dinero, con tasas de interés atractivas (de acuerdo al banco). En cada contacto se registraban 16 atributos que incluyen la respuesta del cliente, esto es si el cliente contrató el producto o no.

Las variables son las siguientes:

title

La institución bancaria quisiera conocer como están relacionadas estas variables, en particular, quisieran entender la relación con la variable respuesta y.

library(dplyr)
library(ggplot2)
library(bnlearn)
library(gRain)
library(tidyr)
library(SDMTools)
load('./Datos/mkt.Rdata')

Dividimos la muestra en un conjunto de prueba y uno de entrenamiento.

set.seed(18937)
mkt_train <- sample_n(mkt, 30000)
mkt_test <- anti_join(mkt, mkt_train)
## Joining by: c("age", "job", "marital", "education", "default", "balance", "housing", "loan", "contact", "month", "duration", "campaign", "previous", "poutcome", "y", "id")

Tenemos en la descripción de la base de datos que hay algunas variables numéricas. Vamos a categorizar estas variables, pues si hay pocas observaciones sobre algún número en particular, puede haber estimaciones ruidosas. Esto se puede ver gráficamente en los histogramas siguientes.

qplot(mkt_train$age) + 
  ggtitle("Distribución de la edad") + 
  theme(plot.title = element_text(lineheight=.8, face="bold")) + 
  xlab("Edad") +
  ylab("Num. de personas")

qplot(mkt_train$balance) + 
  ggtitle("Distribución del balance") + 
  theme(plot.title = element_text(lineheight=.8, face="bold")) + 
  xlab("Balance en euros") +
  ylab("Num. de personas")

qplot(mkt_train$duration) + 
  ggtitle("Distribución de la duración") + 
  theme(plot.title = element_text(lineheight=.8, face="bold")) + 
  xlab("Duración") +
  ylab("Num. de personas")

qplot(mkt_train$campaign) + 
  ggtitle("Distribución de las veces que se \n contactó con el cliente durante la campaña") + 
  theme(plot.title = element_text(lineheight=.8, face="bold")) + 
  xlab("Veces que se contactó con el cliente") +
  ylab("Num. de personas")

qplot(mkt_train$previous) + 
  ggtitle("Distribución de las veces que se había \n contactado con el cliente antes de la campaña") + 
  theme(plot.title = element_text(lineheight=.8, face="bold")) + 
  xlab("Veces que se contactó con el cliente") +
  ylab("Num. de personas")

Como se puede apreciar en los histogramas, todas las variables están sesgadas hacia algún lado y tienen valores extremos con pocas observaciones.

Para evitar esto, vamos a categorizar cada una de las variables anteriores en intervalos tales que la cantidad de clientes en cada intervalo sea más o menos igual.

mkt_train$age_cat <- cut(mkt_train$age, quantile(mkt_train$age, probs=(0:15)/15))
mkt_train$balance_cat <- cut(mkt_train$balance, quantile(mkt_train$balance, probs=(0:15)/15))
mkt_train$duration_cat <- cut(mkt_train$duration, quantile(mkt_train$duration, probs=(0:5)/5))
mkt_train$campaign_cat <- cut(mkt_train$campaign, c(0,1,3,max(mkt_train$campaign)))
mkt_train$previous_cat <- factor(mkt_train$previous!=0)
train <- mkt_train[,sapply(mkt_train, class)=='factor']
names(train) <- c("job","marital","education","default","housing","loan","contact","month","poutcome","y",  "age","balance", "duration","campaign","previous")
train <- train[complete.cases(train),]

Vamos a aprender la estructura de una red bayesiana a partir de la muestra de entrenamiento. Debido a que la variable de interés es si contrató el plan o no (\(y\)), podemos considerarla como la variable respuesta, por lo que en la red bayesiana vamos a ‘obligar’ al algoritmo a que no le asigne hijos a la \(y\) en la red. Ajustaremos primero dos redes con distinto score, una con AIC y otra con BIC.

black <- expand.grid('y',names(train))
net1aic <- hc(train,  score = 'aic', blacklist = black)
strength1aic <- arc.strength(net1aic, train)
strength.plot(net1aic, strength1aic, shape='ellipse', main='AIC')
## Loading required namespace: Rgraphviz