当前位置: 首页 > news >正文

【PYG】简单分析Planetoid()中存储Cora数据集边的数量

文章目录

    • 这得分析cora.cites原始文件
      • 步骤
      • 示例代码
      • 输出解释
      • 分析
    • chagpt生成的第一个版本答案,打印数据集的部分可以看下
      • 输出解释
      • 进一步验证
      • 总结
    • chatgpt生成的第二个版本答案
      • 检查 Cora 数据集的边
      • 输出解释
      • 检查边的方向性
      • 解释
      • 进一步优化
      • 运行结果解释
    • chagpt生成的第三个版本答案,打印cora.cites中重复的边
      • 示例代码
      • 输出解释
      • 分析

  • 分析一下代码生成的数据,edge_index=[2, 10556],10556/2=5278,实际上数据集节点间有5429条边,打印前十条边可以看到(1,2)和(2,1)实际上都存进来了
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])
Number of nodes: 2708
Number of edges (directed): 10556
Average node degree: 3.90
Is undirected: True
Edge index shape: torch.Size([2, 10556])
First 10 edges:
tensor([[   0,    0,    0,    1,    1,    1,    2,    2,    2,    2],[ 633, 1862, 2582,    2,  652,  654,    1,  332, 1454, 1666]])
  • 分析以下代码输出结果
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载并预处理Cora数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 打印边的数量
print(f'Number of nodes: {data.num_nodes}')
print(f'Number of edges (directed): {data.num_edges}')# 检查无向边数量
edge_index = data.edge_index.numpy()
edge_set = set()print(f"edge_index shape {edge_index.shape}")for i in range(edge_index.shape[1]):u, v = edge_index[:, i]print(f"u {u}, v {v}")if (v, u) not in edge_set:  # 如果反向边不存在,则添加当前边edge_set.add((u, v))print(f"add edge_set: {edge_set}")else:print(f"not add v {v}, u {u}")if (i == 9):break
print(f'Number of unique edges (undirected): {len(edge_set)}')
  • 统计独一无二的边的数目,(1,2)在就不添加(2,1),这样计算边数有5278,不存在self-loops的情况
Number of nodes: 2708
Number of edges (directed): 10556
edge_index shape (2, 10556)
u 0, v 633
add edge_set: {(0, 633)}
u 0, v 1862
add edge_set: {(0, 633), (0, 1862)}
u 0, v 2582
add edge_set: {(0, 633), (0, 2582), (0, 1862)}
u 1, v 2
add edge_set: {(1, 2), (0, 633), (0, 2582), (0, 1862)}
u 1, v 652
add edge_set: {(1, 2), (0, 2582), (0, 633), (0, 1862), (1, 652)}
u 1, v 654
add edge_set: {(1, 2), (0, 2582), (1, 654), (0, 633), (0, 1862), (1, 652)}
u 2, v 1
not add v 1, u 2
u 2, v 332
add edge_set: {(1, 2), (2, 332), (0, 2582), (1, 654), (0, 633), (0, 1862), (1, 652)}
u 2, v 1454
add edge_set: {(2, 1454), (1, 2), (2, 332), (0, 2582), (1, 654), (0, 633), (0, 1862), (1, 652)}
u 2, v 1666
add edge_set: {(2, 1454), (1, 2), (2, 332), (0, 2582), (2, 1666), (1, 654), (0, 633), (0, 1862), (1, 652)}
  • 不用那么麻烦打印前十条数据可以用下面代码
for i in range(10):print(f"edge_index {i}: {edge_index[:,i]}")

这得分析cora.cites原始文件

  • 以下代码输出结果可以看出原始文件中就是存在重复的边,打印具体重复边的代码可以看文章最后面
Total edges (directed): 5429
Unique edges (undirected): 5278
Self-loops: 0
Number of unique edges without self-loops: 5278

你提到的边数差异可能涉及到数据的具体细节和处理方式。为了更好地理解这些差异,我们可以通过以下几个步骤来详细检查和分析 Cora 数据集中的边数据。

步骤

  1. 读取和解析 cora.cites 文件:加载所有边并计算独特边的数量。
  2. 检查自环和重复边:确定是否存在自环和重复边,这些可能会影响总边数的计算。
  3. 计算双向边:确认每个无向边是否在数据集中都被存储为两条有向边。

示例代码

以下是一个示例代码,展示如何读取、解析和检查 cora.cites 文件中的边数据:

# 文件路径
cites_file = 'path_to_cora.cites'  # 替换为实际的文件路径# 读取引用关系数据
with open(cites_file, 'r') as f:cites_lines = f.readlines()# 初始化边集合和自环计数
edges = set()
self_loops = 0# 解析边数据
for line in cites_lines:parts = line.strip().split()cited = parts[0]citing = parts[1]# 检查自环if cited == citing:self_loops += 1# 添加无向边(确保 (u, v) 和 (v, u) 都被计为一条边)edge = tuple(sorted((cited, citing)))edges.add(edge)# 计算边数
num_edges = len(cites_lines)
unique_edges = len(edges)# 打印结果
print(f'Total edges (directed): {num_edges}')
print(f'Unique edges (undirected): {unique_edges}')
print(f'Self-loops: {self_loops}')# 验证无向边数量是否符合预期
print(f'Number of unique edges without self-loops: {unique_edges - self_loops}')

输出解释

  1. num_edges:原始数据集中有向边的总数。
  2. unique_edges:去重后的无向边总数。
  3. self_loops:自环数量。
  4. unique_edges - self_loops:去除自环后的无向边总数。

分析

  • 总边数 (num_edges):表示所有有向边的数量。由于每条无向边存储为两条有向边,所以这个数值应该是原始无向边数的两倍(减去自环的情况)。
  • 去重后无向边 (unique_edges):表示独特的无向边数量。
  • 自环 (self_loops):表示从一个节点指向自身的边数量。
  • 去除自环后的无向边数 (unique_edges - self_loops):应与无向边的实际数量接近。

通过这段代码,你可以更清楚地理解 Cora 数据集中边的数量差异。如果去重后无向边的数量与预期不符,那么可能需要进一步检查数据的具体情况,例如是否存在重复边或特定的边处理方式。

这段代码也可以帮助解释为什么 54295278 之间有差异,这可能与特定数据处理细节有关,例如去除了某些自环或重复边。


chagpt生成的第一个版本答案,打印数据集的部分可以看下

在 Cora 数据集中,边是无向的。然而,在许多图神经网络库(包括 PyTorch Geometric)中,边通常被存储为有向边的形式。这意味着每条无向边在边列表中会被存储为两条有向边(一个从节点 A 到节点 B,另一个从节点 B 到节点 A)。

因此,如果 Cora 数据集中有 5429 条无向边,当它们被存储为有向边时,总数会是 5429 * 2 = 10858 条边。这个解释可以解释为什么 num_edges 显示的数量是 10556 而不是 5429。

以下是一个示例,展示如何加载 Cora 数据集并确认无向边被存储为有向边:

from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载并预处理Cora数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 打印图结构和特征信息
print(data)
print(f'Number of nodes: {data.num_nodes}')
print(f'Number of edges (directed): {data.num_edges}')
print(f'Average node degree: {data.num_edges / data.num_nodes:.2f}')
print(f'Is undirected: {data.is_undirected()}')

输出解释

  • data.num_nodes: 节点的数量,应该是 2708。
  • data.num_edges: 边的数量,应该是 10556(因为每条无向边在存储时变成了两条有向边)。
  • data.is_undirected(): 检查图是否是无向的。这个方法会返回 True,表明原始图是无向的,尽管在内部存储时使用了有向边的表示。

进一步验证

你可以进一步验证存储的边确实是有向的,通过查看边的列表:

edge_index = data.edge_index
print(f'Edge index shape: {edge_index.shape}')
print(f'First 10 edges:\n{edge_index[:, :10]}')

这将打印出前 10 条边的索引,确认它们是有向边的形式。

总结

Cora 数据集原本有 5429 条无向边,在 PyTorch Geometric 中被存储为 10556 条有向边(每条无向边变成了两条有向边)。这就是为什么在加载数据集时,data.num_edges 显示的是 10556 而不是 5429。


chatgpt生成的第二个版本答案

你说得对,5429 * 2 确实应该等于 10858,而不是 10556。那么,为何 Cora 数据集中显示的边数是 10556 呢?

这主要是因为在实际数据集中,有一些自环(self-loops)或重复边没有存储为双向边。

检查 Cora 数据集的边

为了进一步验证这一点,我们可以实际检查边的数据并计算其无向边的数量。以下是一个示例代码,展示如何检查边的数据并验证其数量:

from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载并预处理Cora数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 打印边的数量
print(f'Number of nodes: {data.num_nodes}')
print(f'Number of edges (directed): {data.num_edges}')# 检查无向边数量
edge_index = data.edge_index.numpy()
edge_set = set()for i in range(edge_index.shape[1]):u, v = edge_index[:, i]if (v, u) not in edge_set:  # 如果反向边不存在,则添加当前边edge_set.add((u, v))print(f'Number of unique edges (undirected): {len(edge_set)}')

输出解释

  • data.num_edges: 边的数量,应该是 10556。
  • len(edge_set): 计算无向边的唯一数量。

检查边的方向性

我们还可以检查每对边是否确实包含其反向边:

undirected_edges = 0
for i in range(edge_index.shape[1]):u, v = edge_index[:, i]if (v, u) in edge_set:  # 检查是否存在反向边undirected_edges += 1print(f'Number of undirected edge pairs: {undirected_edges}')

解释

  1. 自环(Self-loops)
    自环指的是从一个节点指向自身的边,在无向图中,自环只计算一次。

  2. 重复边(Duplicate edges)
    如果图中存在重复边(多个相同的边),这些边在有向边表示时只会存储一次。

这些因素会导致实际存储的有向边数量比理论上双倍的无向边数量少。

进一步优化

让我们编写更完整的代码来检查这些情况:

import numpy as np
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures# 加载并预处理Cora数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora', transform=NormalizeFeatures())
data = dataset[0]# 打印边的数量
print(f'Number of nodes: {data.num_nodes}')
print(f'Number of edges (directed): {data.num_edges}')# 检查无向边数量
edge_index = data.edge_index.numpy()
edge_set = set()
self_loops = 0for i in range(edge_index.shape[1]):u, v = edge_index[:, i]if u == v:self_loops += 1if (v, u) not in edge_set:  # 如果反向边不存在,则添加当前边edge_set.add((u, v))print(f'Number of unique edges (undirected): {len(edge_set)}')
print(f'Number of self-loops: {self_loops}')# 检查是否有重复边
directed_edge_pairs = set()
for i in range(edge_index.shape[1]):u, v = edge_index[:, i]directed_edge_pairs.add((u, v))print(f'Number of directed edge pairs: {len(directed_edge_pairs)}')

运行结果解释

  • Number of unique edges (undirected): 应该接近 5429。
  • Number of self-loops: 自环数量。
  • Number of directed edge pairs: 检查无向边的反向边是否存在。

通过这段代码,你可以更清楚地理解 Cora 数据集的边数为什么是 10556,而不是 5429 * 2 = 10858。这是因为在实际数据集中,自环和重复边的处理方式不同于简单的双倍计算。


chagpt生成的第三个版本答案,打印cora.cites中重复的边

  • 截取一部分代码运行结果,可以看出5429-5278=151
Total edges (directed): 5429
Unique edges (undirected): 5278
Self-loops: 0
Number of repeated edges: 151
Repeated edges:
Edge ('210871', '35') appears 2 times
Edge ('130', '39403') appears 2 times
Edge ('506', '89416') appears 2 times

为了检查 Cora 数据集中的重复边,我们可以编写代码来查找并列出所有重复的边。这可以帮助我们理解数据集中的边数量差异。

以下是详细的代码步骤:

  1. 读取并解析 cora.cites 文件
  2. 使用字典记录每条边的出现次数
  3. 查找并打印出现次数超过一次的边

示例代码

# 文件路径
cites_file = 'path_to_cora.cites'  # 替换为实际的文件路径# 读取引用关系数据
with open(cites_file, 'r') as f:cites_lines = f.readlines()# 初始化字典记录边的出现次数
edge_count = {}
self_loops = 0# 解析边数据并统计出现次数
for line in cites_lines:parts = line.strip().split()cited = parts[0]citing = parts[1]# 检查自环if cited == citing:self_loops += 1# 创建无向边的标准形式 (sorted tuple)edge = tuple(sorted((cited, citing)))if edge in edge_count:edge_count[edge] += 1else:edge_count[edge] = 1# 查找并打印重复边
repeated_edges = {edge: count for edge, count in edge_count.items() if count > 1}print(f'Total edges (directed): {len(cites_lines)}')
print(f'Unique edges (undirected): {len(edge_count)}')
print(f'Self-loops: {self_loops}')
print(f'Number of repeated edges: {len(repeated_edges)}')# 打印重复边及其出现次数
print('Repeated edges:')
for edge, count in repeated_edges.items():print(f'Edge {edge} appears {count} times')

输出解释

  1. len(cites_lines):原始数据集中有向边的总数。
  2. len(edge_count):去重后的无向边总数。
  3. self_loops:自环数量。
  4. len(repeated_edges):重复边的数量。
  5. repeated_edges:打印每条重复边及其出现次数。

分析

  • 原始有向边总数 (len(cites_lines)) 应该与数据集描述一致。
  • 去重后的无向边总数 (len(edge_count)) 应该接近 5429
  • 重复边 (repeated_edges):查找所有出现次数超过一次的边,帮助理解为什么无向边数目不是预期的 5429

通过这段代码,你可以更清楚地看到 Cora 数据集中是否存在重复边以及这些重复边的具体情况。如果去重后的无向边数量和预期不符,重复边可能是一个关键因素。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Arthas实战(5)- 项目性能调优
  • 专业课笔记——(第十二章:文件的读写)
  • ffmpeg使用bmp编码器把bgr24编码为bmp图像
  • 【Leetcode笔记】406.根据身高重建队列
  • [课程][原创]opencv图像在C#与C++之间交互传递
  • Python内置函数print()详解
  • 【python】PyQt5可视化开发,如何设计鼠标显示的形状?
  • 【k8s安装redis】k8s安装单机版redis实现高性能高可用
  • 从0开始学习pyspark--pyspark的数据读取[第4节]
  • 【linux/shell】awk获取除某列之外的其他数据
  • transformer初探
  • 域名、网页、HTTP概述
  • CTF实战:从入门到提升
  • 振动分析-12-轴承数据库之深度学习一维故障分类CNN-Transformer
  • Linux CentOS Python 离线安装 pip 使用.whl文件离线安装
  • ES6指北【2】—— 箭头函数
  • 【附node操作实例】redis简明入门系列—字符串类型
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • bearychat的java client
  • Django 博客开发教程 16 - 统计文章阅读量
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • iOS 颜色设置看我就够了
  • Node + FFmpeg 实现Canvas动画导出视频
  • overflow: hidden IE7无效
  • Phpstorm怎样批量删除空行?
  • PHP的Ev教程三(Periodic watcher)
  • Redis学习笔记 - pipline(流水线、管道)
  • 使用权重正则化较少模型过拟合
  • 小李飞刀:SQL题目刷起来!
  • ​如何在iOS手机上查看应用日志
  • $(function(){})与(function($){....})(jQuery)的区别
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (二刷)代码随想录第15天|层序遍历 226.翻转二叉树 101.对称二叉树2
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • . NET自动找可写目录
  • .gitattributes 文件
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .Net Memory Profiler的使用举例
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .net开发引用程序集提示没有强名称的解决办法
  • .NET设计模式(11):组合模式(Composite Pattern)
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • @property括号内属性讲解
  • @Value读取properties中文乱码解决方案
  • [20160807][系统设计的三次迭代]
  • [20180129]bash显示path环境变量.txt
  • [Angularjs]asp.net mvc+angularjs+web api单页应用