Python

Análisis de Redes con Python

Durante nuestra serie sobre análisis de redes en R, exploramos en profundidad diversas métricas de centralidad utilizando el paquete igraph. En esta entrada, veremos cómo reproducir esos mismos análisis en Python mediante la biblioteca networkx.

El objetivo es ofrecer una visión paralela que permita a los lectores comparar ambos entornos —R y Python— y elegir el más adecuado según sus necesidades específicas, ya sea por razones técnicas, de familiaridad con el lenguaje o por requerimientos de interoperabilidad con otros análisis o procesos.

A diferencia de las publicaciones anteriores, en esta ocasión no profundizaremos en la teoría que sustenta cada métrica, ya que esos conceptos fueron tratados ampliamente en las entradas dedicadas a igraph. Aquí nos centraremos en la parte práctica: cómo implementar estas métricas en Python, cómo visualizar los resultados de forma efectiva y cómo construir tablas que nos ayuden a comparar las distintas medidas. Cerraremos con un análisis comparativo de las ventajas y desventajas de igraph y networkx para el análisis de redes.

El paquete networkx en Python

networkx es la biblioteca más utilizada en Python para la creación, manipulación y análisis de grafos. Diseñada para ser simple y versátil, permite trabajar con grafos dirigidos y no dirigidos, multigrafos y grafos ponderados. Además, implementa muchos de los algoritmos clásicos del análisis de redes, incluyendo distintas centralidades, detección de comunidades, caminos más cortos y más.

Aunque en términos de rendimiento networkx no es tan eficiente como igraph cuando se trabaja con redes de gran tamaño, su integración con bibliotecas de visualización como matplotlib la hace ideal para proyectos académicos, prototipos y visualizaciones interactivas.

En cuanto a las métricas de centralidad, networkx ofrece soporte para, entre otras, las siguientes medidas:

  • Centralidad de grado (degree_centrality)
  • Centralidad de intermediación (betweenness_centrality)
  • Centralidad de cercanía (closeness_centrality)
  • Centralidad de autovector (eigenvector_centrality)
  • PageRank (pagerank)
  • HITS (hits, que devuelve hubs y authorities)
  • Katz (katz_centrality)

Cabe destacar que networkx no incluye herramientas de visualización por defecto, por lo que generalmente se complementa con bibliotecas como matplotlib para representar gráficamente las redes.

Características principales de networkx

Entre las principales características de la biblioteca networkx se pueden destacar los siguientes puntos:

  • Representación flexible de grafos (listas de adyacencia, listas de aristas, diccionarios).
  • Implementación de las principales métricas de centralidad y algoritmos de grafos.
  • Compatibilidad con bibliotecas de visualización como matplotlib, plotly y pyvis.
  • Gran comunidad de usuarios y documentación extensa.
  • Integración sencilla con pandas y numpy para análisis y manipulación de datos.

Instalación de networkx

Como es habitual, si no dispones de networkx en tu distribución de Python se puede instalar mediante pip, para ello ejecuta el siguiente comando:

pip install networkx

Implementación de las métricas de centralidad en Python

A continuación, presentamos un ejemplo práctico que incluye una red dirigida simulada y el cálculo de varias métricas de centralidad: Grado, Intermediación, Cercanía, Autovector, Katz, PageRank y HITS. Para mantener el ejemplo claro y manejable, utilizaremos un grafo pequeño pero ilustrativo.

import networkx as nx
import matplotlib.pyplot as plt

# Crear un grafo dirigido
G = nx.DiGraph()

# Agregar nodos y aristas
edges = [("A", "B"), ("A", "C"), ("B", "D"),
         ("C", "D"), ("D", "E"), ("E", "F"),
         ("F", "D"), ("C", "F"), ("F", "B")]
G.add_edges_from(edges)

# Dibujar grafo
pos = nx.spring_layout(G, seed=42)
nx.draw(G, pos, with_labels=True,
        node_color='lightblue',
        node_size=1000,
        edge_color='gray',
        font_size=12,
        font_weight='bold')
plt.title("Red de ejemplo")
plt.show()

En el bloque de código anterior se implementa un grafo dirigido sencillo, compuesto por unos pocos nodos y aristas que nos permitirán ilustrar de manera clara el cálculo de diferentes métricas de centralidad. Este tipo de grafo es ideal para fines pedagógicos, ya que su tamaño reducido facilita la interpretación visual y la comprensión de los conceptos clave del análisis de redes.

La representación visual generada muestra cómo están conectados los nodos y nos servirá como base para interpretar los resultados de cada métrica. En la siguiente figura se puede observar el grafo resultante, donde cada nodo representa una entidad y cada arista indica una relación o flujo de información entre ellas.

Visualización de un grafo dirigido de ejemplo, donde los nodos representan entidades y las aristas indican relaciones o conexiones entre ellas.

Centralidad de grado

La centralidad de grado mide cuántas conexiones directas tiene un nodo. Es una de las formas más simples de centralidad y resulta útil en redes donde la visibilidad o accesibilidad inmediata es relevante.

degree = nx.degree_centrality(G)

print("Centralidad de Grado:")
for nodo, valor in degree.items():
    print(f"{nodo}: {valor:.3f}")
Centralidad de Grado:
A: 0.400
B: 0.600
C: 0.600
D: 0.800
E: 0.400
F: 0.800

Centralidad de intermediación (Betweenness)

La centralidad de intermediación cuantifica cuántas veces un nodo actúa como puente en los caminos más cortos entre otros nodos. Es especialmente útil para identificar puntos críticos para la circulación de información.

betweenness = nx.betweenness_centrality(G)

print("Centralidad de Intermediación:")
for nodo, valor in betweenness.items():
    print(f"{nodo}: {valor:.3f}")
Centralidad de Intermediación:
A: 0.000
B: 0.050
C: 0.100
D: 0.250
E: 0.150
F: 0.200

Centralidad de cercanía (Closeness)

La centralidad de cercanía se basa en la inversa de la suma de las distancias más cortas desde un nodo hacia todos los demás. Es relevante en redes donde se valora la rapidez de acceso o difusión.

closeness = nx.closeness_centrality(G)

print("Centralidad de Cercanía:")
for nodo, valor in closeness.items():
    print(f"{nodo}: {valor:.3f}")
Centralidad de Cercanía:
A: 0.000
B: 0.556
C: 0.200
D: 0.714
E: 0.500
F: 0.556

Centralidad de autovector

La centralidad de autovector mide la influencia de un nodo considerando también la importancia de sus vecinos. Se basa en los autovalores de la matriz de adyacencia del grafo.

eigenvector = nx.eigenvector_centrality(G)

print("Centralidad de Autovector:")
for nodo, valor in eigenvector.items():
    print(f"{nodo}: {valor:.3f}")
Centralidad de Autovector:
A: 0.000
B: 0.353
C: 0.000
D: 0.642
E: 0.526
F: 0.431

Centralidad de Katz

La centralidad de Katz es una generalización de la centralidad de autovector que considera caminos de todas las longitudes, penalizándolos con un factor de decaimiento exponencial. Es útil para capturar influencia indirecta.

katz = nx.katz_centrality(G)

print("Centralidad de Katz:")
for nodo, valor in katz.items():
    print(f"{nodo}: {valor:.3f}")
Centralidad de Katz:
A: 0.347
B: 0.424
C: 0.381
D: 0.469
E: 0.394
F: 0.424

PageRank

PageRank, desarrollado originalmente por Google, valora tanto la cantidad como la calidad de los enlaces entrantes. Incluye un factor de amortiguamiento que simula la probabilidad de saltar aleatoriamente a otro nodo.

pagerank = nx.pagerank(G, alpha=0.85)

print("PageRank:")
for nodo, valor in pagerank.items():
    print(f"{nodo}: {valor:.3f}")
PageRank:
A: 0.025
B: 0.146
C: 0.036
D: 0.275
E: 0.259
F: 0.260

HITS (Hubs y Authorities)

El algoritmo HITS asigna a cada nodo dos puntuaciones: hub (nodos que enlazan a buenos authorities) y authority (nodos que son enlazados por buenos hubs). Es útil en contextos como la búsqueda web o redes académicas.

hits = nx.hits(G)

print("Autoridades:")
for nodo, valor in hits[1].items():
    print(f"{nodo}: {valor:.3f}")
    
print("Hubs:")
for nodo, valor in hits[0].items():
    print(f"{nodo}: {valor:.3f}")
Autoridades:
A: 0.000
B: 0.256
C: 0.084
D: 0.444
E: 0.000
F: 0.216
Hubs:
A: 0.144
B: 0.188
C: 0.280
D: 0.000
E: 0.091
F: 0.297

Visualización de resultados y comparación

Una de las ventajas del análisis de redes en Python es la facilidad con la que se pueden representar visualmente los resultados. Visualizar las métricas permite obtener una comprensión más intuitiva de cómo se distribuye la importancia relativa de cada nodo dentro de la red.

Como ejemplo, a continuación representamos gráficamente los valores de PageRank. El tamaño de cada nodo está proporcionalmente escalado según su valor en esta métrica, lo que permite identificar visualmente qué nodos tienen mayor relevancia en base a la métrica seleccionada:

node_size = [v * 4000 for v in pagerank.values()]

plt.figure(figsize=(8,6))
nx.draw(G, pos, with_labels=True, node_size=node_size,
        node_color='lightgreen', edge_color='gray')
plt.title("Visualización de PageRank")
plt.show()
Visualización de la métrica PageRank en un grafo dirigido. El tamaño de cada nodo está proporcionalmente escalado según su valor de PageRank, reflejando la importancia relativa de cada nodo dentro de la red.

Además de la representación gráfica, es útil disponer de una tabla comparativa que nos permita observar y contrastar los valores numéricos obtenidos para cada métrica. Para ello, podemos construir un DataFrame utilizando la biblioteca pandas:

import pandas as pd

df = pd.DataFrame({
    'Grado': degree,
    'Intermediación': betweenness,
    'Cercanía': closeness,
    'Autovector': eigenvector,
    'Katz': katz,
    'PageRank': pagerank,
    'Autoridad': hits[1],
    'Hub': hits[0]
})

print(df.round(3))
   Grado  Intermediación  Cercanía  Autovector   Katz  PageRank  Autoridad    Hub
A 0.4 0.00 0.000 0.000 0.347 0.025 0.000 0.144
B 0.6 0.05 0.556 0.353 0.424 0.146 0.256 0.188
C 0.6 0.10 0.200 0.000 0.381 0.036 0.084 0.280
D 0.8 0.25 0.714 0.642 0.469 0.275 0.444 0.000
E 0.4 0.15 0.500 0.526 0.394 0.259 0.000 0.091
F 0.8 0.20 0.556 0.431 0.424 0.260 0.216 0.297

Esta tabla nos proporciona una vista clara y ordenada de los valores de centralidad para cada nodo, facilitando la comparación cuantitativa entre distintas métricas. También resulta especialmente útil para tareas como la selección de nodos clave o la validación cruzada entre diferentes enfoques de análisis. Por ejemplo, para la creación de un mapa de calor con las correlaciones de las métricas.

Mapa de calor de correlaciones

Una forma útil de complementar la comparación entre métricas es visualizar la correlación entre ellas. Esto permite identificar qué centralidades tienden a ofrecer resultados similares y cuáles aportan una perspectiva diferente sobre la estructura de la red.

A continuación, se muestra un código que genera un mapa de calor (heatmap) que muestra las correlaciones de Pearson entre las distintas métricas de centralidad:

import seaborn as sns
import numpy as np

# Calcular matriz de correlaciones
corr = df.corr()

# Visualizar mapa de calor
plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, cmap='coolwarm', 
            fmt=".2f", square=True,
            cbar_kws={"shrink": .75})
plt.title("Correlación entre métricas de centralidad")
plt.tight_layout()
plt.show()
Mapa de calor que muestra la matriz de correlación entre diferentes métricas de centralidad calculadas en el grafo. Los valores anotados indican la fuerza y dirección de la relación entre cada par de métricas, destacando similitudes y diferencias en sus comportamientos.

Este mapa de calor permite observar de forma visual qué tan relacionadas están las métricas entre sí. Valores cercanos a 1 indican alta correlación positiva (es decir, que ambas métricas tienden a destacar los mismos nodos), mientras que valores cercanos a 0 sugieren independencia entre los enfoques y los negativos correlación negativa.

Comparación con igraph en R

La biblioteca networkx en Python representa una alternativa potente y versátil para el análisis de centralidades, especialmente en entornos donde la interoperabilidad con otras herramientas de ciencia de datos es clave. Si bien igraph en R continúa siendo la opción preferida para el análisis de redes a gran escala por su rendimiento, networkx ofrece importantes ventajas desde el punto de vista de la flexibilidad y la extensibilidad.

Ventajas de networkx:

  • Integración fluida con bibliotecas de visualización (matplotlib, plotly, pyvis) y análisis (pandas, numpy, scikit-learn).
  • Sintaxis explícita y modular, ideal para aprendizaje, prototipado y desarrollo incremental.
  • Gran comunidad y ecosistema dentro del stack de ciencia de datos en Python.

Ventajas de igraph:

  • Mayor rendimiento en el manejo de redes grandes, gracias a su núcleo optimizado en C.
  • Sintaxis concisa y directa, especialmente útil para análisis exploratorio rápido.
  • Mejor integración con el ecosistema estadístico de R.

En definitiva, la elección entre igraph en R y networkx en Python dependerá del contexto específico del análisis: el tamaño y la complejidad de la red, los requerimientos de visualización, el lenguaje de programación preferido y las herramientas complementarias disponibles. Para tareas de exploración o prototipado rápido, ambas bibliotecas resultan adecuadas, y la elección puede basarse simplemente en la familiaridad con uno u otro lenguaje. Sin embargo, en aplicaciones más exigentes, donde el rendimiento y la eficiencia en redes de gran escala son factores determinantes, igraph en R suele ofrecer mejores resultados gracias a su núcleo optimizado.

Conclusiones

A lo largo de esta publicación hemos replicado, desde el entorno Python, los análisis de centralidad previamente realizados en R. Utilizando networkx, mostramos cómo calcular, visualizar y comparar métricas fundamentales como grado, intermediación, cercanía, autovector, Katz, PageRank y HITS, complementando con tablas y mapas de calor para una interpretación más rica de los resultados.

Aunque Python puede requerir un poco más de trabajo para lograr visualizaciones pulidas, su ecosistema de análisis de datos y aprendizaje automático lo convierte en una excelente opción para proyectos más integrales. Por otro lado, igraph en R sigue siendo una referencia por su eficiencia, simplicidad sintáctica y orientación estadística.

Ambas herramientas no son excluyentes, sino complementarias. Dominar tanto igraph como networkx permite a los analistas de redes moverse con soltura entre distintos lenguajes, enfoques y requisitos técnicos, abordando desafíos complejos con mayor flexibilidad y profundidad.

Nota: La imagen de este artículo fue generada utilizando un modelo de inteligencia artificial.

¿Te ha parecido de utilidad el contenido?

Daniel Rodríguez

Share
Published by
Daniel Rodríguez

Recent Posts

De la Regresión Logística al Scorecard: La Transformación Matemática

En un entrada previa explicamos qué son el WOE y el IV y por qué…

2 días ago

Analytics Lane lanza la versión 1.1 del laboratorio con nuevas suites de CLV y Scoring

Seguimos evolucionando el laboratorio de Analytics Lane y hoy lanzamos la versión 1.1, disponible en:…

3 días ago

Interés compuesto: la fuerza que multiplica tu dinero (y los errores que la anulan)

“El interés compuesto es la octava maravilla del mundo. El que lo entiende lo gana…

7 días ago

Cómo comparar datos con barras en Matplotlib: agrupadas, apiladas y porcentuales

Tienes los datos de ventas de tres productos en dos años distintos y quieres saber…

1 semana ago

Costes hundidos en ciencia de datos: cuándo mantener un modelo y cuándo migrar

Imagina la situación. Tu equipo lleva tres años con un modelo en producción. No es…

2 semanas ago

WOE e IV: La Base Matemática del Credit Scoring

Cuando un banco evalúa una solicitud de crédito necesita responder a una pregunta aparentemente simple:…

2 semanas ago

This website uses cookies.