Descripcion del problema

La predicción de eventos futuros es un punto de interés para diversas disciplinas a lo largo de la historia, desde las leyendas de reyes que buscaban la sabiduría de los Oráculos con el fin de actuar frente a su porvenir hasta las falsedades que ahora aparecen en la televisión y diarios de falsos pitonizos que intentan convencer a la gente de escuchar su consejo. No cabe duda que quien sepa con certeza lo que va a suceder es una persona con harto poder en sus manos, esta persona podría modificar sus acciones y prevenir jugadas de otros agentes con el fin de obtener el mayor beneficio en su futuro. Es por esto que el fin de este proyecto es entregar un acercamiento a este arte, mediante la predicción de productos a ser consumidos por clientes del Banco Santander en base a su consumo previo de los últimos 16 meses y a su información personal; armados con este dataset, se nos dio la tarea de predecir el comportamiento futuro de los clientes y así, verificar su actuar.

Limpieza de los datos

Una primera vista al dataset (https://www.kaggle.com/c/santander-product-recommendation/data) nos da una idea de con qué es lo que se dispone a trabajar. Se cuenta con la información personal de los clientes (sexo,edad,código de provincia, etc...) junto con su información de consumo en forma binaria (un uno si consumió el producto en el mes dado y un cero si es que no). Un primer acercamiento nos hace notar que existen muchos datos con información inconclusa (no hay datos) y que existen datos de personas irrelevantes (personas fallecidas), si bien, era factible rellenar los datos faltantes de forma tal que se mantuvieran las tendencias estadísticas imperantes en el modelo, se optó por eliminarlas para no incurrir en errores por falsa predicción, además, se eliminaron las personas fallecidas.

Exploración de los datos

Como fase exploratoria, se procedió a analizar los atributos de mayor interés de forma atómica, con el fin de entender su distribución.

Edad

Se nota un gran alza en el rango de edad entre 20 a 25 años, además de una pequeña remontada en los de 50 años, esto puede influir en los productos enfocados a ciertos grupos etarios

Renta

Se ve una tremenda heterogeneidad, la desviación estándar de la muestra es dos veces el promedio, esto quiere decir que quizás no convenga trabajar con la renta como un continuo, sino como valores discretos mediante la segmentación.

Sexo

Se ve una distribución homogenea, no hay mayores diferencias ni conclusiones que faciliten o dificulten el trabajo c/r a este atributo.

Antiguedad cliente

Se ve que gran parte de los clientes llevan menos de 50 meses en el banco (con lo que se pueden considerar como clientes recientes), esto implica que quizás sus hábitos de consumo no estén tan definidos y que puedan variar bastante dificultando nuestra tarea. Debido a la característica continua de los datos y a su dispersión, también interesaría trabajar con segmentos.

Número de productos consumidos

Este es el análisis más interesante, la mayoría de la gente tan sólo consume un producto (Cuenta Corriente), mientras que la distribución de otros niveles de consumo es muy baja. Esto genera varios problemas al momento de clasificar ya que se tendrán clases muy desbalanceadas y el clasificador necesitará de mayor precisión para funcionar.

Servicios v/s tiempo

Posterior al análisis atómico, se vieron variaciones de atributos combinados Se ve cómo se agregan y eliminan productos con el paso de los meses, llama la atención el producto de recaudación fiscal que tiene una tasa de agregación altísima (casi todos los meses alguien la agrega) además del producto de hipoteca el cuál es abandonado casi todos los meses.

Servicios v/s género v/s tiempo

Se ve que en general, hay un radio similar de agregación y eliminación de productos para ambos sexoss.

Servicios v/s clientes nuevos

Como se esperó, los clientes nuevos añaden más productos que los viejos (están experimentando más es nuestra hipótesis)

Regresiones lineales

Para ciertos productos se realizaron regresiones lineales con los atributos que se consideraban más relevantes (edad,sexo,antiguedad,renta). Se obtuvieron resultados similares en que el sexo era el más influyente para casi todos los productos (ser hembra implica mayor consumo) aunque los modelos tenían un R^2 muy bajo (Por lo que no se consideran significativos), sorprendentemente, la edad no fue relevante para el consumo del producto asociado con las pensiones.

Clasificadores

Tratamiento con K-NN

Se utilizo la Librería sklearn. Se llevo a cabo un entrenamiento con 92.470 datos.

Se utilizo K-NN con todos los datos. El método knn.predict(...) determina la clase de los datos entregados como parámetro. Por ejemplo si ejecutáramos knn.predict([[1.0, 2.0, 3.0, 1.0]]), le estamos pasando al clasificador un dato con valores [1.0, 2.0, 3.0, 1.0]. Al ejecutar predict, éste nos retornará un arreglo indicando la clase en la cual fue clasificado

Luego se utilizo la función cross_validation.train_test_split(X, y, test_size=p, random_state=N) divide los arreglos X e y en dos arreglos, haciendo un muestreo de sus datos de forma consistente para generar un dataset de entrenamiento y otro de pruebas; test_size indica la fracción del total para asignar el tamaño del conjunto de pruebas. El parámetro random_state sirve para tener

resultados consistentes tras cada ejecución.

Finalmente Con cross-validation, el conjunto de entrenamiento se divide en k conjuntos disjuntos; se entrena sobre los datos correspondientes a k−1 de éstos, y se evalúa sobre el conjunto restante. Esto se repite k veces, evaluando siempre sobre un conjunto distinto. Teniendo en cuenta el parámetro k , a éste método se le llama k -fold cross-validation.

Tratamiento con Arules

Para hallar un criterio de asociación, se utilizaron las librerías: arules, arulesViz y arulesCBA dentro de R Studio. Primero se procesaron los datos para que arules los pudiera interpretar, esto implicó discretizar los valores para que quedasen dentro de intervalos (también se tuvo que realizar para los productos a pesar de que tienen valores binarios, esto porque R interpretaba el 1 dentro de esas columnas como un float). Una vez se hizo esto, se procedieron a eliminar varios datos, esto debido a que existía cierta redundancia, se eliminaron los atributos de antiguedad (existe un parámetro que indica si el cliente es nuevo o no), de renta (existe un parámetro que indica el segmento en el que se encuentra el cliente) además del índice de si un cliente es primario o no bajo los mismos argumentos, además del tipo de domicilio (no existía mayor dispersión) y del índice de fallecimiento del cliente. Con esto en mente, se probaron las reglas de asociación para distintos valores de support y confidence a lo largo de todo el data frame

Además, se obtuvieron las reglas más llamativas para diversos niveles

Posteriormente, interesó notar si existía alguna relación entre los consumo de ciertos productos y su influencia en el consumo de otros productos, para esto se realizó una muestra de las reglas de asociación para un support de 0.1 y un confidence de 0.5, dando como resultado:

Lo cual indica que no existe relación entre productos (las asociaciones eran del tipo X -> Cta Corriente, el cuál es el producto de mayor consumo) Se buscaron asociaciones para un menor support, pero debido a lo alto del lift, no se pueden considerar como confiables.

Luego se hizo un análisis por producto, para esto se utilizó el comando CBA, el cuál entrena al clasificador mediante las reglas de asociación entregadas por arules, tomando como training set una muestra de 8000 filas (debido al límite de procesamiento de los computadores utilizados, no fue posible tomar mayor cantidad de datos) y se probó sobre 5.000 datos, los resultados fueron:

Conf Matrix Cta Corriente
classesCtaCor <- predict(classCtaCor, testCtaCor)
> CrossTable(classesCtaCor, testCtaCor$CtaCorriente, prop.chisq =FALSE, prop.r = FALSE, prop.c = FALSE)
 
   Cell Contents
|-------------------------|
|                       N |
|         N / Table Total |
|-------------------------|
 
Total Observations in Table:  5000 

              | testCtaCor$CtaCorriente 
classesCtaCor | [0.0,0.5) | [0.5,1.0] | Row Total | 
--------------|-----------|-----------|-----------|
    [0.5,1.0] |       390 |      4610 |      5000 | 
              |     0.078 |     0.922 |           | 
--------------|-----------|-----------|-----------|
 Column Total |       390 |      4610 |      5000 | 
--------------|-----------|-----------|-----------|
Matrix Confusion Arules CBA

results     [0.0,0.5) [0.5,1.0]
  [0.0,0.5)        99         1
  [0.5,1.0]         0         0
  

Como se puede apreciar, nuestro clasificador entrega precisión del 92.2% ¡Lo que quiere decir que el trabajo fue un éxito! Bueno, no es tan así. Si bien es cierto que la predicción va a acertar en la mayoría de los casos (es como jugar a la segura) no entrega mayor utilidad al banco, es decir, no revisa los casos interesantes en los que se quiere saber si se va a consumir o no.

Bagging de Cluster Compensados

Se intenta compensar datos desbalanceados y luego crear un clasificador. Consiste en crear cluster de los casos negativos y compensarlo con la totalidad de casos positivos, para luego crear grupos de algoritmos en cada cluster que puedan "aprender" las diferencias entre los positivos y los diferentes tipos de negativos. Esto crearía diferentes algoritmos "especialistas" en cada cluster.

Esta técnica parece funcionar en escenarios desbalanceados donde el costo del error de falsos positivos es compensado con la ganancia en predicción  correcta de "algunos" verdaderos positivos, y donde los algoritmos con set normales predicen cerca del 0% de verdaderos positivos.

 

#Calcula prediccion usando voto mayoritario
  Prediccion                 <- as.data.frame(Prediccion)
  Prediccion$Cantidad_yes    <- rowSums(Prediccion [, 1:Iteraciones] == 1)
  Prediccion$Cantidad_no     <- rowSums(Prediccion [, 1:Iteraciones] == 2)
  Prediccion$Prediccion      <- clase[with(Prediccion,(Cantidad_yes>Cantidad_no)+1)]
  MC                         <- table(Test$ind_cco_fin_ult1,Prediccion$Prediccion)
              | Clase Predicha
clase Real    |     0     |     1     |
--------------|-----------|-----------|
    0         |    882    |   126386  |  
--------------|-----------|-----------|
    1         |  166795   |   264005  |  
--------------|-----------|-----------|

Bagging de Cluster vs Rpart

# grafico
comparacion <-data.frame( Recall=c(Recall,Recall_rpart),
                          Precision=c(Precision,Precision_rpart))

plot(comparacion , ylim=c(0,1), xlim=c(0,1))

text(comparacion$Recall,comparacion$Precision,
     labels=c("Bagging de cluster","rpart"),pos=1,cex=.7)

Random Forest

Posteriormente, se buscó seguir la rúbrica del proceso de bagging con otro algoritmo asociado, el cual lleva por nombre "RandomForest". Se eligió debido a su potente precisión, habilidad de manejo de grandes volúmenes de datos y estructura de árbol de decisión (se visualiza la idea de un árbol de decisión como la idea más "pura" dentro del clasificador, es decir, es sencilla de interpretar)

Para sanear el problema de falta de datos pertenecientes a la clase minoritaria para los productos se procedió a utilizar la libreria "unbalanced" de R Studio la cuál cuenta con la función "Racing" que genera una "carrera" de métodos de sub y oversampling para determinar cuál es el método de manipulación de datos más apropiado para el dataset, esto dio como ganador al proceso SMOTE (Synthetic Mining Over-sampling Technique) el cual genera muestras sintéticas mediante la perturbación aleatoria de atributos dentro de los datos pertenecientes a la clase minoritaria

 +-+-----------+-----------+-----------+-----------+-----------+
 | |       Fold|      Alive|       Best|  Mean best| Exp so far|
 +-+-----------+-----------+-----------+-----------+-----------+
 |x|          1|          9|          2|      0.296|          9|
 |=|          2|          9|          4|     0.2856|         18|
 |=|          3|          9|          4|     0.2923|         27|
 |-|          4|          4|          4|     0.2863|         36|
 |=|          5|          4|          4|     0.2857|         40|
 |=|          6|          4|          4|     0.2839|         44|
 |=|          7|          4|          4|     0.2835|         48|
 |=|          8|          4|          4|     0.2817|         52|
 |=|          9|          4|          4|     0.2794|         56|
 |=|         10|          4|          4|     0.2749|         60|
 +-+-----------+-----------+-----------+-----------+-----------+

Posterior a esto, se realizó el algoritmo para cuatro productos distintos, obteniendo como resultados:

 +----------+-------------+-----------+-----------+-----------+
 |Producto  |Cta Corriente|  Hipoteca | Impuestos |  Préstamo |
 +----------+-------------+-----------+-----------+-----------+
 |  Accuracy|      88.8%  |      92.6%|      91.6%|      93.4%|
 |        F1|      0.63   |       0.14|       0.44|       0.03|
 +----------+-------------+-----------+-----------+-----------+

Donde si bien se obtuvo un menor accuracy, se obtuvieron mayores casos de verdaderos positivos. Como para el banco tiene mayor costo tener un falso negativo antes que un falso positivo se ve que esta solución es mejor que el classificador mayoritario. Esto debido a que si bien, no se cumple que el usuario vaya a consumir el producto con certeza, se tendrá que existe una probabilidad mayor a que lo consuma c/r a un cliente arbitrario, por lo que servirá para que el Banco pueda enfocar sus esfuerzos (con publicidad especializada por ejemplo) y así reducir costos operativos.