Skip to content

Proyecto: Marvel

En este proyecto aplicarás los conocimientos adquiridos sobre Apache Spark, RDDs y DataFrames para analizar un grafo de relaciones sociales. Utilizaremos datos reales del Universo Marvel para descubrir quiénes son los superhéroes más populares y cómo están conectados entre sí.

Al finalizar esta práctica, serás capaz de:

  • Cargar y procesar archivos de texto no estructurados con Spark.
  • Aplicar transformaciones y acciones sobre RDDs y DataFrames.
  • Realizar operaciones de limpieza, filtrado y join de datos.
  • Entender e implementar algoritmos iterativos (como BFS) en un entorno distribuido.

Para este proyecto trabajaremos con dos archivos obtenidos de un dataset clásico de redes sociales.

  1. Marvel+Names: Diccionario que asocia IDs con nombres.
    • Formato: ID "Nombre"
$ egrep SPIDER Marvel+Names | head -n 5
400 "BEACH, SPIDER"
603 "BLOOD SPIDER/"
3413 "MAN-SPIDER | MUTANT "
3414 "MAN-SPIDER CLONE | M"
5306 "SPIDER-MAN/PETER PAR"

Contiene un identificador único y el nombre del superhéroe.

  1. Marvel+Graph: Grafo de relaciones (co-apariciones en cómics).
    • Formato: Una lista de IDs separados por espacios.
    • Significado: El primer ID es el superhéroe “protagonista” del cómic, y los siguientes son los superhéroes que aparecen con él.
$ head -n 5 Marvel+Graph
5988 748 1722 3752 4655 5743 1872 3413 5527 6368 6085 4319 4728 1636 2397 3364 4001 1614 1819 1585 732 2660 3952 2507 3891 2070 2239 2602 612 1352 5447 4548 1596 5488 1605 5517 11 479 2554 2043 17 865 4292 6312 473 534 1479 6375 4456
5989 4080 4264 4446 3779 2430 2297 6169 3530 3272 4282 6432 2548 4140 185 105 3878 2429 1334 4595 2767 3956 3877 4776 4946 3407 128 269 5775 5121 481 5516 4758 4053 1044 1602 3889 1535 6038 533 3986
5982 217 595 1194 3308 2940 1815 794 1503 5197 859 5096 6039 2664 651 2244 528 284 1449 1097 1172 1092 108 3405 5204 387 4607 4545 3705 4930 1805 4712 4404 247 4754 4427 1845 536 5795 5978 533 3984 6056
5983 1165 3836 4361 1282 716 4289 4646 6300 5084 2397 4454 1913 5861 5485
5980 2731 3712 1587 6084 2472 2546 6313 875 859 323 2664 1469 522 2506 2919 2423 3624 5736 5046 1787 5776 3245 3840 2399

Cada fila representa un cómic distinto. En cada fila, el primer campo indica el protagonista del cómic, seguido de los superhéroes que también aparecen en ese cómic. Un superhéroe puede ser el protagonista y puede aparecer en N cómics.


Tu primer objetivo es determinar quién es el superhéroe más “popular”. Definiremos popularidad como el número total de co-apariciones (colaboraciones) que tiene un personaje.

graph TD
Hero((Superhéroe Popular))
Hero --- A[Hero1]
Hero --- B[Hero2]
Hero --- C[Hero3]
Hero --- D[Hero4]
style Hero fill:#f96,stroke:#333,stroke-width:4px

Pista: Cuantas más veces aparezca un ID en el archivo Marvel+Graph (ya sea como protagonista o como acompañante), más popular es.

  1. Carga el archivo Marvel+Graph: Lee el archivo como texto.
  2. Procesa las líneas: Cada línea es una lista de superhéroes que interactúan. Necesitas contar cada ocurrencia de cada ID.
  3. Map & Reduce:
    • Usa flatMap para separar los IDs.
    • Usa map para crear pares (ID, 1).
    • Usa reduceByKey para sumar las apariciones.
  4. Ordena: Encuentra el ID con mayor número de apariciones (sortBy o top).
  5. Revela la identidad: Cruza este ID con el archivo Marvel+Names para mostrar el nombre del superhéroe.

Ahora buscaremos a los superhéroes más oscuros y desconocidos del universo Marvel. Específicamente, aquellos que tienen solamente 1 conexión.

  1. Crea DataFrames: Carga Marvel+Names y tu resultado de conteos anterior (o procésalo de nuevo) como DataFrames.
  2. Filtra: Busca aquellos registros donde el número de conexiones (co-apariciones) sea igual a 1.
  3. Join: Realiza un cruce (join) entre tu DataFrame de “solitarios” y el DataFrame de nombres para obtener sus identidades.
  4. Muestra los resultados: Imprime la lista de nombres.
# Filtrar por valor
df_filtrado = df.filter(func.col("count") == 1)
# Join entre dos DataFrames
df_resultado = df_filtrado.join(df_nombres, "id")
# Obtener un valor escalar (mínimo)
min_val = df.agg(func.min("count")).first()[0]

Extra (Opcional): En lugar de asumir que el mínimo es 1, calcula cuál es el número mínimo de conexiones real en el dataset y filtra por ese valor dinámicamente.


Actividad 3: Grados de Separación (Avanzado)

Section titled “Actividad 3: Grados de Separación (Avanzado)”

¿Qué tan lejos está Spider-Man de Iron Man? Esta actividad consiste en encontrar los “grados de separación” entre dos superhéroes utilizando el algoritmo Breadth-First Search (BFS) (Búsqueda en Anchura).

Si Spider-Man conoce a Hulk, están a 1 grado de separación. Si Hulk conoce a Iron Man, entonces Spider-Man y Iron Man están a 2 grados de separación (a través de Hulk).

Para entender mejor este concepto, observa el siguiente diagrama de relaciones:

graph LR
A[Spider-Man] -- 1 grado --> B[Hulk]
B -- 1 grado --> C[Iron Man]
A -.-> |2 grados| C
style A fill:#f9f,stroke:#333,stroke-width:4px
style C fill:#bbf,stroke:#333,stroke-width:4px

Este es un problema iterativo. Deberás “visitar” nodos capa por capa:

  1. Comienza con el Superhéroe Inicial (ej. Spider-Man, ID 5306). Marca su distancia como 0 y su estado como VISITADO.
  2. Todos los demás superhéroes inician con distancia infinito y estado NO_VISITADO.
  3. Iteración:
    • Para cada nodo VISITADO en esta vuelta, busca sus conexiones.
    • A sus conexiones (si son NO_VISITADO), márcalas como VISITADO, establece su distancia como distancia_actual + 1 y anota de qué nodo vienen (“padre”).
    • Si encuentras al Superhéroe Objetivo (ej. Iron Man), ¡has terminado! La distancia acumulada es la respuesta.
  4. Repite hasta encontrar el objetivo.

Recurso: Puedes basarte en explicaciones visuales de BFS para grafos, como este video o el artículo de Wikipedia sobre Búsqueda en anchura.


CriterioDescripciónPuntos
FuncionalidadEl código compila y produce los resultados correctos para el superhéroe más y menos popular.40%
Uso de SparkUso correcto de transformaciones (map, flatMap, reduceByKey) y acciones. Uso eficiente de DataFrames.30%
BFS (Bonus)Implementación correcta o intento lógico del algoritmo de grados de separación.20%
Calidad de CódigoCódigo limpio, comentado y organizado. Variables con nombres descriptivos.10%

Antes de entregar, verifica:

  • He eliminado rutas absolutas de mi código local.
  • El código maneja correctamente la lectura de los archivos Marvel+Names y Marvel+Graph.
  • He verificado que el superhéroe más popular tiene sentido (suele ser uno de los grandes conocidos como Spider-Man, Capitán América, etc.).