CASO: Detección de fraude en transacciones bancarias

Se dispone de una base de datos de 5000 transacciones bancarias, clasificadas en tres tipos:

Normal: transacciones habituales del cliente Sospechosa: transacciones con patrones atípicos Fraude: transacciones con alta probabilidad de actividad fraudulenta

El objetivo es construir un modelo de análisis discriminante que permita clasificar nuevas transacciones en uno de estos tres grupos, a partir de variables relacionadas con el comportamiento financiero del cliente.

Este tipo de análisis es relevante en contextos reales como:

Sistemas de detección de fraude en bancos

Seguridad en comercio electrónico

Prevención de pérdidas financieras

Tipo de transacción: (1 = Normal, 2 = Sospechosa, 3 = Fraude)

log_monto: Logaritmo del monto de la transacción.

log_trans_24h: Logaritmo del número de transacciones realizadas por el cliente en las últimas 24 horas. Valores altos pueden indicar actividad inusual.

log_distancia_km: Logaritmo de la distancia geográfica (en km) entre la ubicación habitual del cliente y el lugar de la transacción. Valores altos pueden reflejar transacciones desde ubicaciones atípicas.

desviacion_horaria: Medida continua que representa cuánto se aleja la hora de la transacción del patrón habitual del cliente. Valores altos indican horarios inusuales (por ejemplo, madrugada).

log_intentos_fallidos: Logaritmo del número de intentos fallidos previos (por ejemplo, ingreso incorrecto de clave). Valores elevados pueden indicar intentos de acceso no autorizado.

log_tiempo_entre_trans: Logaritmo del tiempo (en minutos) entre transacciones consecutivas. Valores bajos (en escala original) indican actividad rápida y potencialmente sospechosa.

Carga de datos

datos <- read.csv("/Users/verar/Downloads/fraude_transacciones.csv")
datos <- data.frame(datos[,1:7])
head(datos)
##   log_monto log_trans_24h log_distancia_km desviacion_horaria
## 1  3.491959   0.267064389         3.058356         1.13983440
## 2  3.541905   1.559396166         2.107716         0.80614927
## 3  3.029255   1.440256544         1.292181        -1.21802087
## 4  3.869978   0.783484985         1.677030         0.32141709
## 5  3.381762   1.024567244         2.651197        -0.09020685
## 6  3.696927  -0.003814171         1.262385        -0.25604700
##   log_intentos_fallidos log_tiempo_entre_trans  grupo
## 1            0.52178777               4.458712 Normal
## 2            0.04668717               4.663755 Normal
## 3           -0.54280611               4.774280 Normal
## 4           -0.12303155               3.634071 Normal
## 5            0.35239779               4.968085 Normal
## 6           -0.56186736               5.202638 Normal
  1. ¿Cuál es el objetivo principal del análisis discriminante en el contexto de este estudio?

Se busca distinguir entre transacciones fraudulentas y no fraudulentas, identificando qué variables permiten separar mejor ambos grupos y construir un modelo que permita predecir nuevas transacciones.

  1. Identifique la variable dependiente y las variasble sindependientes y explique por qué es adecuada para aplicar análisis discriminante.

La variable dependiente es grupo, de tipo categórico.

Las variables independientes son log_monto, log_trans_24h, log_distancia_km, desviacion_horaria, log_intentos_fallidos y log_tiempo_entre_trans.

El análisis discriminante es adecuado porque permite clasificar observaciones en grupos a partir de variables numéricas.

  1. Realice un análisis descriptivo adecuado de los datos.
par(mfrow=c(2,3))

boxplot(log_monto ~ grupo, col='skyblue', data=datos)
boxplot(log_trans_24h ~ grupo, col='skyblue', data=datos)
boxplot(log_distancia_km ~ grupo, col='skyblue', data=datos)
boxplot(desviacion_horaria ~ grupo, col='skyblue', data=datos)
boxplot(log_intentos_fallidos ~ grupo, col='skyblue', data=datos)
boxplot(log_tiempo_entre_trans ~ grupo, col='skyblue', data=datos)

Los boxplots muestran diferencias claras entre los grupos. El grupo Fraude presenta valores más altos en la mayoría de variables y el grupo Normal los más bajos

Esto indica la existencia de patrones diferenciados entre los grupos y sugiere que las variables tienen capacidad para discriminar entre ellos.

  1. Verifique los supuestos del análisis discriminante.
library(mvnormtest)
mshapiro.test(t(datos[, -which(names(datos)=="grupo")]))
## 
##  Shapiro-Wilk normality test
## 
## data:  Z
## W = 0.98905, p-value < 2.2e-16
library(biotools)
## Warning: package 'biotools' was built under R version 4.5.3
## Cargando paquete requerido: MASS
## ---
## biotools version 4.3
boxM(datos[, -which(names(datos)=="grupo")], datos$grupo)
## 
##  Box's M-test for Homogeneity of Covariance Matrices
## 
## data:  datos[, -which(names(datos) == "grupo")]
## Chi-Sq (approx.) = 43.282, df = 42, p-value = 0.4164

La prueba de Shapiro-Wilk presenta un p-valor < 0.05, por lo que no se cumple la normalidad. La prueba de Box’s M tiene un p-valor de 0.4164 > 0.05, por lo que se cumple la homogeneidad de covarianzas.

  1. Realiza la prueba para justificar el análisis discriminante.
manova_fit <- manova(
  cbind(log_monto, log_trans_24h, log_distancia_km,
        desviacion_horaria, log_intentos_fallidos,
        log_tiempo_entre_trans) ~ grupo,
  data = datos
)

Se aplicó la prueba de Box’s M para evaluar la igualdad de matrices de covarianza, obteniéndose un valor de Chi-cuadrado de 43.282 con un p-valor de 0.416 mayor a 0.05

No se rechaza la hipótesis nula, lo que indica que las matrices de covarianza son iguales entre los grupos. Por lo tanto, se cumple este supuesto y el uso del análisis discriminante está justificado.

  1. Interprete el lambda de Wilk.
summary(manova_fit)
##             Df  Pillai approx F num Df den Df    Pr(>F)    
## grupo        2 0.68323   431.78     12   9986 < 2.2e-16 ***
## Residuals 4997                                             
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(manova_fit, test="Wilks")
##             Df   Wilks approx F num Df den Df    Pr(>F)    
## grupo        2 0.32374   630.27     12   9984 < 2.2e-16 ***
## Residuals 4997                                             
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

El estadístico de Pillai (0.68323) y el Lambda de Wilks (0.32374) presentan p-valores menores a 0.05, por lo que se rechaza la hipótesis nula. Esto indica que existen diferencias estadísticamente significativas entre los grupos en función de las variables analizadas.

Asimismo, el valor de Lambda de Wilks relativamente bajo (0.32374) evidencia que el modelo tiene una buena capacidad para discriminar entre los grupos, lo que respalda la aplicación del análisis discriminante.

  1. Ajuste el modelo discriminante e interprete las probabilidad aprioris:
library(MASS)
lda_fit <- lda(grupo ~ log_monto + log_trans_24h + log_distancia_km +
               desviacion_horaria + log_intentos_fallidos +
               log_tiempo_entre_trans,
               data = datos)
lda_fit
## Call:
## lda(grupo ~ log_monto + log_trans_24h + log_distancia_km + desviacion_horaria + 
##     log_intentos_fallidos + log_tiempo_entre_trans, data = datos)
## 
## Prior probabilities of groups:
##     Fraude     Normal Sospechosa 
##       0.07       0.78       0.15 
## 
## Group means:
##            log_monto log_trans_24h log_distancia_km desviacion_horaria
## Fraude      4.971090     2.3091132         4.077646          2.4002759
## Normal      3.601113     0.9908171         1.999379          0.4023653
## Sospechosa  4.274717     1.6754687         3.178935          1.3213661
##            log_intentos_fallidos log_tiempo_entre_trans
## Fraude                1.36071626               2.241785
## Normal                0.09083588               4.190407
## Sospechosa            0.68512138               3.226164
## 
## Coefficients of linear discriminants:
##                                LD1        LD2
## log_monto              -0.30193942 -0.2955025
## log_trans_24h          -0.06847524  0.3813189
## log_distancia_km       -0.62784855  1.4678456
## desviacion_horaria     -0.84387739 -1.1544538
## log_intentos_fallidos   0.26837034 -0.4467930
## log_tiempo_entre_trans  0.87688890  0.2466753
## 
## Proportion of trace:
##    LD1    LD2 
## 0.9949 0.0051

Las probabilidades a priori indican que la mayoría de las observaciones pertenecen al grupo Normal (78%), seguido de Sospechosa (15%) y Fraude (7%).

La primera función discriminante (LD1) explica el 99.49% de la variabilidad, por lo que es la más importante para diferenciar los grupos.

  1. Escriba las funciones lineales discriminantes e interprete en cuanto a su importancia las funciones discriminantes.
library(MASS)
modelo<-lda(grupo ~ log_monto + log_trans_24h + log_distancia_km +
               desviacion_horaria + log_intentos_fallidos +
               log_tiempo_entre_trans,
               data = datos)
modelo
## Call:
## lda(grupo ~ log_monto + log_trans_24h + log_distancia_km + desviacion_horaria + 
##     log_intentos_fallidos + log_tiempo_entre_trans, data = datos)
## 
## Prior probabilities of groups:
##     Fraude     Normal Sospechosa 
##       0.07       0.78       0.15 
## 
## Group means:
##            log_monto log_trans_24h log_distancia_km desviacion_horaria
## Fraude      4.971090     2.3091132         4.077646          2.4002759
## Normal      3.601113     0.9908171         1.999379          0.4023653
## Sospechosa  4.274717     1.6754687         3.178935          1.3213661
##            log_intentos_fallidos log_tiempo_entre_trans
## Fraude                1.36071626               2.241785
## Normal                0.09083588               4.190407
## Sospechosa            0.68512138               3.226164
## 
## Coefficients of linear discriminants:
##                                LD1        LD2
## log_monto              -0.30193942 -0.2955025
## log_trans_24h          -0.06847524  0.3813189
## log_distancia_km       -0.62784855  1.4678456
## desviacion_horaria     -0.84387739 -1.1544538
## log_intentos_fallidos   0.26837034 -0.4467930
## log_tiempo_entre_trans  0.87688890  0.2466753
## 
## Proportion of trace:
##    LD1    LD2 
## 0.9949 0.0051

Las funciones discriminante son: LD1=−0.302log_monto−0.068log_trans_24h−0.628log_distancia_km−0.844desviacion_horaria+0.268log_intentos_fallidos+0.877log_tiempo_entre_trans LD2=−0.296log_monto+0.381log_trans_24h+1.468log_distancia_km−1.154desviacion_horaria−0.447log_intentos_fallidos+0.247log_tiempo_entre_trans

En conclusión, LD1 es la función principal de clasificación con un 99% , mientras que LD2 aporta muy poco a la discriminación con un 0.51%.

  1. Interprete la matriz de confusión
pred_train <- predict(lda_fit, newdata = datos)
m_confusion <- table(Real = datos$grupo, Predicho = pred_train$class)
m_confusion
##             Predicho
## Real         Fraude Normal Sospechosa
##   Fraude        290      1         59
##   Normal          0   3783        117
##   Sospechosa     41    223        486

el modelo presenta buen desempeño general de 75.8% destacando una alta capacidad para clasificar.(3783 aciertos). 10. Obtenga predicciones considerando valores supuestos de las variables independientes

nuevo <- data.frame(
  log_monto = 4,
  log_trans_24h = 1,
  log_distancia_km = 2,
  desviacion_horaria = 0.5,
  log_intentos_fallidos = 0.2,
  log_tiempo_entre_trans = 4
)

predict(lda_fit, nuevo)
## $class
## [1] Normal
## Levels: Fraude Normal Sospechosa
## 
## $posterior
##         Fraude    Normal Sospechosa
## 1 3.553829e-06 0.9805088 0.01948766
## 
## $x
##         LD1        LD2
## 1 0.3667314 -0.3418538

El modelo clasifica la observación como Normal, con una probabilidad de 0.98, muy superior a las demás. Esto indica una clasificación confiable.