2024-2023 Universidades
Taller 1 - Introducción a los Grafos
Vamos a desglosar los conceptos fundamentales de Neo4J y los grafos en general,
explicando cada término y proporcionando ejemplos claros. Luego, discutiremos los usos,
ventajas y desventajas de los grafos, con un ejemplo específico de operaciones con tarjeta
de crédito y detección de fraude.
Conceptos Fundamentales
1. Nodo (Node):
✓ Descripción: Los nodos representan entidades u objetos en el grafo. Cada nodo puede
tener propiedades (pares clave-valor) que describen sus atributos.
✓ Ejemplo: Un nodo que representa a un cliente.
```cypher
CREATE (c:Cliente {nombre: 'Juan Pérez', id: 123, edad: 30})
CREATE (c:Cliente {nombre: 'Ana Paz', id: 155, edad: 32})
CREATE (d:Compra {comercio: 'Plaza Norte II', id: 1001, telefono:
45896325, dirección: 'San Sebastián, Madrid', fecha: '2024-06-04'})
```
2. Relación (Relationship):
✓ Descripción: Las relaciones conectan dos nodos y también pueden tener
propiedades. Representan la forma en que los nodos están interconectados.
✓ Ejemplo: Una relación que indica que un cliente realizó una compra.
```cypher
MATCH (c:Cliente {id: 123}), (com:Compra {id: 1001})
CREATE (c)-[:REALIZA]->(com)
```
3. Arista (Edge):
✓ Descripción: En el contexto de grafos, una arista es otro término para una relación,
describiendo la conexión entre dos nodos.
✓ Ejemplo: En el ejemplo anterior, `[:REALIZA]` es una arista que conecta el nodo
`Cliente` con el nodo `Compra`.
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
4. Etiqueta (Label):
✓ Descripción: Las etiquetas se utilizan para clasificar los nodos. Un nodo puede tener
una o más etiquetas.
✓ Ejemplo: `:Cliente` es una etiqueta que se le asigna a un nodo que representa a un
cliente.
```cypher
CREATE (c:Cliente {nombre: 'Juan Pérez', id: 123, edad: 30})
```
5. Propiedad (Property):
✓ Descripción: Las propiedades son atributos de nodos o relaciones, almacenados
como pares clave-valor.
✓ Ejemplo: El nodo `Cliente` tiene propiedades como `nombre`, `id`, y `edad`.
```cypher
CREATE (c:Cliente {nombre: 'Juan Pérez', id: 123, edad: 30})
```
Usos de los Grafos
Los grafos se utilizan para modelar datos que están altamente interconectados y donde las
relaciones entre los datos son tan importantes como los propios datos.
Ventajas:
• Eficiencia en consultas de relaciones: Los grafos son muy eficientes para
consultas que exploran relaciones múltiples grados de separación.
• Flexibilidad: Pueden evolucionar fácilmente con nuevos tipos de nodos y
relaciones sin necesidad de una estructura rígida.
• Visualización intuitiva: Los datos pueden ser visualizados de una manera que
muestra claramente las conexiones y patrones.
Desventajas:
1. Escalabilidad: Pueden tener problemas de rendimiento con grafos
extremadamente grandes y densos.
2. Complejidad: La modelación y gestión de grafos puede ser más compleja que
otros tipos de bases de datos.
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
Ejemplo de Uso: Detección de Fraude en Operaciones con Tarjeta de Crédito
Escenario: Un banco quiere detectar patrones de fraude en transacciones con tarjetas de
crédito.
Modelo de Grafo:
✓ Nodos:
o `Cliente`: Representa a un cliente del banco.
o `Tarjeta`: Representa una tarjeta de crédito.
o `Transacción`: Representa una operación con la tarjeta.
o `Tienda`: Representa un establecimiento comercial.
✓ Relaciones:
o `POSEE`: Relaciona un cliente con una tarjeta de crédito.
o `USA`: Relaciona una tarjeta con una transacción.
o `REALIZA`: Relaciona un cliente con una transacción.
o `OCURRE_EN`: Relaciona una transacción con una tienda.
Ejemplo de Creación en Neo4J:
```cypher
// Crear nodos
CREATE (c:Cliente {nombre: 'Ana García', id: 1})
CREATE (t:Tarjeta {numero: '1234-5678-9876-5432', id: 1})
CREATE (tr:Transacción {id: 1, monto: 500.00, fecha: '2024-06-04'})
CREATE (ti: Tienda {nombre: 'Supermercado XYZ', id: 1})
// Crear relaciones
MATCH (c:Cliente {id: 1}), (t:Tarjeta {id: 1})
CREATE (c)-[:POSEE]->(t)
MATCH (t:Tarjeta {id: 1}), (tr:Transacción {id: 1})
CREATE (t)-[:USA]->(tr)
MATCH (c:Cliente {id: 1}), (tr:Transacción {id: 1})
CREATE (c)-[:REALIZA]->(tr)
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
MATCH (tr:Transacción {id: 1}), (ti:Tienda {id: 1})
CREATE (tr)-[:OCURRE_EN]->(ti)
// tiempo después llega la siguiente información
CREATE (c:Cliente {nombre: 'Pablo Malote', id: 12})
CREATE (tr:Transacción {id: 2, monto: 655.00, fecha: '2024-06-04'})
CREATE (tr:Transacción {id: 3, monto: 850.00, fecha: '2024-06-04'})
CREATE (ti: Tienda {nombre: 'Xanadú', id: 15})
CREATE (ti: Tienda {nombre: 'Parque Sur', id: 43})
MATCH (t:Tarjeta {id: 1}), (tr:Transacción {id: 2})
CREATE (t)-[:USA]->(tr)
MATCH (t:Tarjeta {id: 1}), (tr:Transacción {id: 3})
CREATE (t)-[:USA]->(tr)
MATCH (tr:Transacción {id: 2}), (ti:Tienda {id: 15})
CREATE (tr)-[:OCURRE_EN]->(ti)
MATCH (tr:Transacción {id: 3}), (ti:Tienda {id: 43})
CREATE (tr)-[:OCURRE_EN]->(ti)
MATCH (c:Cliente {id: 12}), (tr:Transacción {id: 2})
CREATE (c)-[:REALIZA]->(tr)
MATCH (c:Cliente {id: 12}), (tr:Transacción {id: 3})
CREATE (c)-[:REALIZA]->(tr)
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
Detección de Fraude:
Para detectar fraude, podríamos buscar patrones sospechosos como transacciones en
lugares geográficamente distantes en un corto período de tiempo, o múltiples
transacciones en diferentes tiendas con la misma tarjeta en un tiempo reducido.
Consulta de Ejemplo:
```cypher
// Encontrar transacciones sospechosas
MATCH (t:Tarjeta)-[:USA]->(tr1:Transacción)-[:OCURRE_EN]-
>(ti1:Tienda),
(t)-[:USA]->(tr2:Transacción)-[:OCURRE_EN]->(ti2:Tienda)
WHERE tr1.fecha = '2024-06-04' AND tr2.fecha = '2024-06-04' AND
ti1.nombre <> ti2.nombre
RETURN t.numero, tr1.id, ti1.nombre, tr2.id, ti2.nombre
```
Este ejemplo muestra cómo los grafos pueden ser utilizados para detectar fraudes al
identificar patrones y relaciones complejas entre los datos.
Borrar todos los nodos y sus relaciones:
```cypher
MATCH (n)
DETACH DELETE n;
```
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
Taller 2 - Repaso de Neo4J Cypher
Vamos a crear un pequeño taller de introducción a Neo4J y su lenguaje de consulta, Cypher.
Comenzaremos con los conceptos básicos y luego agregaremos complejidad
gradualmente.
Paso 1: Crear Nodos Básicos
En Neo4J, los nodos representan entidades. Vamos a crear nodos para `Proveedor`,
`Cliente`, `Compra` y `Tienda`.
```cypher
// Crear un nodo Proveedor
CREATE (p:Proveedor {nombre: 'Proveedor A', id: 1})
// Crear un nodo Cliente
CREATE (c:Cliente {nombre: 'Cliente 1', id: 101})
// Crear un nodo Tienda
CREATE (t:Tienda {nombre: 'Tienda Central', id: 201})
// Crear un nodo Compra
CREATE (com:Compra {id: 301, fecha: '2024-06-04', total: 150.00})
```
Paso 2: Crear Relaciones Entre Nodos
Ahora, conectaremos estos nodos con relaciones. Las relaciones en Neo4J tienen
direcciones y pueden tener propiedades.
```cypher
// Relacionar Proveedor con Tienda
MATCH (p:Proveedor {id: 1}), (t:Tienda {id: 201})
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
CREATE (p)-[:SUMINISTRA_A]->(t)
// Relacionar Cliente con Tienda
MATCH (c:Cliente {id: 101}), (t:Tienda {id: 201})
CREATE (c)-[:COMPRA_EN]->(t)
// Relacionar Cliente con Compra
MATCH (c:Cliente {id: 101}), (com:Compra {id: 301})
CREATE (c)-[:REALIZA]->(com)
// Relacionar Tienda con Compra
MATCH (t:Tienda {id: 201}), (com:Compra {id: 301})
CREATE (t)-[:VENDE]->(com)
```
Paso 3: Agregar Más Propiedades y Relaciones
Para hacer el modelo más interesante, vamos a agregar más detalles.
1. Agregar más atributos a los nodos y relaciones.
2. Crear más nodos y relaciones.
```cypher
// Crear otro nodo Proveedor
CREATE (p2:Proveedor {nombre: 'Proveedor B', id: 2})
// Crear otro nodo Cliente
CREATE (c2:Cliente {nombre: 'Cliente 2', id: 102})
// Crear otra Compra
CREATE (com2:Compra {id: 302, fecha: '2024-06-05', total: 200.00})
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
// Relacionar el nuevo Proveedor con la Tienda
MATCH (p2:Proveedor {id: 2}), (t:Tienda {id: 201})
CREATE (p2)-[:SUMINISTRA_A {fecha_suministro: '2024-06-03'}]->(t)
// Relacionar el nuevo Cliente con la Tienda
MATCH (c2:Cliente {id: 102}), (t:Tienda {id: 201})
CREATE (c2)-[:COMPRA_EN {frecuencia: 'mensual'}]->(t)
// Relacionar el nuevo Cliente con la nueva Compra
MATCH (c2:Cliente {id: 102}), (com2:Compra {id: 302})
CREATE (c2)-[:REALIZA]->(com2)
// Relacionar la Tienda con la nueva Compra
MATCH (t:Tienda {id: 201}), (com2:Compra {id: 302})
CREATE (t)-[:VENDE {metodo_pago: 'tarjeta'}]->(com2)
```
Consulta de Datos
Para verificar los datos que hemos ingresado, podemos realizar algunas consultas.
Consultar todos los nodos y relaciones
```cypher
MATCH (n)
RETURN n
```
Consultar todos los clientes y sus compras
```cypher
MATCH (c:Cliente)-[:REALIZA]->(com:Compra)
RETURN c.nombre, com.id, com.fecha, com.total
```
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
Consultar proveedores y tiendas que suministran
```cypher
MATCH (p:Proveedor)-[:SUMINISTRA_A]->(t:Tienda)
RETURN p.nombre, t.nombre
```
Consultar tiendas y compras
```cypher
MATCH (t:Tienda)-[:VENDE]->(com:Compra)
RETURN t.nombre, com.id, com.total
```
Conclusión
Hemos cubierto lo básico de Neo4J y Cypher, desde la creación de nodos y relaciones hasta
la realización de consultas simples. Con estos fundamentos, puedes seguir explorando
Neo4J para crear gráficos más complejos y realizar análisis avanzados.
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
Taller 3 - Ejercicio de Modelado de Grafos para
Apuestas Deportivas
Vamos a modelar un escenario de apuestas deportivas utilizando conceptos como casas
de apuestas, juegos, ciudades, casinos, jugadores, apuestas online, apuestas en casinos,
y montos de juego. Este ejemplo también incluirá cómo podríamos detectar patrones
anómalos como ludopatía o apuestas amañadas.
Nodos y Relaciones
✓ Nodos:
o `CasaDeApuestas`: Representa una casa de apuestas (e.g., Bet365, William
Hill, Bwin).
o `Juego`: Representa un evento deportivo (e.g., Partido de Fútbol, Carrera de
Caballos).
o `Ciudad`: Representa una ciudad en España (e.g., Madrid, Barcelona).
o `Casino`: Representa un casino físico (e.g., Casino Gran Madrid).
o `Jugador`: Representa a una persona que realiza apuestas.
o `Apuesta`: Representa una apuesta específica (e.g., monto, tipo de apuesta).
✓ Relaciones:
o `OFRECE`: Relaciona una `CasaDeApuestas` con un `Juego`.
o `UBICADO_EN`: Relaciona un `Casino` con una `Ciudad`.
o `APUESTA_EN`: Relaciona un `Jugador` con un `Juego`.
o `REALIZA_APU`: Relaciona un `Jugador` con una `Apuesta`.
o `SE_REALIZA_EN`: Relaciona una `Apuesta` con una `CasaDeApuestas` o
`Casino`.
Ejemplo de Creación en Neo4J
1. Crear nodos de Casas de Apuestas:
```cypher
CREATE (c1:CasaDeApuestas {nombre: 'Bet365', id: 1})
CREATE (c2:CasaDeApuestas {nombre: 'William Hill', id: 2})
CREATE (c3:CasaDeApuestas {nombre: 'Bwin', id: 3})
```
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
2. Crear nodos de Juegos:
```cypher
CREATE (j1:Juego {nombre: 'Partido Real Madrid vs Barcelona', id: 101,
fecha: '2024-06-10'})
CREATE (j2:Juego {nombre: 'Final Copa del Rey', id: 102, fecha: '2024-
07-01'})
```
3. Crear nodos de Ciudades y Casinos:
```cypher
CREATE (ci1:Ciudad {nombre: 'Madrid', id: 201})
CREATE (ci2:Ciudad {nombre: 'Barcelona', id: 202})
CREATE (ca1:Casino {nombre: 'Casino Gran Madrid', id: 301})
CREATE (ca2:Casino {nombre: 'Casino Barcelona', id: 302})
// Relacionar Casinos con Ciudades
MATCH (ca1:Casino {id: 301}), (ci1:Ciudad {id: 201})
CREATE (ca1)-[:UBICADO_EN]->(ci1);
MATCH (ca2:Casino {id: 302}), (ci2:Ciudad {id: 202})
CREATE (ca2)-[:UBICADO_EN]->(ci2);
```
4. Crear nodos de Jugadores:
```cypher
CREATE (j1:Jugador {nombre: 'Carlos López', id: 401})
CREATE (j2:Jugador {nombre: 'Ana Martínez', id: 402})
```
5. Crear nodos de Apuestas y relacionarlas:
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
```cypher
// Apuestas Online
CREATE (a1:Apuesta {id: 501, monto: 100.00, tipo: 'online', fecha:
'2024-06-08'})
CREATE (a2:Apuesta {id: 502, monto: 200.00, tipo: 'online', fecha:
'2024-06-09'})
// Apuestas en Casino
CREATE (a3:Apuesta {id: 503, monto: 300.00, tipo: 'casino', fecha:
'2024-06-08'})
CREATE (a4:Apuesta {id: 504, monto: 400.00, tipo: 'casino', fecha:
'2024-06-09'})
// Relacionar Jugadores con Apuestas
MATCH (j1:Jugador {id: 401}), (a1:Apuesta {id: 501})
CREATE (j1)-[:REALIZA_APU]->(a1);
MATCH (j2:Jugador {id: 402}), (a2:Apuesta {id: 502})
CREATE (j2)-[:REALIZA_APU]->(a2);
MATCH (j1:Jugador {id: 401}), (a3:Apuesta {id: 503})
CREATE (j1)-[:REALIZA_APU]->(a3);
MATCH (j2:Jugador {id: 402}), (a4:Apuesta {id: 504})
CREATE (j2)-[:REALIZA_APU]->(a4);
// Relacionar Apuestas con Casas de Apuestas y Casinos
MATCH (a1:Apuesta {id: 501}), (c1:CasaDeApuestas {id: 1})
CREATE (a1)-[:SE_REALIZA_EN]->(c1);
MATCH (a2:Apuesta {id: 502}), (c2:CasaDeApuestas {id: 2})
CREATE (a2)-[:SE_REALIZA_EN]->(c2);
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
MATCH (a3:Apuesta {id: 503}), (ca1:Casino {id: 301})
CREATE (a3)-[:SE_REALIZA_EN]->(ca1);
MATCH (a4:Apuesta {id: 504}), (ca2:Casino {id: 302})
CREATE (a4)-[:SE_REALIZA_EN]->(ca2);
```
Consultas para Detectar Patrones Anómalos
1. Detección de Ludopatía:
✓ Buscamos jugadores que han realizado un número elevado de apuestas en un corto
período de tiempo.
```cypher
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)
WITH j, COUNT(a) AS numApuestas
WHERE numApuestas > 10
RETURN j.nombre, numApuestas;
```
2. Apuestas Amañadas:
✓ Identificamos si hay patrones de apuestas grandes en juegos específicos por
múltiples jugadores.
```cypher
MATCH (a:Apuesta)-[:SE_REALIZA_EN]->(c:CasaDeApuestas),
(j:Jugador)-[:REALIZA_APU]->(a)
WHERE a.monto > 100
RETURN DISTINCT a.id, a.monto, c.nombre
```
3. Jugadores con Apuestas en Múltiples Casas o Casinos:
✓ Detectamos jugadores que apuestan tanto online como en casinos, lo que puede
indicar un comportamiento de alto riesgo.
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
```cypher
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)-[:SE_REALIZA_EN]->(e)
WITH j, COLLECT(DISTINCT e.nombre) AS lugares
WHERE SIZE(lugares) > 1
RETURN j.nombre, lugares
```
Otras consultas sobre el modelo
Aquí tienes tres consultas adicionales para detectar patrones de amaño de apuestas y
múltiples apuestas respectivamente.
Consultas para Detectar Amaño de Apuestas
1. Identificar Jugadores que Apuestan Grandes Montos en Juegos Específicos
Repetidamente:
• Buscamos jugadores que han apostado grandes montos en el mismo juego en
múltiples ocasiones.
```cypher
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)
WHERE a.monto > 100
RETURN j.nombre, COUNT(a) AS numApuestas, SUM(a.monto) AS
totalApostado
ORDER BY totalApostado DESC
```
2. Detectar Patrón de Apuestas Grandes en Corto Período de Tiempo Antes del Juego:
• Identificamos apuestas grandes realizadas justo antes del inicio de un juego, lo cual
puede indicar información privilegiada.
```cypher
MATCH (a:Apuesta)
WHERE a.monto > 100 AND date(a.fecha) >= date() - duration({days: 1})
RETURN a.id, a.monto, a.fecha
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
ORDER BY a.fecha DESC
```
3. Buscar Jugadores que Apuestan Grandes Montos en Múltiples Juegos en un Día:
- Detectamos jugadores que realizan apuestas grandes en múltiples juegos el mismo día,
lo que puede indicar intentos de manipulación.
```Cypher
// Seguramente haya que condicionar los datos para encontrar este patrón
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)
WHERE a.monto > 100
WITH j, date(a.fecha) AS dia, COUNT(DISTINCT a) AS numJuegos
WHERE numJuegos > 1
RETURN j.nombre, dia, numJuegos
ORDER BY numJuegos DESC
```
Consultas para Detectar Múltiples Apuestas
1. Identificar Jugadores que Realizan Muchas Apuestas en Diferentes Casas en un
Corto Período de Tiempo:
• Buscamos jugadores que han realizado muchas apuestas en diferentes casas de
apuestas en una semana.
```Cypher
// Seguramente haya que condicionar los datos para encontrar este patrón
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)-[:SE_REALIZA_EN]-
>(c:CasaDeApuestas)
WHERE date(a.fecha) >= date() - duration({days: 7})
RETURN j.nombre, COUNT(DISTINCT c) AS numCasas, COUNT(a) AS
numApuestas
ORDER BY numCasas DESC, numApuestas DESC
```
2. Detectar Jugadores que Apuestan en Ambos Juegos Online y en Casinos Físicos:
• Identificamos jugadores que han realizado apuestas tanto online como en casinos
físicos.
```cypher
// Seguramente haya que condicionar los datos para encontrar este patrón
Autor: Marlon Cárdenas Bonett
2024-2023 Universidades
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)-[:SE_REALIZA_EN]->(e)
WITH j, COLLECT(DISTINCT e.tipo) AS tipos
WHERE 'online' IN tipos AND 'casino' IN tipos
RETURN j.nombre, tipos
```
3. Buscar Jugadores con Apuestas Frecuentes en Múltiples Juegos en un Mes:
- Detectamos jugadores que han realizado apuestas en un gran número de juegos
diferentes en el último mes.
```cypher
// Seguramente haya que condicionar los datos para encontrar este patrón
MATCH (j:Jugador)-[:REALIZA_APU]->(a:Apuesta)
WHERE date(a.fecha) >= date() - duration({days: 30})
RETURN j.nombre, COUNT(DISTINCT a) AS numJuegos, COUNT(a) AS numApuestas
ORDER BY numJuegos DESC, numApuestas DESC
```
Conclusión
Este ejercicio de modelado de grafos en el contexto de apuestas deportivas permite
analizar y detectar patrones anómalos como la ludopatía y apuestas amañadas. Utilizando
nodos y relaciones, podemos crear un modelo detallado que refleje las complejas
interacciones en el mundo de las apuestas, proporcionando una base para análisis
avanzados y detección de comportamientos sospechosos.
Las consultas adicionales permiten identificar patrones sospechosos en el
comportamiento de los apostadores, tanto en términos de posibles amaños de apuestas
como en la frecuencia y variedad de sus apuestas. Al analizar estos patrones, las casas de
apuestas pueden detectar comportamientos anómalos que podrían indicar fraude o
problemas de adicción al juego.
Autor: Marlon Cárdenas Bonett