【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换

本文主要是介绍【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 引言:python代码学习,本博客对python的"pickled object" (腌制对象,也叫序列化对象), 调整邻接矩阵使其对称图加自环 & 图邻接矩阵归一化稀疏邻接矩阵格式转换从代码实现的角度进行介绍。我们先引入一段代码,通过这段代码来解释相应的知识点。
with open('data/' + args.dataset + '_mean_' + args.diffusion_model + str(10*args.seed_rate) + '.SG', 'rb') as f:graph = pickle.load(f)adj, inverse_pairs = graph['adj'], graph['inverse_pairs']adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)
adj = normalize_adj(adj + sp.eye(adj.shape[0]))
adj = torch.Tensor(adj.toarray()).to_sparse()
  • 上述代码是什么意思呢?我们逐行来分析。

知识点一:pickled object

  • “pickled object”(腌制对象)是指一个已经被序列化(serialized)的对象。序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在Python中,这个过程通常是通过pickle模块来完成的。

  • 当使用pickle模块的dump函数将一个对象序列化到一个文件或字节流中时,这个对象就被"pickled"(腌制)了。序列化后的数据可以被存储在文件中,通过网络传输,或者以其他方式保存,被"pickled"的数据可以被pickle模块的load函数重新加载,恢复成原始的对象。

  • 例如,如果你有一个复杂的Python对象,比如一个包含多个嵌套字典和列表的数据结构,你可以使用pickle将其序列化到一个文件中:

import pickle
# 创建一个复杂的数据结构
data = {'name': 'Alice','age': 30,'friends': ['Bob', 'Charlie'],'scores': {'math': 90, 'english': 85}
}
# 将数据结构序列化到一个文件中
with open('data.pkl', 'wb') as f:pickle.dump(data, f)
  • 之后,你可以使用pickle.load函数从文件中加载这个pickled对象,并恢复成原始的数据结构:
# 从文件中加载pickled对象
with open('data.pkl', 'rb') as f:loaded_data = pickle.load(f)
# 现在loaded_data包含了原始的数据结构
print(loaded_data)
  • 需要注意的是,pickle模块是Python特有的,它生成的序列化数据是依赖于Python的实现细节的,因此不能跨语言使用。此外,由于pickle可以重建任何Python对象,包括执行代码,因此它可能存在安全风险,不应该用于加载不受信任或未经身份验证的数据。

知识点二 调整邻接矩阵使其对称

  • 本文开头提到的代码中,adj, inverse_pairs = graph['adj'], graph['inverse_pairs'] 这行代码从名为graph的字典中提取了两个键值对,adj和inverse_pairs。adj通常代表图的邻接矩阵,而inverse_pairs则是一些额外的图信息。
  • adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)
    • adj.T 是矩阵 adj 的转置矩阵。
    • (adj.T > adj) 是一个布尔矩阵,其中每个元素是 adj.T 中的元素与 adj 中对应位置的元素比较的结果。如果 adj.T 中的元素大于 adj 中的对应元素,则该位置为 True,否则为 False。
    • adj.T.multiply(adj.T > adj) 是矩阵乘法,它将 adj.T 中的每个元素与其对应位置的布尔值相乘。如果布尔值为 True,则结果是 adj.T 中的元素;如果布尔值为 False,则结果是 0。
    • adj.multiply(adj.T > adj) 是同样的操作,但是这次是使用 adj 矩阵。
    • adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) 将原始矩阵 adj 与步骤3的结果相加,然后减去步骤4的结果。
    • 最终,这行代码的结果是一个新的矩阵,其中每个元素是原始矩阵 adj 中的元素,如果 adj.T 中的对应元素大于 adj 中的元素,则该元素被替换为 adj.T 中的对应元素;否则,该元素保持不变。换句话说,这行代码将 adj 中的每个元素替换为 adj.T 中对应位置的元素,前提是 adj.T 中的元素大于 adj 中的元素。
    • 如果用数学表达式来描述这个操作,对于矩阵 adj 中的每个元素 a_ij,新的值 a’_ij 将是:a'_ij = a_ij + (a_ji - a_ij) * (a_ji > a_ij),其中 a_ji 是 adj 的转置矩阵中对应位置的元素。如果 a_ji > a_ij,则 a’_ij = a_ji;否则,a’_ij = a_ij。

知识点三 图加自环 & 图邻接矩阵归一化

  • adj = normalize_adj(adj + sp.eye(adj.shape[0])) 这行代码调用了一个名为normalize_adj的函数,该函数用于归一化邻接矩阵。在归一化之前,它先将单位矩阵(sp.eye(adj.shape[0]))加到adj上。单位矩阵的对角线元素都是1,非对角线元素都是0,这个操作是为了确保每个节点至少与自己相连(自环)。
  • 其中 normalize_adj函数为:
def normalize_adj(mx):"""Row-normalize sparse matrix"""rowsum = np.array(mx.sum(1))r_inv_sqrt = np.power(rowsum, -0.5).flatten()r_inv_sqrt[np.isinf(r_inv_sqrt)] = 0.r_mat_inv_sqrt = sp.diags(r_inv_sqrt)return mx.dot(r_mat_inv_sqrt).transpose().dot(r_mat_inv_sqrt)
  • rowsum = np.array(mx.sum(1)) :这行代码计算了输入矩阵 mx 的每行之和,并将结果存储在 rowsum 数组中。

  • r_inv_sqrt = np.power(rowsum, -0.5).flatten():这行代码计算了 rowsum 数组中每个元素的负二分之一次方,即求每个行和的平方根的倒数。这样做的目的是为了准备对矩阵进行归一化。flatten() 函数将结果展平为一维数组。

  • r_inv_sqrt[np.isinf(r_inv_sqrt)] = 0. :这行代码检查 r_inv_sqrt 数组中是否有无穷大的值(这可能是因为行和为0导致的),并将这些无穷大的值替换为0。

  • r_mat_inv_sqrt = sp.diags(r_inv_sqrt):这行代码使用 r_inv_sqrt 数组创建了一个对角稀疏矩阵 r_mat_inv_sqrt,其中对角线上的元素是 r_inv_sqrt 中的值。

  • return mx.dot(r_mat_inv_sqrt).transpose().dot(r_mat_inv_sqrt) :这行代码返回了归一化后的矩阵。首先,mx.dot(r_mat_inv_sqrt) 将原始矩阵 mx 与 r_mat_inv_sqrt 相乘,这实际上是对 mx 的每一列进行缩放,使得每行的和为1。然后,transpose() 函数将结果转置,接着再次与 r_mat_inv_sqrt 相乘。这个转置和再次相乘的操作确保了归一化后的矩阵是对称的,这在图数据处理中是常见的,因为邻接矩阵通常是对称的。

知识点四 稀疏矩阵格式转换

  • adj = torch.Tensor(adj.toarray()).to_sparse() 这行代码将归一化后的邻接矩阵从稀疏矩阵格式转换为密集矩阵格式(toarray()),然后将其转换为PyTorch张量(torch.Tensor)。最后,它将这个张量转换为稀疏张量(to_sparse())。稀疏张量是一种优化表示,用于存储大多数元素为0的矩阵,这样可以节省内存和计算资源。
    在这行代码中,toarray() 和 to_sparse() 是两个不同的操作,它们分别将稀疏矩阵转换为密集数组,然后再将密集数组转换回稀疏张量。下面是这两个操作的详细解释:

  • toarray() :这个方法用于将稀疏矩阵(通常是 SciPy 的稀疏矩阵格式,如 scipy.sparse.csr_matrix 或 scipy.sparse.csc_matrix)转换为密集数组(即 NumPy 数组)。稀疏矩阵是一种特殊的矩阵表示形式,它只存储非零元素的位置和值,而不是存储整个矩阵的所有元素,这样可以节省内存和计算资源,特别是当矩阵非常稀疏时。toarray() 方法将稀疏矩阵转换为常规的二维数组,其中包含了所有元素,包括零元素。

  • to_sparse() :这个方法用于将密集张量(在 PyTorch 中是 torch.Tensor)转换为稀疏张量。在 PyTorch 中,稀疏张量是一种特殊的数据结构,它只存储非零元素的位置和值。这种表示形式对于处理大规模稀疏数据非常有用,因为它可以减少内存使用并提高计算效率。to_sparse() 方法创建一个稀疏张量,其中包含了密集张量中的非零元素。

  • 这行代码的意义在于:首先,它将原始的稀疏矩阵转换为密集数组,这可能是因为某些操作(如矩阵乘法)在密集数组上更容易执行,或者是因为需要将数据转换为 PyTorch 可以处理的格式。然后,它将密集数组转换回稀疏张量。这可能是因为在 PyTorch 中进行后续的稀疏矩阵操作,或者是因为稀疏张量在内存使用和计算效率方面有优势。

这篇关于【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/989462

相关文章

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

IDEA如何将String类型转json格式

《IDEA如何将String类型转json格式》在Java中,字符串字面量中的转义字符会被自动转换,但通过网络获取的字符串可能不会自动转换,为了解决IDEA无法识别JSON字符串的问题,可以在本地对字... 目录问题描述问题原因解决方案总结问题描述最近做项目需要使用Ai生成json,可生成String类型

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

Python中使用defaultdict和Counter的方法

《Python中使用defaultdict和Counter的方法》本文深入探讨了Python中的两个强大工具——defaultdict和Counter,并详细介绍了它们的工作原理、应用场景以及在实际编... 目录引言defaultdict的深入应用什么是defaultdictdefaultdict的工作原理

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod