Если я правильно понимаю, вам нужен график, на котором вершины представляют классы, а ребра представляют два класса с ненулевой вероятностью для одного и того же экземпляра данных.
Начиная с данных, аналогичных вашим (поскольку у вас есть только2 класса, когда-либо имеющих ненулевую способность) ...
import numpy as np
A = np.array([[0. , 0. , 0. , 0.8285762 , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0.17817138, 0. , 0.12554741, 0. , 0.16248149],
[0. , 0. , 0. , 0.10000000, 0. ],
[0.70687366, 0. , 0.85997397, 0.06154018, 0.828603 ],
[0. , 0.11233618, 0. , 0. , 0. ],
[0.11495425, 0. , 0. , 0. , 0. ],
[0. , 0.86215913, 0. , 0. , 0. ]
])
Возможно, здесь есть хитрый ход NumPy, но с помощью цикла над классами мы можем построить список ребер:
from itertools import combinations
edge_list = []
idx = np.argwhere(A.T)
for i, _ in enumerate(A):
this = idx[idx[:, 0]==i]
combs = combinations(this[:, 1], r=2)
edge_list.extend(list(combs))
edge_list
Вы можете создать экземпляр networkx.Graph
и добавить ребра следующим образом:
import networkx as nx
G = nx.Graph()
G.add_edges_from(edge_list)
Затем вы можете нарисовать график с помощью nx.draw(G)
, но рисунок по умолчанию не очень хорош.Мы можем подготовить размер узла и метки ...
nx.set_node_attributes(G, {i:chr(65+i) for i in range(len(A))}, 'name')
nx.set_node_attributes(G, {i:sum(a) for i, a in enumerate(A)}, 'prob')
probs = nx.get_node_attributes(G, 'prob')
sizes = [1000*x for x in probs.values()]
labels = nx.get_node_attributes(G, 'name')
Затем составить лучший график:
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, ax=ax, node_size=sizes, node_color='orange')
nx.draw_networkx_edges(G, pos, ax=ax, width=4, splines='curved')
nx.draw_networkx_labels(G, pos,
labels=labels,
font_size=20,
font_family='sans-serif',
font_color='blue')
plt.axis('off')
plt.show()