Day04 图表示学习笔记

两种节点嵌入的方法:深度游走和 Node2Vec。

随机游走 :随机选择一个邻居,并移动到这个邻居

最简单的随机游走策略是深度游走,即从每个节点开始运行固定长度、无偏的随机游走。

图表示学习

对图 G 中的节点嵌入求和(或平均)

引入“虚拟节点”

匿名步行嵌入,将图表示为这些游走的概率分布

import matplotlib.pyplot as plt  # 导入matplotlib库,用于数据可视化
import networkx as nx  # 导入networkx库,用于创建和操作复杂网络
import torch  # 导入torch库,用于深度学习计算
import torch.nn as nn  # 导入torch的神经网络模块
from sklearn.decomposition import PCA  # 导入sklearn库的PCA模块,用于数据降维

# 载入空手道俱乐部网络
G = nx.karate_club_graph()  # 使用networkx库的karate_club_graph函数加载空手道俱乐部网络

# 可视化图
nx.draw(G, with_labels=True)  # 使用networkx库的draw函数绘制空手道俱乐部网络的图形,节点带有标签

torch.manual_seed(1)  # 设置torch库的随机数种子,以确保结果可复现


# 初始化嵌入函数
def create_node_emb(num_node=34, embedding_dim=16):
    emb = nn.Embedding(num_node, embedding_dim)  # 创建一个嵌入层,用于将节点映射到嵌入空间
    emb.weight.data = torch.rand(num_node, embedding_dim)  # 初始化嵌入层的权重,使用均匀分布填充
    return emb


# 初始化嵌入
emb = create_node_emb()  # 调用create_node_emb函数初始化嵌入层


# 可视化
def visualize_emb(emb):
    X = emb.weight.data.numpy()  # 获取嵌入层的权重,转换为numpy数组
    pca = PCA(n_components=2)  # 创建一个PCA对象,用于将嵌入空间的数据降到2维
    components = pca.fit_transform(X)  # 对嵌入数据进行PCA降维

    plt.figure(figsize=(6, 6))  # 创建一个6x6的绘图窗口

    club1_x = []  # 用于存储属于"Mr. Hi"俱乐部的节点的x坐标
    club1_y = []  # 用于存储属于"Mr. Hi"俱乐部的节点的y坐标
    club2_x = []  # 用于存储属于"Officer"俱乐部的节点的x坐标
    club2_y = []  # 用于存储属于"Officer"俱乐部的节点的y坐标

    for node in G.nodes(data=True):  # 遍历空手道俱乐部网络的所有节点
        if node[1]['club'] == 'Mr. Hi':  # 判断节点所属的俱乐部
            club1_x.append(components[node[0]][0])  # 将节点对应的PCA降维后的x坐标添加到club1_x列表
            club1_y.append(components[node[0]][1])  # 将节点对应的PCA降维后的y坐标添加到club1_y列表
        else:
            club2_x.append(components[node[0]][0])  # 将节点对应的PCA降维后的x坐标添加到club2_x列表
            club2_y.append(components[node[0]][1])  # 将节点对应的PCA降维后的y坐标添加到club2_y列表

    plt.scatter(club1_x, club1_y, color="red", label="Mr. Hi")  # 绘制"Mr. Hi"俱乐部的节点散点图,颜色为红色
    plt.scatter(club2_x, club2_y, color="blue", label="Officer")  # 绘制"Officer"俱乐部的节点散点图,颜色为蓝色
    plt.legend()  # 显示图例
    plt.show()  # 显示图形


# 可视化初始嵌入
visualize_emb(emb)  # 调用visualize_emb函数可视化初始嵌入结果


def graph_to_edge_list(G):
    # 将 tensor 变成 edge_list

    edge_list = []

    for edge in G.edges():
        edge_list.append(edge)

    return edge_list


def edge_list_to_tensor(edge_list):
    # 将 edge_list 变成 tesnor

    edge_index = torch.tensor([])

    edge_index = torch.LongTensor(edge_list).t()

    return edge_index


pos_edge_list = graph_to_edge_list(G)
pos_edge_index = edge_list_to_tensor(pos_edge_list)
print("The pos_edge_index tensor has shape {}".format(pos_edge_index.shape))
print("The pos_edge_index tensor has sum value {}".format(torch.sum(pos_edge_index)))
import random


# 采样负边
def sample_negative_edges(G, num_neg_samples):
    neg_edge_list = []

    # 得到图中所有不存在的边(这个函数只会返回一侧,不会出现逆边)
    non_edges_one_side = list(enumerate(nx.non_edges(G)))
    neg_edge_list_indices = random.sample(range(0, len(non_edges_one_side)), num_neg_samples)
    # 取样num_neg_samples长度的索引
    for i in neg_edge_list_indices:
        neg_edge_list.append(non_edges_one_side[i][1])

    return neg_edge_list


# Sample 78 negative edges
neg_edge_list = sample_negative_edges(G, len(pos_edge_list))

# Transform the negative edge list to tensor
neg_edge_index = edge_list_to_tensor(neg_edge_list)
print("The neg_edge_index tensor has shape {}".format(neg_edge_index.shape))
The pos_edge_index tensor has shape torch.Size([2, 78])
The pos_edge_index tensor has sum value 2535
The neg_edge_index tensor has shape torch.Size([2, 78])

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值