Una implementación de codificación para crear, anotar y visualizar gráficos complejos de conocimiento biológico utilizando Pybel

En este tutorial, exploramos cómo aprovechar el Pybel Ecosistema para construir y analizar gráficos de conocimiento biológico ricos directamente dentro de Google Colab. Comenzamos instalando todos los paquetes necesarios, incluidos Pybel, NetworkX, Matplotlib, Seaborn y Pandas. Luego demostramos cómo definir proteínas, procesos y modificaciones utilizando el Pybel DSL. A partir de ahí, lo guiamos a través de la creación de una vía relacionada con la enfermedad de Alzheimer, que muestra cómo codificar relaciones causales, interacciones proteínas-proteínas y eventos de fosforilación. Junto con la construcción de gráficos, presentamos análisis de red avanzados, incluidas medidas de centralidad, clasificación de nodos y extracción de subgrafías, así como técnicas para extraer datos de citas y pruebas. Al final de esta sección, tendrá un Bel Graph totalmente anotado listo para la visualización posterior y los análisis de enriquecimiento, estableciendo una base sólida para la exploración de conocimiento biológico interactivo.

!pip install pybel pybel-tools networkx matplotlib seaborn pandas -q


import pybel
import pybel.dsl as dsl
from pybel import BELGraph
from pybel.io import to_pickle, from_pickle
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from collections import Counter
import warnings
warnings.filterwarnings('ignore')


print("PyBEL Advanced Tutorial: Biological Expression Language Ecosystem")
print("=" * 65)

Comenzamos instalando Pybel y sus dependencias directamente en Colab, asegurando que todas las bibliotecas necesarias, NetworkX, Matplotlib, Seaborn y Pandas estén disponibles para nuestro análisis. Una vez instalado, importamos los módulos centrales y suprimamos las advertencias para mantener nuestro cuaderno limpio y enfocado en los resultados.

print("\n1. Building a Biological Knowledge Graph")
print("-" * 40)


graph = BELGraph(
   name="Alzheimer's Disease Pathway",
   version="1.0.0",
   description="Example pathway showing protein interactions in AD",
   authors="PyBEL Tutorial"
)


app = dsl.Protein(name="APP", namespace="HGNC")
abeta = dsl.Protein(name="Abeta", namespace="CHEBI")
tau = dsl.Protein(name="MAPT", namespace="HGNC")
gsk3b = dsl.Protein(name="GSK3B", namespace="HGNC")
inflammation = dsl.BiologicalProcess(name="inflammatory response", namespace="GO")
apoptosis = dsl.BiologicalProcess(name="apoptotic process", namespace="GO")




graph.add_increases(app, abeta, citation="PMID:12345678", evidence="APP cleavage produces Abeta")
graph.add_increases(abeta, inflammation, citation="PMID:87654321", evidence="Abeta triggers neuroinflammation")


tau_phosphorylated = dsl.Protein(name="MAPT", namespace="HGNC",
                               variants=[dsl.ProteinModification("Ph")])
graph.add_increases(gsk3b, tau_phosphorylated, citation="PMID:11111111", evidence="GSK3B phosphorylates tau")
graph.add_increases(tau_phosphorylated, apoptosis, citation="PMID:22222222", evidence="Hyperphosphorylated tau causes cell death")
graph.add_increases(inflammation, apoptosis, citation="PMID:33333333", evidence="Inflammation promotes apoptosis")


graph.add_association(abeta, tau, citation="PMID:44444444", evidence="Abeta and tau interact synergistically")


print(f"Created BEL graph with {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges")

Inicializamos un belgraph con metadatos para una vía de la enfermedad de Alzheimer y definimos proteínas y procesos utilizando el Pybel DSL. Al agregar relaciones causales, modificaciones de proteínas y asociaciones, construimos una red integral que captura interacciones moleculares clave.

print("\n2. Advanced Network Analysis")
print("-" * 30)


degree_centrality = nx.degree_centrality(graph)
betweenness_centrality = nx.betweenness_centrality(graph)
closeness_centrality = nx.closeness_centrality(graph)


most_central = max(degree_centrality, key=degree_centrality.get)
print(f"Most connected node: {most_central}")
print(f"Degree centrality: {degree_centrality[most_central]:.3f}")

Calculamos la centralidad de grado, intermedia y cercanía para cuantificar la importancia de cada nodo dentro del gráfico. Al identificar los nodos más conectados, obtenemos información sobre posibles centros que pueden impulsar los mecanismos de enfermedades.

print("\n3. Biological Entity Classification")
print("-" * 35)


node_types = Counter()
for node in graph.nodes():
   node_types[node.function] += 1


print("Node distribution:")
for func, count in node_types.items():
   print(f"  {func}: {count}")

Clasificamos cada nodo por su función, como proteínas o procesos biológicos, y contamos con sus recuentos. Este desglose nos ayuda a comprender la composición de nuestra red de un vistazo.

print("\n4. Pathway Analysis")
print("-" * 20)


proteins = [node for node in graph.nodes() if node.function == 'Protein']
processes = [node for node in graph.nodes() if node.function == 'BiologicalProcess']


print(f"Proteins in pathway: {len(proteins)}")
print(f"Biological processes: {len(processes)}")


edge_types = Counter()
for u, v, data in graph.edges(data=True):
   edge_types[data.get('relation')] += 1


print("\nRelationship types:")
for rel, count in edge_types.items():
   print(f"  {rel}: {count}")

Separamos todas las proteínas y procesos para medir el alcance y la complejidad de la vía. Contar los diferentes tipos de relaciones revela aún más qué interacciones, como aumentos o asociaciones, dominan nuestro modelo.

print("\n5. Literature Evidence Analysis")
print("-" * 32)


citations = []
evidences = []
for _, _, data in graph.edges(data=True):
   if 'citation' in data:
       citations.append(data['citation'])
   if 'evidence' in data:
       evidences.append(data['evidence'])


print(f"Total citations: {len(citations)}")
print(f"Unique citations: {len(set(citations))}")
print(f"Evidence statements: {len(evidences)}")

Extraemos identificadores de citas y cadenas de evidencia de cada borde para evaluar la base de nuestro gráfico en la investigación publicada. Resumir citas totales y únicas nos permite evaluar la amplitud de la literatura de apoyo.

print("\n6. Subgraph Analysis")
print("-" * 22)


inflammation_nodes = [inflammation]
inflammation_neighbors = list(graph.predecessors(inflammation)) + list(graph.successors(inflammation))
inflammation_subgraph = graph.subgraph(inflammation_nodes + inflammation_neighbors)


print(f"Inflammation subgraph: {inflammation_subgraph.number_of_nodes()} nodes, {inflammation_subgraph.number_of_edges()} edges")

Aislamos el subgrafio de inflamación recolectando sus vecinos directos, produciendo una visión enfocada de la diafonía inflamatoria. Esta subred dirigida resalta cómo la inflamación interactúa con otros procesos de enfermedad.

print("\n7. Advanced Graph Querying")
print("-" * 28)


try:
   paths = list(nx.all_simple_paths(graph, app, apoptosis, cutoff=3))
   print(f"Paths from APP to apoptosis: {len(paths)}")
   if paths:
       print(f"Shortest path length: {len(paths[0])-1}")
except nx.NetworkXNoPath:
   print("No paths found between APP and apoptosis")


apoptosis_inducers = list(graph.predecessors(apoptosis))
print(f"Factors that increase apoptosis: {len(apoptosis_inducers)}")

Enumeramos caminos simples entre la aplicación y la apoptosis para explorar las rutas mecanicistas e identificar intermedios clave. La lista de todos los predecesores de la apoptosis también nos muestra qué factores pueden desencadenar la muerte celular.

print("\n8. Data Export and Visualization")
print("-" * 35)


adj_matrix = nx.adjacency_matrix(graph)
node_labels = [str(node) for node in graph.nodes()]


plt.figure(figsize=(12, 8))


plt.subplot(2, 2, 1)
pos = nx.spring_layout(graph, k=2, iterations=50)
nx.draw(graph, pos, with_labels=False, node_color="lightblue",
       node_size=1000, font_size=8, font_weight="bold")
plt.title("BEL Network Graph")


plt.subplot(2, 2, 2)
centralities = list(degree_centrality.values())
plt.hist(centralities, bins=10, alpha=0.7, color="green")
plt.title("Degree Centrality Distribution")
plt.xlabel("Centrality")
plt.ylabel("Frequency")


plt.subplot(2, 2, 3)
functions = list(node_types.keys())
counts = list(node_types.values())
plt.pie(counts, labels=functions, autopct="%1.1f%%", startangle=90)
plt.title("Node Type Distribution")


plt.subplot(2, 2, 4)
relations = list(edge_types.keys())
rel_counts = list(edge_types.values())
plt.bar(relations, rel_counts, color="orange", alpha=0.7)
plt.title("Relationship Types")
plt.xlabel("Relation")
plt.ylabel("Count")
plt.xticks(rotation=45)


plt.tight_layout()
plt.show()

Preparamos matrices de adyacencia y etiquetas de nodos para el uso posterior y generamos una figura de múltiples paneles que muestra la estructura de la red, las distribuciones de centralidad, las proporciones de tipo nodo y los recuentos de tipo de borde. Estas visualizaciones dan vida a nuestro Bel Graph, apoyando una interpretación biológica más profunda.

En este tutorial, hemos demostrado el poder y la flexibilidad de Pybel para modelar sistemas biológicos complejos. Mostramos con qué facilidad se pueden construir un gráfico de caja blanca curada de las interacciones de la enfermedad de Alzheimer, realizar análisis a nivel de red para identificar nodos de concentración clave y extraer subgrafos biológicamente significativos para un estudio enfocado. También cubrimos prácticas esenciales para la minería de evidencia de literatura y preparamos estructuras de datos para visualizaciones convincentes. Como el siguiente paso, le recomendamos que extienda este marco a sus vías, integrando datos OMICS adicionales, ejecutando pruebas de enriquecimiento o acoplando el gráfico con flujos de trabajo de aprendizaje automático.


Mira el Códigos aquí. Todo el crédito por esta investigación va a los investigadores de este proyecto. Además, siéntete libre de seguirnos Gorjeo Y no olvides unirte a nuestro Subreddit de 100k+ ml y suscribirse a Nuestro boletín.


Sana Hassan, una pasante de consultoría en MarktechPost y estudiante de doble grado en IIT Madras, le apasiona aplicar tecnología e IA para abordar los desafíos del mundo real. Con un gran interés en resolver problemas prácticos, aporta una nueva perspectiva a la intersección de la IA y las soluciones de la vida real.