基于scikit-learn与NetworkX构建月牙形数据集的谱聚类关联图(近邻数设为2)
构建月牙数据集的近邻关联图(近邻数为2)
你已经完成了谱聚类的关键步骤,拿到了节点数据和亲和矩阵,接下来只需要筛选指定近邻的边,再结合原始数据的坐标布局来绘图就能实现需求。下面是完整的实现代码,我把图构建和可视化的部分补充进去了:
import numpy as np from sklearn.cluster import SpectralClustering from sklearn.datasets import make_moons import matplotlib.pyplot as plt import networkx as nx # 生成月牙形数据集 X, y = make_moons(n_samples=20, random_state=0) # 执行谱聚类,获取亲和矩阵 clustering = SpectralClustering( n_clusters=2, assign_labels='kmeans', affinity='rbf', gamma=10, random_state=0 ) y_predict = clustering.fit_predict(X) affinity_matrix = clustering.affinity_matrix_ # ---------------------- 构建近邻数为2的关联图 ---------------------- # 1. 为每个节点筛选权重最高的2个近邻(排除自身) G = nx.Graph() # 添加所有节点,用样本索引作为节点ID,同时存储坐标和聚类标签 for idx in range(len(X)): G.add_node(idx, pos=X[idx], label=y_predict[idx]) # 遍历每个节点,找top2的近邻 for i in range(len(affinity_matrix)): # 获取当前节点与其他节点的亲和度,排除自身(对角线元素) neighbor_scores = affinity_matrix[i].copy() neighbor_scores[i] = -np.inf # 把自身的亲和度设为最小值,避免选中 # 获取权重最高的2个节点的索引 top2_neighbors = np.argsort(neighbor_scores)[-2:] # 添加边,带上亲和度作为权重,避免重复添加双向边 for neighbor in top2_neighbors: if not G.has_edge(i, neighbor): weight = affinity_matrix[i][neighbor] G.add_edge(i, neighbor, weight=weight) # 2. 可视化:用原始数据的坐标作为节点位置,保持月牙形态 pos = nx.get_node_attributes(G, 'pos') node_labels = nx.get_node_attributes(G, 'label') # 绘制节点,用聚类结果上色区分簇 nx.draw_networkx_nodes(G, pos, node_size=500, node_color=[node_labels[n] for n in G.nodes], cmap=plt.cm.coolwarm) # 绘制边,边的透明度对应权重大小(权重越高越不透明) edges = G.edges(data=True) nx.draw_networkx_edges(G, pos, edgelist=edges, alpha=[d['weight'] for (u, v, d) in edges], width=2) # 添加节点编号方便对应原始数据 nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold') plt.title('Moon Dataset Neighbor Graph (Top 2 Neighbors)') plt.axis('equal') plt.show()
关键步骤说明:
- 筛选近邻:通过把自身亲和度设为负无穷,确保每个节点只选出和其他节点中权重最高的2个连接,避免生成自环。
- 图布局:直接使用原始数据集的坐标作为节点位置,这样图的形态会和月牙数据集保持一致,不会打乱原有分布。
- 可视化细节:用聚类结果给节点上色,边的透明度对应亲和权重,能直观看到节点间的连接强度差异。
运行这段代码后,你就能得到一个保持月牙形态、每个节点仅连接2个权重最高近邻的关联图啦。
内容的提问来源于stack exchange,提问作者Ytt
相关产品推荐
相关产品推荐

