В этой статье я опишу, как визуализировать графовую сеть с помощью NetworkX. Например, я буду использовать набор данных MUTAG для представления реализации.

При работе над проектами с использованием графовой нейронной сети мне было трудно анализировать график до и после прогнозирования. Причина в том, что мы их не визуализировали. Все, что мы получили, — это огромное количество входных данных, включая ребра и узлы, а также выходные данные, содержащие некоторое значение. Именно это и вдохновило меня на написание этой статьи.

Контур

  • Источник данных
  • Пакет
  • Визуализация

Источник данных — МУТАГ

Набор данных MUTAG состоит из 188 химических соединений, разделенных на два класса в зависимости от их мутагенного действия на бактерию. Химические данные были получены с http://cdb.ics.uci.edu и преобразованы в графы, где вершины представляют собой атомы, а ребра представляют собой химические связи. Явные атомы водорода были удалены, а вершины помечены по типу атома, а ребра по типу связи (одинарная, двойная, тройная или ароматическая). Химические данные были обработаны с использованием Chemistry Development Kit (v1.4).

Представленный как сеть, узлы и ребра помечены как:

Node labels:
0  C
1  N
2  O
3  F
4  I
5  Cl
6  Br
Edge labels:
0  aromatic
1  single
2  double
3  triple

Файлы, которые мы будем использовать здесь, следующие:

|- MUTAG_A.txt             # Adjacency list
|- MUTAG_edge_labels.txt   # Edge labels
|- MUTAG_node_labels.txt   # Node labels

Источник данных: Бумага с кодом

Справочный документ: Дебнат А.К., Лопес де Компадре Р.Л., Дебнат Г., Шустерман А.Дж. и Ханш С. Взаимосвязь структура-активность мутагенных ароматических и гетероароматических нитросоединений.

Пакет — NetworkX

NetworkX — это пакет Python для создания, управления и изучения структуры, динамики и функций сложных сетей.

  • Монтаж
$ pip install networkx[default]
  • Простой пример
import networkx as nx
import matplotlib.pyplot as plt
# init network
G = nx.Graph()
# add edges
G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(1, 5)
G.add_edge(2, 3)
G.add_edge(3, 4)
G.add_edge(4, 5)

# explicitly set positions
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
# network visualization options
options = {
    "font_size": 36,
    "node_size": 3000,
    "node_color": "white",
    "edgecolors": "black",
    "linewidths": 5,
    "width": 5,
}
# draw network
nx.draw_networkx(G, pos, **options)

# plot setting and show
ax = plt.gca()
ax.margins(0.20)
plt.axis("off")
plt.show()

Вывод:

Визуализация МУТАГ

Чтобы визуализировать набор данных MUTAG, нам нужно сначала загрузить наши ребра, узлы и список смежности.

mut_edge = np.loadtxt('MUTAG_edge_labels.txt')
mut_node = np.loadtxt('MUTAG_node_labels.txt')
A= np.loadtxt('MUTAG_A.txt', dtype=str)

Во-вторых, давайте определим наши узлы как словарь меток узлов и цвет, который их представляет.

# define colors for each label
color_dict= {0:"Red", 1:"Blue", 2:"Yellow",3:"Green", 4:"Gray", 5:"Purple", 6:"Pink"}
# create dict for nodes
node={}
for i in range(3371):
   node[str(i)]=dict(color=color_dict[mut_node[i]])

Для ребер мы определяем список ребер на основе списка смежности и их меток.

# dict for edge labels
bond_dict = {0:"aromatic", 1:"single", 2:"double", 3:"triple"}
# list to define edges
edges=[]
for i in range(7440):
   edges.append((A[i][0].split(',')[0], A[i][1],                               bond_dict[mut_edge[i]]))

И последнее, но не менее важное: давайте создадим нашу сеть и начнем добавлять узлы, ребра и стиль. Ведь мы можем просто нарисовать его и увидеть результат.

# init graph
original_graph = nx.Graph()
# add nodes and edges
original_graph.add_nodes_from(n for n in node.items())
original_graph.add_edges_from((u, v, {"type": label}) for u, v, label in edges)
# format plot
plt.figure(1, figsize=(50, 25), dpi=60)
# set baseline network plot options
base_options = dict(with_labels=False, edgecolors="black", node_size=200)
# define layout of position
pos = nx.spring_layout(original_graph, seed=7482934)
# set node's color as we define previously
node_colors = [d["color"] for _, d in original_graph.nodes(data=True)]
# add weights on edges to classify different bonds by widths
edge_type_visual_weight_lookup = {"aromatic":1,"single":2, "double":3, "triple":4}
edge_weights = [edge_type_visual_weight_lookup[d["type"]] for _, _, d in original_graph.edges(data=True)]
# draw network
nx.draw_networkx(original_graph, pos=pos, node_color=node_colors, width=edge_weights, **base_options)
plt.show()

Вывод:

Удивительный!!! Не так ли?

Это все, что у меня есть для этой статьи, спасибо, ребята, за поддержку!!! Пожалуйста, нажмите кнопку аплодисментов, оставьте комментарий и подпишитесь на меня, если вам интересен мой контент!!!

Заранее ознакомьтесь с моей статьей о Graph Convolutional Network!!!

Вы также можете проверить некоторые ссылки ниже для получения дополнительной информации.

Увидимся в следующий раз!!!