DeepWalk初探

    科技2024-06-30  72

    欲实现下面的一个效果: 数据集的获取,可以利用networkx中的集成的Karate图来得到,获取数据集到原始的CSV文件,在上篇(处理数据的常见操作)中有介绍,这里不再介绍。 那么,首先我们需要使用louvain算法来进行这个数据集的社区的划分,同样的前面也介绍过,这里不再重复。这里直接改变划分后的节点的颜色即可,代码如下:

    import community as community_louvain import matplotlib.cm as cm import matplotlib.pyplot as plt import networkx as nx # load the karate club graph G = nx.karate_club_graph() #first compute the best partition partition = community_louvain.best_partition(G) # draw the graph pos = nx.spring_layout(G) # colors colors = ["BlueViolet", "LawnGreen", "OrangeRed", "Turquoise"] # 33-1紫、32-1绿、1-1红、7-1蓝 , 减1是因为图是从0开始的 # 节点对应的颜色的封装 resu = {} for com in list(set(partition.values())): nodes = [key for key in partition.keys() if partition[key] == com] if 32 in nodes: resu[colors[0]] = nodes elif 31 in nodes: resu[colors[1]] = nodes elif 0 in nodes: resu[colors[2]] = nodes else: resu[colors[3]] = nodes # 生成节点对应的label字典 labels = {} for node in list(G.nodes()): labels[node] = node+1 options = {"node_size": 250, "alpha": 0.8} # nodes for color in colors: nx.draw_networkx_nodes(G, pos, nodelist=resu[color], label=resu[color], node_color=color, **options) # edges nx.draw_networkx_edges(G, pos, alpha=0.5) # labels nx.draw_networkx_labels(G, pos, labels, font_size=10, font_color='black') # plt.axis("off") # 关闭坐标轴 plt.show()

    结果: 不知道为什么,每次程序运行划分社区的节点有个别有不同,这是多次运行后取的一个和上图最相似的一个。 原图: 可以对比发现节点10在这里还是划分为了不同的社区。 然后,我们需要学习一个表示,即右图。 DeepWalk算法主要包括两个步骤,第一步为随机游走采样节点序列,第二部为使用word2vec学习表达向量。 不妨,这里就使用前面写过的社区认知的随机游走来做。 但是在通过之前的随机游走和gensim中的word2vec来得到的节点的向量表示,用sklearn中KMeans聚类做颜色标记,最终用TSNE(t-distributed Stochastic Neighbor Embedding)来做数据的二维可视化的时候,出现的图像并不是最上面的想要的目标图形,如下: 那么它是如何聚集在一堆中的呢? 这里颜色是随机的,但其实感觉是失败了。就当熟练相关函数了 代码如下:

    from sklearn.cluster import KMeans import numpy as np import pandas as pd from sklearn.manifold import TSNE from matplotlib import pyplot data=normalization(TSNE(n_components=2).fit_transform(node_embedding)) # 降维 model = KMeans(n_clusters=4, max_iter=4) # 分为k类 # 对数据向量归一化处理 def normalization(data): _range = np.max(data) - np.min(data) return (data - np.min(data)) / _range model.fit(normalization(data)) # 开始聚类 # 简单打印结果 r1 = pd.Series(model.labels_).value_counts() # 统计各个类别的数目 r2 = pd.DataFrame(model.cluster_centers_) # 找出聚类中心 # 详细输出原始数据及其类别 r3 = pd.DataFrame(data[:, 0], columns=['x']) r4 = pd.DataFrame(data[:, 1], columns=['y']) r5 = pd.DataFrame(model.labels_, columns=['label']) r = pd.concat([r3, r4, r5], axis=1) # 二维中对应的坐标和分类的结果, axis=1表示列 colors = ["BlueViolet", "LawnGreen", "OrangeRed", "Turquoise"] # 随机一个颜色 for index, row in r.iterrows(): pyplot.scatter(row['x'], row['y'], c=colors[int(row['label'])], s=200) pyplot.text(row['x']+0.01, row['y']-0.01,str(index+1), family='serif', style='italic', ha='right', wrap=True) pyplot.show()

    node_embedding来自以前的博客中的随机游走的节点的嵌入表示,这里不再介绍。

    以后在探究这个问题:那么它是如何聚集在一堆中的呢?

    感觉原因应该是这个: 原文中的图片是经过文中的DeepWalk后的一个社区的聚类效果。自然和我的不一样,我这里的画图是直接将得到的节点表示向量进行降维,然后直接在这个二维表示中来做聚类效果,也就是简单的聚类效果。原因总结: 1)没有处理社区信息; 2)简单距离聚类效果; 3)节点的向量表示直接用TSNE降维过于粗糙;

    Processed: 0.016, SQL: 8