Категориальная классификация вероятностей как граф - PullRequest
2 голосов
/ 20 сентября 2019

Каков наилучший способ взять вероятности категориальной классификации, обычно выводимые из нейронной сети, и построить их в виде графика, используя что-то вроде networkx.

Учитывая 8 категорий, скажем ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] и прогнозына 5 выборках с формой (8, 5) Я хотел бы построить график, где метка узла является категорией, и вероятность для всех индексов, где вероятность больше 0,0.

array([[0.        , 0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 0.        ],
       [0.17817138, 0.11233618, 0.12554741, 0.16154018, 0.16248149],
       [0.        , 0.        , 0.        , 0.        , 0.        ],
       [0.70687366, 0.86215913, 0.85997397, 0.8285762 , 0.828603  ],
       [0.        , 0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 0.        ]],
      dtype=float32)

Допустимые ребра находятся между всеми ненулевыми значениями последовательных столбцов в массиве.

1 Ответ

0 голосов
/ 24 сентября 2019

Если я правильно понимаю, вам нужен график, на котором вершины представляют классы, а ребра представляют два класса с ненулевой вероятностью для одного и того же экземпляра данных.

Начиная с данных, аналогичных вашим (поскольку у вас есть только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()

A plot of the resulting graph.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...