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í.
Objetivos de Aprendizaje
Section titled “Objetivos de Aprendizaje”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.
Recursos y Datos
Section titled “Recursos y Datos”Para este proyecto trabajaremos con dos archivos obtenidos de un dataset clásico de redes sociales.
- Repositorio de datos: GitHub - josepgarcia/datos/superhero
Estructura de los Datos
Section titled “Estructura de los Datos”Marvel+Names: Diccionario que asocia IDs con nombres.- Formato:
ID "Nombre"
- Formato:
$ egrep SPIDER Marvel+Names | head -n 5400 "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.
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+Graph5988 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 44565989 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 39865982 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 60565983 1165 3836 4361 1282 716 4289 4646 6300 5084 2397 4454 1913 5861 54855980 2731 3712 1587 6084 2472 2546 6313 875 859 323 2664 1469 522 2506 2919 2423 3624 5736 5046 1787 5776 3245 3840 2399Cada 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.
Actividad 1: El Superhéroe Más Popular
Section titled “Actividad 1: El Superhéroe Más Popular”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:4pxPista: Cuantas más veces aparezca un ID en el archivo
Marvel+Graph(ya sea como protagonista o como acompañante), más popular es.
Pasos sugeridos
Section titled “Pasos sugeridos”- Carga el archivo
Marvel+Graph: Lee el archivo como texto. - Procesa las líneas: Cada línea es una lista de superhéroes que interactúan. Necesitas contar cada ocurrencia de cada ID.
- Map & Reduce:
- Usa
flatMappara separar los IDs. - Usa
mappara crear pares(ID, 1). - Usa
reduceByKeypara sumar las apariciones.
- Usa
- Ordena: Encuentra el ID con mayor número de apariciones (
sortByotop). - Revela la identidad: Cruza este ID con el archivo
Marvel+Namespara mostrar el nombre del superhéroe.
Actividad 2: El Superhéroe Menos Popular
Section titled “Actividad 2: El Superhéroe Menos Popular”Ahora buscaremos a los superhéroes más oscuros y desconocidos del universo Marvel. Específicamente, aquellos que tienen solamente 1 conexión.
Estrategia
Section titled “Estrategia”- Crea DataFrames: Carga
Marvel+Namesy tu resultado de conteos anterior (o procésalo de nuevo) como DataFrames. - Filtra: Busca aquellos registros donde el número de conexiones (co-apariciones) sea igual a 1.
- Join: Realiza un cruce (
join) entre tu DataFrame de “solitarios” y el DataFrame de nombres para obtener sus identidades. - Muestra los resultados: Imprime la lista de nombres.
Snippets de Ayuda
Section titled “Snippets de Ayuda”# Filtrar por valordf_filtrado = df.filter(func.col("count") == 1)
# Join entre dos DataFramesdf_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).
Concepto
Section titled “Concepto”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).
Guía de Implementación
Section titled “Guía de Implementación”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:4pxEste es un problema iterativo. Deberás “visitar” nodos capa por capa:
- Comienza con el Superhéroe Inicial (ej. Spider-Man, ID 5306). Marca su distancia como
0y su estado comoVISITADO. - Todos los demás superhéroes inician con distancia
infinitoy estadoNO_VISITADO. - Iteración:
- Para cada nodo
VISITADOen esta vuelta, busca sus conexiones. - A sus conexiones (si son
NO_VISITADO), márcalas comoVISITADO, establece su distancia comodistancia_actual + 1y anota de qué nodo vienen (“padre”). - Si encuentras al Superhéroe Objetivo (ej. Iron Man), ¡has terminado! La distancia acumulada es la respuesta.
- Para cada nodo
- 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.
Evaluación y Entrega
Section titled “Evaluación y Entrega”Criterios de Evaluación
Section titled “Criterios de Evaluación”| Criterio | Descripción | Puntos |
|---|---|---|
| Funcionalidad | El código compila y produce los resultados correctos para el superhéroe más y menos popular. | 40% |
| Uso de Spark | Uso 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ódigo | Código limpio, comentado y organizado. Variables con nombres descriptivos. | 10% |
Autoevaluación
Section titled “Autoevaluación”Antes de entregar, verifica:
- He eliminado rutas absolutas de mi código local.
- El código maneja correctamente la lectura de los archivos
Marvel+NamesyMarvel+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.).