目录
1. 预备知识
GNN Framework
2. GNN使用PyG(PyTorch第三方库)的实现
torch_geometric 官方文档
1. Message Passing
继承MessagePassing基类的GCNConv
2. 节点/边表征以及图表征
node /edge level:
graph level:节点嵌入——节点表征——图池化——图的表征——线性变换
【Zachary‘s karate club network数据集进行PyG小白入门实战 】
1. 数据集
2. 数据集展示(使用networkx可视化展示)
3. Graph Neural Network网络定义
4. 输出特征展示
5. 训练模型(Semi-supervised)
【一些PyG的数据类型】
Data 类(PyG的数据结构)
Batch类【详情可参考】
batch属性说明
3. 生化任务的一些第三方包
rdkit 官方文档
1. 如何画分子&一些分子操作方法的引入
Drawing Molecules
Some Simple Calculation
2. 子结构搜索&分子指纹
4. 引用
️一些视频【强烈安利】
其他
GNN可以被抽象为Aggregate和两个步骤,分为MPNN(Messege Passing Neural Networks)和NLNN(Non-local Neural Networks)
(1)公式中h代表各个层中某个节点的隐向量,它是随机初始化的(或者加入原有节点特征)。a是某个节点i,对于他的邻居j们,通过某个聚合函数(sum、average...)aggregate获得的消息(在代码中可能会使用torch_scatter.scatter 做scatter_sum/scatter_mean运算)。
通过某个函数将(l-1)层的隐向量和(l)层的消息combine(消息传递框架中也叫做update),就能够获得(l)层的隐向量。
此外,仅仅获得每个节点的隐向量还不足以表征整个图,所以需要一个图读出(Readout)函数来将很多节点的隐向量表征为一个统一长度的向量表示。
这个readout function可以是对各个节点的隐向量做max pooling、average pooling获得特征(graph pooling操作:在代码中可能会使用torch_scatter.scatter 做scatter_sum/scatter_mean运算);也可以是引入一个上帝节点连接每个图中的节点,取最后一层中上帝节点的隐向量作为表征;还可以是differentiable hierarchical pooling、Edge Pooling、Set2Set等方法。
广义角度上的理解,可参考此文:图机器学习——5.5 广义 GNN 框架:消息传递与聚合_Kanny广小隶的博客-CSDN博客_gnn聚合5. 广义视角下的 GNN 框架GNN 层的本质为:消息(Message) + 聚合(Aggregation)。在这一视角下的有许多不同的实例:GCN,GraphSAGE,GAT等,下面我们将着重讲解这三个不同的实例。GNN 的总体框架分别包括:1)消息 与 2)聚合,也就是一个网络层中的操作。3)层与层之间的连接4)图增广(Graph augmentation) 与 5)学习目标(Learning Object)下面我们一部分一部分进行分析。1)消息(Message)图网络中的https://kanny.blog.csdn.net/article/details/124929624?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-124929624-blog-118027083.pc_relevant_aa_2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-124929624-blog-118027083.pc_relevant_aa_2&utm_relevant_index=1
torch_geometric — pytorch_geometric documentationhttps://pytorch-geometric.readthedocs.io/en/latest/modules/root.html
PyTorch Geometric,简称Pyg。Pyg库包含易用的小批量加载器(mini-batch loader)、多GPU支持、大量常见基准数据集和有用的变换,适用于任意图像、三维网格(3D mesh)和点云。基于PyTorch构建,用于处理不规则结构化输入数据(如图、点云、流形)。除了一般的图形数据结构和处理方法外,它还包含从关系学习到3D数据处理等领域中最新发布的多种方法。通过利用稀疏 GPU 加速、提供专用的 CUDA 内核以及为不同大小的输入样本引入高效的小批量处理,PyTorch Geometric 实现了很高的数据吞吐量。
安装踩坑过后的友情提示:建议严格参考官方GitHub安装说明!!!
(踩坑解决详情见4的其他部分)GitHub - pyg-team/pytorch_geometric: Graph Neural Network Library for PyTorchGraph Neural Network Library for PyTorch. Contribute to pyg-team/pytorch_geometric development by creating an account on GitHub.https://github.com/pyg-team/pytorch_geometric
消息传递范式是一种聚合邻接节点信息(称为邻域聚合,节点的邻居的消息聚合到节点本身)来更新中心节点信息的范式,它将卷积算子推广到了不规则数据领域,实现了图与神经网络的连接。消息传递的详情可参考,讲得很清晰:图神经网络task2——消息传递_Wmnyang的博客-CSDN博客这是目录1、消息传递范式2、MessagePassing基类2.1、MP类和基本方法3、MessagePassing实例3.1、三个函数的数学定义3.2、`GCNConv`实现步骤(1)向邻接矩阵添加自环边(2)对节点的特征矩阵进行线性变换(3)对变换后的节点特征进行标准化(4)归一化j中的节点特征(5)将节点特征求和参考文献1、消息传递范式消息传递是实现GNN的一种通用框架和编程范式。它从聚合与更新的角度归纳总结了多种GNN模型的实现,它的思路是:首先结合边的特征以及和边相连的两个节点的特征,得到 https://blog.csdn.net/Wmnyang/article/details/118048781
该范式包含这样三个步骤:
基于此范式,我们可以定义聚合邻接节点信息来生成中心节点表征的图神经网络。在PyG中,MessagePassing基类是所有基于消息传递范式的图神经网络的基类,它大大地方便了我们对图神经网络的构建。
【步骤】
- 首先导入必要的包(from from torch_geometric.nn import MessagePassing)
- 其次创建一个类,继承MessagePassing基类
class MessagePassing(aggr='add', flow='source_to_target', node_dim=0)
aggr: 定义要使用的聚合方案(“add”、“mean"或"max”)
flow: 定义消息传递的流向(“source_to_target"或"target_to_source”)
node_dim: 定义沿着哪个轴线传播
然后初始化__init()__,定义forward()方法用于模型的表示
接着可以覆写这几个函数:
message()
aggregate()(
查看MessagePassing
的源码,可以看到其aggregate
函数的定义(在PyG中是通过scatter函数来实现上述过程)PyG教程(7):剖析邻域聚合-pudn.com)
- message_and_aggregate()方法
- update()方法
数学定义以及PyG实现-GCNConv
import torch
from torch_geometric.nn import MessagePassing
from torch_geometric.utils import add_self_loops, degree
class GCNConv(MessagePassing):
def __init__(self, in_channels, out_channels):
super(GCNConv, self).__init__(aggr='add', flow='source_to_target')
# "Add" aggregation (Step 5).
# flow='source_to_target' 表示消息从源节点传播到目标节点
self.lin = torch.nn.Linear(in_channels, out_channels)
#所有逻辑在forward()方法中实现
def forward(self, x, edge_index):
# x has shape [N, in_channels]
# edge_index has shape [2, E]
# Step 1: Add self-loops to the adjacency matrix.
# 使用torch_geometric.utils.add_self_loops() 给边索引添加自循环边【对应1. 向邻接矩阵添加自环边】
edge_index, _ = add_self_loops(edge_index, num_nodes=x.size(0))
# Step 2: Linearly transform node feature matrix.
# torch.nn.Linear 线性变换【对应2. 对节点表征做线性变换】
x = self.lin(x)
# Step 3: Compute normalization.【对应3. 计算归一化系数】
row, col = edge_index
deg = degree(col, x.size(0), dtype=x.dtype)
deg_inv_sqrt = deg.pow(-0.5)
norm = deg_inv_sqrt[row] * deg_inv_sqrt[col]
# Step 4-5: Start propagating messages.
# progagate包含了(先调用message(),再aggregate,再update)
return self.propagate(edge_index, x=x, norm=norm)
#MessagePassing.propagate(edge_index, size=None, **kwargs):
# 开始传播消息的起始调用。它以edge_index(边的端点的索引)和flow(消息的流向)以及一些额外的数据为参数,size=(N,M)设置对称邻接矩阵的形状。
def message(self, x_j, norm):
# x_j has shape [E, out_channels]
# Step 4: Normalize node features.
return norm.view(-1, 1) * x_j
from torch_geometric.datasets import Planetoid
dataset = Planetoid(root='dataset/Cora', name='Cora')
data = dataset[0]
print(data.x)#node_feature
print(data.edge_index)#边索引
net = GCNConv(data.num_features, 64)
h_nodes = net(data.x, data.edge_index)
print(h_nodes.shape)
输出结果:
在图节点预测或边预测任务中,首先需要生成节点表征(Node Representation)。我们使用图神经网络来生成节点表征,并通过基于监督学习的对图神经网络的训练,使得图神经网络学会产生高质量的节点表征。高质量的节点表征能够用于衡量节点的相似性,同时高质量的节点表征也是准确分类节点的前提。
图表征学习要求根据节点属性、边和边的属性(如果有的话)生成一个向量作为图的表征,基于图表征我们可以做图的预测.
基于图同构网络(Graph Isomorphism Network, GIN)的图表征网络是当前最经典的图表征学习网络,为了得到图表征首先需要做节点表征,然后做图读出。GIN中节点表征的计算遵循WL Test算法中节点标签的更新方法,因此它的上界是WL Test算法。在图读出中,我们对所有的节点表征(加权,如果用Attention的话)求和,这会造成节点分布信息的丢失。
详情可参考:https://blog.csdn.net/LuoMin2523/article/details/118464411?spm=1001.2014.3001.5502https://blog.csdn.net/LuoMin2523/article/details/118464411?spm=1001.2014.3001.5502
⚛️⚛️⚛️⚛️⚛️⚛️
此模块首先采用GINNodeEmbedding模块对图上每一个节点做节点嵌入(Node Embedding),得到节点表征;然后对节点表征做图池化得到图的表征;最后用一层线性变换对图表征转换为对图的预测。
- 基于图同构网络的节点嵌入模块(GINNodeEmbedding Module)
输入到此节点嵌入模块的节点属性为类别型向量。
步骤:
1)嵌入。用AtomEncoder对输入向量做嵌入得到第0层节点表征
2)计算节点表征。
从第1层开始到第num_layers层逐层计算节点表征。(每一层节点表征的计算都以上一层的节点表征h_list[layer]、边edge_index和边的属性edge_attr为输入)
注意事项:GINConv的层数越多,此节点嵌入模块的感受野(receptive field)越大,结点i的表征最远能捕获到结点i的距离为num_layers的邻接节点的信息。
- 输入的边属性(edge_attr为类别型),先将类别型边属性转换为边表征,GINConv模块遵循:“消息传递,消息聚合,消息更新”这一过程。
- AtomEncoder和BondEncoder
节点(原子)和边(化学键)的属性都为离散值,属于不同的空间。
所以通过Embedding,将节点属性和边属性分别映射到一个新的空间,在这个新的空间中对节点和边进行消息聚合。
注:节点属性有多少维,就需要多少个嵌入函数(通过调用 torch.nn.Embedding(dim,emb_dim))可以实例化一个嵌入函数
其中dim为:被嵌入数据可能取值的数量;emb_dim:要映射到的空间的维度。
得到的嵌入函数,接收一个x(0
在forward()函数中,我们对不同属性值得到的不同嵌入向量进行了相加操作,实现了节点不同属性融合在一起(消息聚合)。
数据集——数据集展示——GCN网络定义——输入特征展示——训练模型
from torch_geometric.datasets import KarateClub
dataset = KarateClub()
print(f'Dataset:{dataset}:')
print('===================')
print(f'Number of graphs:{len(dataset)}')
print(f'Number of features:{dataset.num_features}')
print(f'Number of classes:{dataset.num_classes}')
'''
Dataset:KarateClub():
===================
Number of graphs:1 #只有一个图,对点做分类
Number of features:34 #每一个点有34个特征
Number of classes:4 #每个点做4分类
'''
dataset[0]
'''
Data(x=[34, 34], edge_index=[2, 156], y=[34], train_mask=[34])
'''
edge_index = dataset[0].edge_index
print(edge_index.t())
'''
tensor([[ 0, 1],
[ 0, 2],
[ 0, 3],
[ 0, 4],
[ 0, 5],
[ 0, 6],
[ 0, 7],
[ 0, 8],
[ 0, 10],
[ 0, 11],
[ 0, 12],
[ 0, 13],
[ 0, 17],
[ 0, 19],
[ 0, 21],
[ 0, 31],
[ 1, 0],
[ 1, 2],
[ 1, 3],
[ 1, 7],
[ 1, 13],
[ 1, 17],
[ 1, 19],
[ 1, 21],
[ 1, 30],
...
[33, 29],
[33, 30],
[33, 31],
[33, 32]])
'''
图的表示用Data格式
torch_geometric.nn:是可以调用的一些层
torch_geometric.data:是可以调用的一些数据(数据结构)
torch_geometric.datasets:是可以调用的一些数据集
torch_geometric.utils:是可以调用的一些基本处理的函数
import matplotlib.pyplot as plt
import networkx as nx
def visualize_graph(G,color):
plt.figure(figsize=(7,7))
plt.xticks([])
plt.yticks([])
nx.draw_networkx(G,pos=nx.spring_layout(G,seed=42),with_labels=False,node_color=color,cmap="Set2")
plt.show()
from torch_geometric.utils import to_networkx
data = dataset[0]
G = to_networkx(data,to_undirected=True)
visualize_graph(G,color=data.y)
很明显classes=4,即有4个不同的类别
GCN layer(与上述 继承MessagePassing基类的GCNConv 略有不同)
import torch
from torch.nn import Linear
from torch_geometric.nn import GCNConv
class GCN(torch.nn.Module):
def __init__(self):
super().__init__()
torch.manual_seed(1234)#设置随机种子是为了确保每次生成固定的随机数
# 定义输入特征和输出特征即可
self.conv1 = GCNConv(dataset.num_features,4)#dataset.num_features:34维向量,经过这一层得到4维向量
self.conv2 = GCNConv(4,4)
self.conv3 = GCNConv(4,2)
#连接全连接
self.classifier = Linear(2,dataset.num_classes)# 4个类别概率值
def forward(self,x,edge_index):
h = self.conv1(x,edge_index)#输入特征与邻接矩阵 x:图(有每个点的特征),edge_index(邻接矩阵)
h = h.tanh()
h = self.conv2(h,edge_index)
h = h.tanh()
h = self.conv3(h,edge_index)
h = h.tanh()
#分类层,即FC
out = self.classifier(h)
return out,h #out为输出结果,h为得到的中间结果【self.conv3 = GCNConv(4,2)】,即两维向量
model = GCN()
print(model)
'''
GCN(
(conv1): GCNConv(34, 4)
(conv2): GCNConv(4, 4)
(conv3): GCNConv(4, 2)
(classifier): Linear(in_features=2, out_features=4, bias=True)
)
'''
def visualize_embedding(h,color,epoch=None,loss=None):
plt.figure(figsize=(7,7))
plt.xticks([])
plt.yticks([])
#detach(): 返回一个新的Tensor,但返回的结果是没有梯度的。cpu():把gpu上的数据转到cpu上。numpy():将tensor格式转为numpy
h = h.detach().cpu().numpy()
plt.scatter(h[:,0],h[:,1],s=140,c=color,cmap="Set2")
if epoch is not None and loss is not None:
plt.xlabel(f"Epoch:{epoch},Loss:{loss.item():.4f}",fontsize=16)
plt.show()
# 展示输出的两维特征(还未训练前)
model = GCN()
_, h = model(data.x,data.edge_index)
print(f'Embedding Shape:{list(h.shape)}') #Embedding Shape:[34, 2]
visualize_embedding(h,color=data.y)
上图为随机初始化的两维向量
import time
model = GCN()
criterion = torch.nn.CrossEntropyLoss() #define loss criterion 分类损失函数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01)#优化器
#train
def train(data):
optimizer.zero_grad()#梯度清零
out,h = model(data.x,data.edge_index)#h为两维向量主要是为了展示画图
loss = criterion(out[data.train_mask],data.y[data.train_mask])#data.train_mask 即看train_mask为True的,即只看有标签的结点
#semi-supervised:只关注有标签的那些
loss.backward()#反向传播
optimizer.step()#参数更新
return loss,h
#迭代
for epoch in range(401):#1个epoch即1个图
loss,h = train(data)
#每10个epoch去画一个图
if epoch%10 ==0:
visualize_embedding(h,color=data.y,epoch=epoch,loss=loss)
time.sleep(0.3) #让画停一下
【一些PyG的数据类型】
Data 类(PyG的数据结构)
一些data的方法和属性补充:
data.keys
:返回属性名列表。data['x']
:返回属性名为'x'
的值。for key, item in data: ...
:按照字典的方法返回data属性和对应值。'x' in data
:判断某一属性是否在data中。data.num_nodes
:返回节点个数,相当于x.shape[0]
。data.num_edges
:返回边的条数,相当于edge_index.shape[1]
。data.contains_isolated_nodes()
:是否存在孤立的节点。data.contains_self_loops()
:是否存在自环。data.is_directed()
:是否是有向图。data.to(torch.device('cuda'))
:将数据对象转移到GPU。
Common Benchmark Datasets-PyG包含了很多公用的数据集,所有Planetoid数据集(Cora, Citeseer, Pubmed)。来自TUDataset | TUD Benchmark datasets的所有图分类数据集,和其简洁版,QM7和QM9数据集等等。
Batch类【详情可参考】
番外篇:PyG框架及Cora数据集简介 - 知乎由于GNN的输入是不规则的graph,所以在训练中无法方便地像image或text输入数据,该篇文章介绍PyG框架,介绍部分基本上来自于PyG的文档的前面两节。介绍Cora数据集是因为在该篇之后会单独再发一篇使用PyG框架及原生…https://zhuanlan.zhihu.com/p/78452993?from_voters_page=true
Mini-Batches(Batch类是继承Data的,是自动生成的)
神经网络通常以批量方式进行训练。 PyG 通过创建稀疏块对角邻接矩阵(由 edge_index 定义)并在节点维度上连接特征和目标矩阵来实现小批量的并行化。 这种设计使得我们可以将不同规模的图放在同一个batch中。
PyTorch Geometric中采用的将多个图封装成批的方式是:将小图作为连通组件(connected component)的形式合并,构建一个大图。于是小图的邻接矩阵存储在大图邻接矩阵的对角线上。大图的邻接矩阵、属性矩阵、预测目标矩阵分别为:
注意,邻接矩阵没有额外的内存开销,因为它们是以稀疏的方式保存的,只保留非零项,即边。
- 通过torch_geometric.data.DataLoader类,多个小图被封装成一个大图。 torch_geometric.data.DataLoader是PyTorch的DataLoader的子类,它覆盖了collate()函数(该函数定义了一列表的样本是如何封装成批的)。因此,所有可以传递给PyTorch DataLoader的参数也可以传递给PyTorch Geometric的 DataLoader,例如,num_workers。
- torch_geometric.data.Batch类继承自torch_geometric.data.Data,多出了一个batch属性。batch属性为一个用于标记每一个来自于哪张图的列向量。
ENZYMES数据集(包含600个图,分为6类)为例做介绍
注:上图黄字说明——第一个graph包含有37个节点,每个节点特征维度为3,有 1682=84 条无向边,并且该graph的标签(类别)的维度为1。
#加载ENZYMES数据集
from torch_geometric.datasets import TUDataset
from torch_geometric.loader import DataLoader
dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES', use_node_attr=True)
loader = DataLoader(dataset, batch_size=4, shuffle=True)
#获取一个batch
batch = loader.__iter__().next()
print(batch)
batch属性说明
1. ptr属性
如上图所示batch['ptr']的结果为:tensor([ 0, 20, 62, 81, 130])
for i in range(batch.num_graphs): #num_graphs:4 print(batch[i]) #batch['ptr']:tensor([ 0, 20, 62, 81, 130]) ''' Data(edge_index=[2, 82], x=[20, 21], y=[1])——batch[0]就是[0:20] 20-0=20 Data(edge_index=[2, 176], x=[42, 21], y=[1])——batch[1]就是[20:62] 62-20=42 Data(edge_index=[2, 78], x=[19, 21], y=[1])——batch[2]就是[62:81] 81-62=19 Data(edge_index=[2, 188], x=[49, 21], y=[1])——batch[3]就是[81:130] 130-81=49 '''
2. batch属性
#加载ENZYMES数据集 from torch_geometric.datasets import TUDataset from torch_geometric.loader import DataLoader dataset = TUDataset(root='/tmp/ENZYMES', name='ENZYMES', use_node_attr=True) ## 每次加载4个数据到内存中,loader = DataLoader(dataset, batch_size=4, shuffle=True) loader = DataLoader( # 要加载的数据集 dataset=dataset, # ENZYMES包含600个图 # 每次加载4个 batch_size=4, # 每次加入进来之后是否随机打乱数据(可以增加模型的泛化性) shuffle=True ) batch = loader.__iter__().next() print(batch) print(batch['ptr']) print(batch.batch) print((batch.batch==0).sum()) print((batch.batch==1).sum()) # edge_index:连接的边 #x:整个batch的节点特征矩阵 #y:graph标签 #batch:列向量,用于指示每个节点属于batch中的第几个graph #ptr: pointer record 第几个graph起始的指针位置 ''' DataBatch(edge_index=[2, 498], x=[124, 21], y=[4], batch=[124], ptr=[5]) tensor([ 0, 27, 49, 108, 124]) tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]) tensor(27) #第一个graph graph0有27个图 tensor(22) #第二个graph graph1有49-27=22个图 '''
为什么要获取一个batch?
【Reminder】
- parser.py 中的batch_size是决定从比如ENZYMES数据集中抽多少个graph出来
- batch[0]的graph都一样(其SMILES分子式也是一样的)
分子和蛋白质是可以用图来表示的结构化实体。原子或残基作为节点,化学键或链作为边。
RDKit Cookbook — The RDKit 2022.03.1 documentationhttps://www.rdkit.org/docs/Cookbook.html
RDKit是一个专门处理化学分子数据的包,可以用来读取分子文件smiles,提取分子的各种特征。(比如读取toxcast.csv文件里面的smiles,然后将smiles转成RDKit的molecules)
from rdkit import Chem
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import Draw
IPythonConsole.ipython_useSVG=False #如果想展示PNG请设置为FALSE
- mol对象是RDKit的特殊的对象,专门用于保存化学分子的。
- 下面两幅图展示了如何画一个分子结构式以及对有原子编号的分子结构式
- 注:画的这个图是 a kinase inhibitor(激酶抑制剂)
【Code】
#将分子中的原子都标记上原子编号 def mol_with_atom_index(mol): for atom in mol.GetAtoms():#返回原子atom对象组成的列表 atom.SetAtomMapNum(atom.GetIdx())#返回原子编号 return mol #Chem.MolFromSmiles()输入的字符串是SMILES(用于表示分子的一种方法),得到的是mol对象 mol = Chem.MolFromSmiles("C1CC2=C3C(=CC=C2)C(=CN3C1)[C@H]4[C@@H](C(=O)NC4=O)C5=CNC6=CC=CC=C65") # With atom index mol_with_atom_index(mol)
添加原子索引的更简单方法是调整 IPythonConsole 属性。 这会产生与上面示例类似的图像,不同之处在于原子索引现在靠近原子,而不是原子位置。
【Code】
from rdkit import Chem
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import Draw
IPythonConsole.drawOptions.addAtomIndices = True
IPythonConsole.molSize = 300,300
mol = Chem.MolFromSmiles("C1CC2=C3C(=CC=C2)C(=CN3C1)[C@H]4[C@@H](C(=O)NC4=O)C5=CNC6=CC=CC=C65")
mol
from rdkit import Chem
mol = Chem.MolFromSmiles("C1CC2=C3C(=CC=C2)C(=CN3C1)[C@H]4[C@@H](C(=O)NC4=O)C5=CNC6=CC=CC=C65")
atom0 = mol.GetAtomWithIdx(0)
atom0 #返回结果:
- 注:分子分为原子和键
1. 原子信息 | 得到了atom对象,其常用的内置方法为:
|
2. 键信息 | 得到键对象bond, 内置了大量的方法:
|
计算原子电荷值 Gasteiger Charges
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.Draw import IPythonConsole
IPythonConsole.molSize = 250,250
m = Chem.MolFromSmiles('c1ncncc1C(=O)[O-]')
# Gasteiger Charges:原子电荷
# 计算一个分子的Gasteiger电荷。 使用称为_GasteigerCharge的属性为每个Atom对象存储计算出的值。 可以通过将此值传递给相似度图来绘制电荷图。
AllChem.ComputeGasteigerCharges(m)#计算各原子的Gasteiger Charges
m
AllChem.ComputeGasteigerCharges(m)
已经将m中每个原子的Gasteiger Charges已经计算出来了并保存在每一个原子_GasteigerCharge中;然后对原子逐个使用atom.SetProp(添加原子的性质),同步可以实现直接显示。
【Code】
#设置原子电荷的属性
for atom in m.GetAtoms():
value = '%.2f'%(atom.GetDoubleProp('_GasteigerCharge'))
atom.SetProp('atomNote',value) #设置原子的属性,设置完以后,会在mol中直接显示
#这里要注意,不能直接使用atom.SetAtomMapNum(value),因为matom.SetAtomMapNum()用于添加原子编号,只能添加整数
#遍历每个原子并调用其属性值
for atom in m.GetAtoms():
print(atom.GetProp('atomNote'))
Smiles 可以看成分子的1D形式,分子的平面结构可以看成分子的2D形式。
SMARTS 在子结构匹配、化学反应等方面发挥着重要作用。
(SMART编码是前面描述的SMILES语言的扩展,可以用来创建查询。可以将SMART模式看作类似于用于搜索文本的正则表达式(换一种说法就是,smart编码相当于对smiles编码的一种模糊搜索)) 常用的SMARTS知识:
- 判断是否有子结构m.HasSubstructMatch(patt)
- 获取第一个子结构对应的原子编号m.GetSubstructMatch(patt)——返回一个元组
- m.GetSubstructMatches(patt) 获取所有子结构的原子编号——返回元组表(内含有多个元组...)
以甲氧基苯为例,查找是否含有-OCH3,若有则显示其对应的原子编号。:
【Code】
from rdkit import Chem m = Chem.MolFromSmiles('c1ccccc1OC') patt = Chem.MolFromSmarts('OC') flag =m.HasSubstructMatch(patt) if flag: print("molecu m contains group -OCH3") atomids = m.GetSubstructMatch(patt) print("matched atom id:",atomids) else: print("molecu m don't contain group -OCH3")
分子指纹就是一种分子的抽象表征,它将分子转化(编码)为一系列比特串(即比特向量,bit vector .),然后可以很容易地在分子之间进行比较,比较分子的相似性等。典型的流程是将提取分子的结构特征、然后哈希(Hashing)生成比特向量。
使用rdkit中的 from rdkit.Chem.Fingerprints import FingerprintMols
详情可参考:
化合物相似性搜索_RDKit | 基于分子指纹的分子相似性_weixin_39999859的博客-CSDN博客分子相似性: 相似性原理(similar property principle)指出,总体相似的分子应具有相似的生物活性。相似性评估 化合物的指纹对于使用计算机考虑化合物的相似性是必需的。已经提出了各种评估方法,但是最常用的评估方法称为“ Tanimoto系数 ”。使用以下等式从两个分子A和B的位阵列指纹计算Tanimoto系数:导入库import pandas as p...https://blog.csdn.net/weixin_39999859/article/details/112354718?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4-112354718-blog-97921745.pc_relevant_default&spm=1001.2101.3001.4242.3&utm_relevant_index=7
Chem : 负责基础常用的化学功能 ( 如 : 读写分子 , 子结构搜索 , 分子美化等 )
AllChem: 负责高级但不常用的化学功能 。
- torch_sparse安装问题
使用pip install torch_sparse有如下报错:
解决方案:
装了torch_geometric之后装不上sparse的参考文章:torch-sparse安装教程_机器不学习我学习的博客-CSDN博客_torch_sparse
失败原因:
应该是库和库之间依赖的问题,所以torch版本要和geometric还有sparse等module都要对应起来!
torch_geometric、 torch_sparse、 torch_scatter、 torch_cluster是一个大佬根据根据pytorch版本和一些bug修复持续更新的,因此依赖关系比较严重,根据发布的版本应该对应起来进行安装使用。
1. python——import torch 查看torch版本和the CUDA version PyTorch
2. 按照这个Installation — pytorch_geometric documentation安装
安装命令为下图蓝色highlight所示