在 scikit learn using networkX 中使用二维数据点形成图形

Posted

技术标签:

【中文标题】在 scikit learn using networkX 中使用二维数据点形成图形【英文标题】:Forming a graph using two dimensional data points in scikit learn using networkX 【发布时间】:2021-10-21 01:22:09 【问题描述】:

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

这是我的代码

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 的图形,形状为两个卫星(因为我的数据集是两个卫星),使用数据点作为节点,亲和矩阵作为节点之间的边。

【问题讨论】:

【参考方案1】:

如果“最近邻居=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 才能正确检索节点的两个最近邻居。如果我们改用标准的无向图,一些节点将有 3 个邻居,因为它们离另一个节点最近,这可能不是互易的 例如,输出中 Y 最高的节点有两个后继(邻居)和三个前任,而它的两个前任也是后继。如果它是一个无向图,它将有 3 个邻居,因为在无向图中没有区分后继者和前驱者。 我建议取消注释最后两行代码中的打印,检查输出,然后将 DiGraph 更改为 Graph 以了解这意味着什么,如果还不清楚的话。

【讨论】:

感谢您的帮助。我认为这是正确的图表。你能帮我改变节点的颜色和形状吗?我想改变一个集群的颜色和形状,以便与第二个集群区分开来。 要根据每个集群更改每个节点的颜色,您应该使用颜色图。我建议在 SO 中搜索与此问题相关的其他问题,例如这个:***.com/questions/28910766/… 或这个:***.com/questions/27030473/… 如果您没有找到任何可以回答您的问题,那么我建议创建一个新问题,作为更改节点' 颜色和形状与原始问题无关。 最后,我觉得我应该说draw_networkx() 上的文档也可能对您有所帮助:networkx.org/documentation/stable/reference/generated/…。特别是可选参数node_colornode_shape 嘿,你能在给定的链接上回答这个问题吗?我将不胜感激。与上面的问题相同,添加了一些小细节。这是链接link【参考方案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”的意思是,您希望每个节点仅在两个最近的节点之间有边,而不是完整图? 是的,对于一个特定节点,它应该考虑它的两个最近邻居,并且对于所有节点来说,它应该考虑它的 2 个最近节点而不显示与自身的连接。

以上是关于在 scikit learn using networkX 中使用二维数据点形成图形的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scikit-learn 管道中将时代添加到 Keras 网络

从 scikit-learn 训练 SVC 表明使用 -h 0 可能更快?

无法导入 Scikit-Learn

用scikit-learn学习LDA主题模型

Scikit-learn 多线程

Scikit-learn使用总结