使用networkX在scikit学习中使用二维数据点形成图形

Forming a graph using two dimensional data points in scikit learn using networkX

我必须对卫星形状的数据集进行光谱聚类,然后必须创建一个图表来显示数据点之间的联系。

这是我的代码

import numpy as np
import os
from sklearn import metrics
from sklearn.cluster import SpectralClustering
from sklearn.neighbors import DistanceMetric
from sklearn.cluster import KMeans
import pandas as pd
import pylab as pl
import sklearn.metrics as sm
from sklearn.metrics import confusion_matrix,classification_report
from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
import networkx as nx
X, y = make_moons(n_samples=20)
print(X)
clustering=SpectralClustering(n_clusters=2,
       assign_labels='kmeans',affinity='rbf',gamma=10, degree=3,
         random_state=0)
y_predict=clustering.fit_predict(X)
y_predict_labels = clustering.labels_
clustering.affinity_matrix_

我将节点作为数据点,将亲和力矩阵作为边上的权重。 有人可以帮助我使用两个卫星形状的最近邻居 = 2 创建一个图(因为我的数据集是两个卫星),使用数据点作为节点和亲和力矩阵作为节点之间的边。

代码

# Make Graph
G = nx.Graph()
i = 0
for i in range(0, len(X)):
  j = 0
  for affinity in clustering.affinity_matrix_[i]:
    G.add_edge(tuple(X[i]), tuple(X[j]), weight = affinity)
    j += 1
  i += 1

# Draw graph in moon shape
pos = {node_name: node_name for node_name in G.nodes}
nx.draw_networkx(G, pos, with_labels=False)

输出

详情

  • Networkx 中节点的索引需要是不可变的。这就是我们将 X[i] 和 X[j] 转换为元组的原因;
  • 为了将图形绘制成月亮形状,我们首先通过 G.nodes 获取每个节点的索引来获取每个节点的位置,并将它们存储在字典中(pos 变量是用听写理解)。然后我们可以使用 pos dict 来绘制具有自定义布局的图形;
  • 可能有更“pythonic”的方式来制作图表,但这也行得通。

如果“最近邻=2”是指每个节点的出度必须为 2,而不是返回完整图,那么实现此目的的一种方法是使用以下代码:

代码

k = 2

# Make Graph
G = nx.DiGraph()
for i in range(0, len(X)):
  affinity_list = clustering.affinity_matrix_[i]
  affinity_list[i] = 0 # in case we don't want to consider the node as it's own neighbour
  nearest_neighbors_indices = np.argpartition(clustering.affinity_matrix_[i], -k)[-k:]
  for j in nearest_neighbors_indices:
    G.add_edge(tuple(X[i]), tuple(X[j]), weight = clustering.affinity_matrix_[i][j])

# Draw Graph
pos = {node_name: node_name for node_name in G.nodes}
nx.draw_networkx(G, pos, with_labels=False)

# for node in G.nodes:
#    print(list(G.neighbors(node)))

输出

详情

  • 对于每个节点,我们使用 np.argpartition() 方法获得与关联矩阵中的两个最大值对应的索引。
  • 我们不认为节点是它们自己的邻居,所以我们在应用 np.argparition().
  • 之前将它们与自己的亲和力更改为 0
  • 我们需要 nx.DiGraph 而不是 nx.Graph 来正确检索节点的 2 个最近邻居。如果我们改用标准的无向图,一些节点将有 3 个邻居,因为它们离另一个节点最近,这可能不是互惠的
    • 例如,输出中Y最高的节点有两个后继(邻居)和三个前驱,而它的两个前驱也是后继。如果它是无向图,它会有3个邻居,因为无向图中没有后继和前任的区别。
    • 我建议取消注释代码最后两行中的打印,检查输出,然后将 DiGraph 更改为 Graph 以了解这意味着什么,如果还不清楚的话。