Problema sobre fraudes

Se desea predecir si una orden de compra de un e-commerce serÔ fraudulenta y se tiene la siguiente ingormación.

Muestra de datos
id_usuario fecha inicio Fecha compra Monto id_dispositivo
1 22058 2015-02-24 22:55:49 2015-04-18 02:47:11 34 QVPSPJUOCKZAR
2 333320 2015-06-07 20:39:50 2015-06-08 01:38:54 16 EOGFQPIZPYXFZ
3 1359 2015-01-01 18:52:44 2015-01-01 18:52:45 15 YSSKYOSJHPPLJ
4 150084 2015-04-28 21:13:25 2015-05-04 13:54:50 44 ATGTXKYKUDUQN
5 221365 2015-07-21 07:09:52 2015-09-09 18:40:53 39 NAUITBZFJKHWW
6 159135 2015-05-21 06:03:03 2015-07-09 08:05:14 42 ALEYXFXINSXLZ
Muestra de datos
Fuente Navegador sexo edad direccion_ip Fraude
1 SEO Chrome M 39 732758369 0
2 Ads Chrome F 53 350311388 0
3 SEO Opera M 53 2621473820 1
4 SEO Safari M 41 3840542444 0
5 Ads Safari M 45 415583118 0
6 Ads Chrome M 18 2809315200 0

Se tienen 151,112 registros de compras realizadas donde de las cuales 14,151 se han identificado como fraude, para esta viariable binaria tenemos que 1 son las compras fraude y 0 identifica a las compras verdaderas

Fraudes
Fraude Frecuencia
1 0 136961
2 1 14151

Las variables que se han decidido utilizar seran ā€œFecha compraā€,ā€œMontoā€,ā€œFuenteā€,ā€œNavegadorā€, ā€œsexoā€, ā€œedadā€, ā€œdireccion_ipā€, ā€œFraudeā€. Para hacer uso de estas variables hay que notar que algunas son variables categoricas y otras numericas. Por lo que procederemos a preparar los datos para modelarlos.

Vamos a observar la grÔfica de dispersión entre el monto de de las compras según el indicador si es fraude o no.

library(ggplot2)
ggplot( dat , aes ( x= purchase_value , y=age  , group = class , col = factor(class ))) +
  geom_point ( alpha =0.4) +
  labs (x =" Rendimiento ",y =" Fabricante ") 

Preprocesamiento de los datos

Es necesario que preparemos los datos que vamos a utilizar de modo que nos sean utiles para la creación de nuestra red neuronal. Para esto se ha realizado lo siguiente.

Transformación de variables

Se transformaran las variables categoricas a dummies y se utilizarÔ la variable fecha de compra pues nos parece interesante saber si esta variable puede indicar alguna relación sobre si es una compra fraude o no. Por lo que se transforma la variable fecha a un valor numerico asignado a cada fecha.

Muestra de datos
purchase_time purchase_value source browser sex
1 16490 34 SEO Chrome M
2 16593 16 Ads Chrome F
3 16436 15 SEO Opera M
4 16553 44 SEO Safari M
5 16637 39 Ads Safari M
6 16576 42 Ads Chrome M
Muestra de datos
age ip_address class source_Ads source_Direct source_SEO
1 39 732758369 0 0 0 1
2 53 350311388 0 1 0 0
3 53 2621473820 1 0 0 1
4 41 3840542444 0 0 0 1
5 45 415583118 0 1 0 0
6 18 2809315200 0 1 0 0
Muestra de datos
browser_Chrome browser_FireFox browser_IE browser_Opera browser_Safari
1 1 0 0 0 0
2 1 0 0 0 0
3 0 0 0 1 0
4 0 0 0 0 1
5 0 0 0 0 1
6 1 0 0 0 0

Notar que la variable fecha ya tiene asignado un valor numerico

Escalamiento de los datos

Una parte importante del preprocesamiento de los datos es escalarlos, es decir, haremos todos los datos nĆŗmericos esten en la misma escala.

x_vars <- t(scale(dat[,c(1,2,6,7,9:18)],center=T,scale=T))

Overfitting: Conjunto de entrenamiento y de prueba

Un problema muy usual al momento de modelar un conjunto de datos es que nuestro modelo podria estar sobre estimando los datos, es decir, se aproxima tanto a los datos que no generaliza de manera adecuada los datos.

Y dado que la principal razón de modelar datos es predecir, el comportamiento de las variables de un determinado evento a futuro… Un modelo que no generalice de manera adecuada es un modelo que no nos servirĆ”. Por tal motivo intentaremos detectar si nuestro modelo estĆ” sobre estimando o no.

Para esto se utilizarĆ” una proporción de los datos para entrenar nuestra red neuronal y la otra proporción para evaluarla, dado que la red ā€œaprendeā€ y memoriza el comportamiento de los datos con los que entrena, buscaremos evaluarla con datos que no haya entrenado. De esta manera sabremos si esta generalizando nuestro evento o no.

La proporción seleccionada fue 80% de los datos para el entrenamiento y el 20% de los datos para la evaluación. Eligiendo registros pseudoaleatorios dado que no conocemos cual es la naturaleza u orden de los 151,112 registros y evitaremos tomar una proporción de datos que posiblemente tengan una ā€œnaturalezaā€ distinta.

filas.random <- sample(1:151112, 30222, replace= F)
dat_train <- as.data.frame(dat[-filas.random,])
dat_test <- as.data.frame(dat[filas.random,])

Posteriormente procederemos a escalar estos datos.

x_vars_train <- t(scale(dat_train[,c(1,2,6,7,9:18)],center=T,scale=T))
x_vars_test <- t(scale(dat_test[,c(1,2,6,7,9:18)],center=T,scale=T))

y_var_train <- t(as.matrix(dat_train[,8]))
t_var_test <- t(as.matrix(dat_test[,8]))

Red neuronal

Se realiza la siguiente red Neuronal:

Y la matriz de confusión

y_var <- t(as.matrix(dat_train[,8]))

model <- train_nn(x_vars_train, y_var_train, hidden_neurons = 6 , iters = 1000, learning_rate = 0.9)
## Iteration 1000  | Cost:  0.2557398
probas <- predict_nn(x_vars_train, model)

clase <- round(probas)

Observamos los datos obtenidos de nuestra red Neuronal

summary(t(probas))
##        V1         
##  Min.   :0.03417  
##  1st Qu.:0.03423  
##  Median :0.03575  
##  Mean   :0.09262  
##  3rd Qu.:0.08364  
##  Max.   :0.43858

Se utilizaron pocas iteraciones pues computacionalmente tiene una complejidad en tiempo muy alta tener iteraciones altas. Por lo que se utilizaron pocas iteraciones para ejemplificar el problema que tenemos. Sin embargo, es ideal tener un nĆŗmero alto de iteraciones para obtener la red neuronal entrenada con menor costo. Asi obtendriamos la red ā€œmejor entrenadaā€ por medio del mĆ©todo backward propagation.

Observando probabilidades entrenadas y de prueba

Vamos a observar el comportamiento que a aproximado nuestra red en los datos entrenados y la sprobabilidades que modelarĆ” con los datos que decidimos separar para la prueba. De esta manera vamos a detectar si esta sobre estimando o no nuestra red neuronal.

plot(sort(as.vector(probas)),type = 'l',col='blue')
legend('bottomright', legend='Entrenada', col='blue', lty=1)

probas1 <- predict_nn(x_vars_test, model)

plot(sort(as.vector(probas1)),type = 'l',col='red')
legend('bottomright', legend='Evaluada', col='red', lty=1)

Por lo que podemos notar que nuestra red neuronal esta generalizando bien el problema que estamos trabajando.