En este pequeño ejemplo vamos a demostrar las capacidades para la detección del fraude de Neo4J (Base de datos orientada a grafos), que han hecho nuestros compañeros de Stratebi
Nuestro juego de datos incluye:
- 10 Personas (Nodos): Fernando, Juan, Daniel, Marcos...
- 13 Comercios (Nodos): Fnac, El Corte Inglés, Primark, Ikea...
- 64 Transacciones de compra (Relaciones) que identifican compras de una determinada persona en un comercio. Cada una de estas Relaciones tiene los siguientes atributos: cantidad de la compra en €, fecha y estado (legítima o fraudulenta).
// Crear Clientes 10
CREATE (Fernando:Persona {id:'1', nombre:'Fernando', sexo:'masculino', edad:'50'})
CREATE (Juan:Persona {id:'2', nombre:'Juan', sexo:'masculino', edad:'48'})
CREATE (Daniel:Persona {id:'3', nombre:'Daniel', sexo:'masculino', edad:'23'})
CREATE (Marcos:Persona {id:'4', nombre:'Marcos', sexo:'masculino', edad:'30'})
CREATE (Gonzalo:Persona {id:'5', nombre:'Gonzalo', sexo:'masculino', edad:'31'})
CREATE (Marta:Persona {id:'6', nombre:'Marta', sexo:'femenino', edad:'52'})
...
// Crear Comercios
CREATE (Fnac:Comercio {id:'11', nombre:'Fnac', calle:'2626 Wilkinson Court', address:'Madrid 92410'})
CREATE (El_Corte_Ingles:Comercio {id:'12', nombre:'El Corte Ingles', calle:'Nuevos Minist', address:'Madrid 92410'})
CREATE (Primark:Comercio {id:'13', nombre:'Primark', calle:'2092 Larry Street', address:'Madrid 92410'})
CREATE (MacDonalds:Comercio {id:'14', nombre:'MacDonalds', calle:'1870 Caynor Circle', address:'Madrid 92410'})
CREATE (Springfield:Comercio {id:'15', nombre:'Springfield', calle:'1381 Spruce Drive', address:'Madrid 92410'})
CREATE (Burguer_King:Comercio {id:'16', nombre:'Burguer King', calle:'826 Anmoore Road', address:'Madrid 92410'})
CREATE (Ikea:Comercio {id:'17', nombre:'Ikea', calle:'1925 Spring Street', address:'Madrid 92410'})
CREATE (Nike:Comercio {id:'18', nombre:'Nike', calle:'4209 Elsie Drive', address:'Madrid 92410'})
CREATE (Adidas:Comercio {id:'19', nombre:'Adidas', calle:'86 D Street', address:'Madrid 92410'})
CREATE (Sprinter:Comercio {id:'20', nombre:'Sprinter', calle:'945 Kinney Street', address:'Madrid 92410'})
CREATE (Starbucks:Comercio {id:'21', nombre:'Starbucks', calle:'3810 Apple Lane', address:'Madrid 92410'})
...
A continuación se muestra un subconjunto con 25 compras.
// Crear Compras
CREATE (Fernando)-[:HA_COMPRADO_EN {cantidad:'986', fecha:'4/17/2015', estado:'Legitima'}]->(Burguer_King)
CREATE (Fernando)-[:HA_COMPRADO_EN {cantidad:'239', fecha:'5/15/2015', estado:'Legitima'}]->(Starbucks)
CREATE (Fernando)-[:HA_COMPRADO_EN {cantidad:'475', fecha:'3/28/2015', estado:'Legitima'}]->(Nike)
CREATE (Fernando)-[:HA_COMPRADO_EN {cantidad:'654', fecha:'3/20/2015', estado:'Legitima'}]->(Primark)
CREATE (Juan)-[:HA_COMPRADO_EN {cantidad:'196', fecha:'7/24/2015', estado:'Legitima'}]->(Adidas)
CREATE (Juan)-[:HA_COMPRADO_EN {cantidad:'502', fecha:'4/9/2015', estado:'Legitima'}]->(El_Corte_Ingles)
CREATE (Juan)-[:HA_COMPRADO_EN {cantidad:'848', fecha:'5/29/2015', estado:'Legitima'}]->(Primark)
CREATE (Juan)-[:HA_COMPRADO_EN {cantidad:'802', fecha:'3/11/2015', estado:'Legitima'}]->(Fnac)
CREATE (Juan)-[:HA_COMPRADO_EN {cantidad:'203', fecha:'3/27/2015', estado:'Legitima'}]->(Subway)
CREATE (Daniel)-[:HA_COMPRADO_EN {cantidad:'35', fecha:'1/23/2015', estado:'Legitima'}]->(MacDonalds)
.....
Ahora vamos a comenzar a utilizar las capacidades de Cypher el lenguaje de consultas gráficas de Neo4J
1º Mostramos todas las operaciones fraudulentas
MATCH (victima:Persona)-[r:HA_COMPRADO_EN]->(comercio)
WHERE r.estado = "Fraudulenta"RETURN
victima.nombre AS `Nombre Cliente`,
comercio.nombre AS `Nombre Comercio`,
r.cantidad AS Cantidad,
r.fecha AS `Fecha Transaccion`
ORDER BY `Fecha Transaccion` DESC
Resultado: 16 Operaciones fraudulentas2º Hasta ahora sabemos cuales son los comercios en los que han ocurrido casos de fraude.
Pero existe un timador que estamos buscando, para ayudarnos a encontrarlo nos apoyaremos en la fecha de la transacción.
El ladrón que buscamos ha captado el nº de tárjeta de crédito en una compra legítima. Después de robar los datos de la tarjeta el ladrón ha realizado operaciones fraudulentas.
En la siguiente consulta mostraremos para personas han sido víctimas de fraude, operaciones de compra legítimas y anteriores en el tiempo a las fraudulentas. De esta forma nos aparecerán los comercios en los que se han podido robar el nº de la tarjeta.
MATCH (victima:Persona)-[r:HA_COMPRADO_EN]->(comercio)
WHERE r.estado = "Fraudulenta"
MATCH (victima)-[t:HA_COMPRADO_EN]->(otroscomercios)
WHERE t.estado = "Legitima"AND t.fecha < r.fecha
WITH victima, otroscomercios, t
ORDER BY t.fecha DESC
RETURN
victima.nombre AS `Nombre Cliente`,
otroscomercios.nombre AS `Nombre Comercio`,
t.cantidad AS Cantidad,
t.fecha AS `Fecha Transaccion`
ORDER BY `Fecha Transaccion` DESC
Resultado: 34 operaciones legítimas y anteriores en el tiempo a las fraudulentas
3º Ahora vamos a calcular el denominador común, agrupamos y ordenamos por el nº de personas que han comprado en cada comercio.
MATCH (victima:Persona)-[r:HA_COMPRADO_EN]->(comercio)
WHERE r.estado = "Fraudulenta"
MATCH (victima)-[t:HA_COMPRADO_EN]->(otroscomercios)
WHERE t.estado = "Legitima"AND t.fecha < r.fecha
WITH victima, otroscomercios, t ORDER BY t.fecha DESC
RETURN
DISTINCT otroscomercios.nombre AS `Comercio Sospechoso`,
count(DISTINCT t) AS Contador,
collect(DISTINCT victima.nombre) AS Victimas
ORDER BY Contador DESC
Resultado: En todas las compras fraudulentas la persona propietaria de la tarjeta había realizado alguna compra en Primark en los días anteriores. Ahora ya sabemos tanto la fecha como el comercio donde fueron robados los datos bancarios.
Visualizamos ahora ordenadas por fecha las compras de las víctimas, de esta forma sabemos la fecha del robo de los datos.