如何将化学分子SMILES字符串转化为Pytorch图数据结构——ESOL分子水溶性数据集解析

本文主要是介绍如何将化学分子SMILES字符串转化为Pytorch图数据结构——ESOL分子水溶性数据集解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

硬核原创,转载请注明出处:
https://leytton.blog.csdn.net/article/details/130406553

一、前言

在用Pytorch图神经网络对化学分子进行数据分析的时候,经常使用现有的数据集。看到自动处理完毕的数据结构,里面的特征值让我们一脸懵逼,不知道代表的是什么含义。本文将带大家分析这些数据结构的来龙去脉。

二、数据原始特征

在使用图神经网络(GNN)对化学分子进行水溶性预测的实验中,加载了MoleculeNetESOL数据集。我们打开原始的csv文件,结构是这样的(非专业翻译,有误恳请留言纠正):

表头含义示例
Compound ID化合物ID2-pyrrolidone
ESOL predicted log solubility in mols per litreESOL预测对数溶解度(mol/L)0.243
Minimum Degree最小度1
Molecular Weight分子量85.10600000000001
Number of H-Bond Donors氢键供体数1
Number of Rings环数1
Number of Rotatable Bonds可旋转键数0
Polar Surface Area极性表面积29.1
measured log solubility in mols per litre测量对数溶解度(mol/L)1.07
smiles分子SMILES字符串O=C1CCCN1

从smiles中可以看到,这个分子有OCN、H(一般省略)四种元素,除去H有六个原子。

三、分析预处理数据

加载数据

如下面代码,加载ESOL数据集后将其打印出来:

from torch_geometric.datasets import MoleculeNetdata = MoleculeNet(root="data", name="ESOL")print("Dataset Size:", len(data))
print("Dataset classes:", data.num_classes)
print("Dataset features:", data.num_features)
Dataset Size: 1128
Dataset classes: 734
Dataset features: 9

从结果可以看到,有1128个分子样本,734种类型,每个分子有9个特征。

分析数据

我们选择第11个分子(smiles比较短)进行分析:

print("Sample:", data[10])
print("Sample y:", data[10].y)
Sample: Data(x=[6, 9], edge_index=[2, 12], edge_attr=[12, 3], smiles='O=C1CCCN1', y=[1, 1])
Sample y: tensor([[1.0700]])

可以看到x、edge_index、edge_attr 是二维数组,y可以看成一个值(水溶性)。

关于水溶性参考《理化性质|(logSw和logP)小分子化合物水溶性和脂溶性指标》

画出分子图

根据SMILES字符串,将其分子图画出来:

from rdkit import Chem
from rdkit.Chem import Drawmolecule = Chem.MolFromSmiles(data[10]["smiles"])
# Draw.MolToFile(molecule, "mol.png")
Draw.MolToImage(molecule)

在这里插入图片描述

edge_index数据分析

edge_index数组打印出来:

print(data[10].edge_index.T)
tensor([[0, 1],[1, 0],[1, 2],[1, 5],[2, 1],[2, 3],[3, 2],[3, 4],[4, 3],[4, 5],[5, 1],[5, 4]])

这是O、C、N六个原子的连接关系。

x数据分析

x数组打印出来:

print(data[10].x.shape)
print(data[10].x)
torch.Size([6, 9])
tensor([[8, 0, 1, 5, 0, 0, 3, 0, 0],[6, 0, 3, 5, 0, 0, 3, 0, 1],[6, 0, 4, 5, 2, 0, 4, 0, 1],[6, 0, 4, 5, 2, 0, 4, 0, 1],[6, 0, 4, 5, 2, 0, 4, 0, 1],[7, 0, 3, 5, 1, 0, 3, 0, 1]])

这就不太看得懂了,看起来像是描述6个原子9个特征的二维数组。

四、真相:从SMILES字符串得到

作者查阅资料无果,那么久只能去分析MoleculeNet中的代码了,到底对原始数据进行了怎样的处理,x中的数据是怎样来的。

点进去看到一个process函数应该是处理数据的,我对其进行了注释:

# Format: name: [display_name, url_name, csv_name, smiles_idx, y_idx]names = {'esol': ['ESOL', 'delaney-processed.csv', 'delaney-processed', -1, -2],'freesolv': ['FreeSolv', 'SAMPL.csv', 'SAMPL', 1, 2],'lipo': ['Lipophilicity', 'Lipophilicity.csv', 'Lipophilicity', 2, 1],'pcba': ['PCBA', 'pcba.csv.gz', 'pcba', -1,slice(0, 128)],'muv': ['MUV', 'muv.csv.gz', 'muv', -1,slice(0, 17)],'hiv': ['HIV', 'HIV.csv', 'HIV', 0, -1],'bace': ['BACE', 'bace.csv', 'bace', 0, 2],'bbbp': ['BBPB', 'BBBP.csv', 'BBBP', -1, -2],'tox21': ['Tox21', 'tox21.csv.gz', 'tox21', -1,slice(0, 12)],'toxcast':['ToxCast', 'toxcast_data.csv.gz', 'toxcast_data', 0,slice(1, 618)],'sider': ['SIDER', 'sider.csv.gz', 'sider', 0,slice(1, 28)],'clintox': ['ClinTox', 'clintox.csv.gz', 'clintox', 0,slice(1, 3)],}def process(self):with open(self.raw_paths[0], 'r') as f: #读取原始数据文件dataset = f.read().split('\n')[1:-1] #按行分割,并去掉第一行dataset = [x for x in dataset if len(x) > 0]  # 去掉空行data_list = []for line in dataset:  #遍历每行line = re.sub(r'\".*\"', '', line)  # 去掉".*"字符串line = line.split(',') #逗号分隔smiles = line[self.names[self.name][3]] #获取到smiles字符串ys = line[self.names[self.name][4]] #获取到y值ys = ys if isinstance(ys, list) else [ys] #将y值统一成数组形式ys = [float(y) if len(y) > 0 else float('NaN') for y in ys] #将y转成float类型y = torch.tensor(ys, dtype=torch.float).view(1, -1) #将y转成torch.float类型# 重点:获取x、edge_index、edge_attr数据,需要查看from_smiles函数data = from_smiles(smiles)  data.y = y  #y处理完毕if self.pre_filter is not None and not self.pre_filter(data):continueif self.pre_transform is not None:data = self.pre_transform(data)data_list.append(data)torch.save(self.collate(data_list), self.processed_paths[0])

从上面分析可以知道,原来x、edge_index、edge_attr数据都是通过将smile字符串传递到from_smiles函数获取到的!

from_smiles函数如下:

def from_smiles(smiles: str, with_hydrogen: bool = False,kekulize: bool = False) -> 'torch_geometric.data.Data':# 太多了省略。。。return Data(x=x, edge_index=edge_index, edge_attr=edge_attr, smiles=smiles)

这下可以参考这个函数的代码进一步分析了。

我们直接指定smiles进行分析:

smiles='O=C1CCCN1'
from rdkit import Chemmol = Chem.MolFromSmiles(smiles)
for atom in mol.GetAtoms():print(f'原子序号:{atom.GetAtomicNum()}, 手性信息:{atom.GetChiralTag()}, 度:{atom.GetTotalDegree()}, 电荷:{atom.GetFormalCharge()}, 连接氢原子数:{atom.GetTotalNumHs()}, 自由基:{atom.GetNumRadicalElectrons()}, 杂化类型:{atom.GetHybridization()}, 芳香性:{atom.GetIsAromatic()}, 是否在环上:{atom.IsInRing()}')
原子序号:8, 手性信息:CHI_UNSPECIFIED, 度:1, 电荷:0, 连接氢原子数:0, 自由基:0, 杂化类型:SP2, 芳香性:False, 是否在环上:False
原子序号:6, 手性信息:CHI_UNSPECIFIED, 度:3, 电荷:0, 连接氢原子数:0, 自由基:0, 杂化类型:SP2, 芳香性:False, 是否在环上:True
原子序号:6, 手性信息:CHI_UNSPECIFIED, 度:4, 电荷:0, 连接氢原子数:2, 自由基:0, 杂化类型:SP3, 芳香性:False, 是否在环上:True
原子序号:6, 手性信息:CHI_UNSPECIFIED, 度:4, 电荷:0, 连接氢原子数:2, 自由基:0, 杂化类型:SP3, 芳香性:False, 是否在环上:True
原子序号:6, 手性信息:CHI_UNSPECIFIED, 度:4, 电荷:0, 连接氢原子数:2, 自由基:0, 杂化类型:SP3, 芳香性:False, 是否在环上:True
原子序号:7, 手性信息:CHI_UNSPECIFIED, 度:3, 电荷:0, 连接氢原子数:1, 自由基:0, 杂化类型:SP2, 芳香性:False, 是否在环上:True

如上所示,这9个特征就是x变量中每个原子的含义,对其进行一些编码变换就构造成了x变量。具体的原子更多的属性,可以参考 RDKit 文档

接下来我们分析edge_attredge_index变量含义:

for bond in mol.GetBonds(): #便利所有的键i = bond.GetBeginAtomIdx()j = bond.GetEndAtomIdx()print(f'连接:{i,j},{j,i}')print(f'键的类型:{bond.GetBondType()}, Stereo:{bond.GetStereo()}, 是否共轭:{bond.GetIsConjugated()}')
连接:(0, 1),(1, 0)
键的类型:DOUBLE, Stereo:STEREONONE, 是否共轭:True
连接:(1, 2),(2, 1)
键的类型:SINGLE, Stereo:STEREONONE, 是否共轭:False
连接:(2, 3),(3, 2)
键的类型:SINGLE, Stereo:STEREONONE, 是否共轭:False
连接:(3, 4),(4, 3)
键的类型:SINGLE, Stereo:STEREONONE, 是否共轭:False
连接:(4, 5),(5, 4)
键的类型:SINGLE, Stereo:STEREONONE, 是否共轭:False
连接:(5, 1),(1, 5)
键的类型:SINGLE, Stereo:STEREONONE, 是否共轭:True

这就是分子SMILES字符串转化成图数据结构的过程,可以看到只用到了原始数据里的SMILES字符串水溶性结果

在Pytorch官网找了半天没找到数据集的说明资料,等我分析完后,才发现,这里已经有大佬发表了相关文章。不过,如果不知道图结构数据是从SMILES字符串分析得到,很难通过关键字找到这些资料。
How to turn a SMILES string into a molecular graph for Pytorch Geometric

这篇关于如何将化学分子SMILES字符串转化为Pytorch图数据结构——ESOL分子水溶性数据集解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

IDEA与JDK、Maven安装配置完整步骤解析

《IDEA与JDK、Maven安装配置完整步骤解析》:本文主要介绍如何安装和配置IDE(IntelliJIDEA),包括IDE的安装步骤、JDK的下载与配置、Maven的安装与配置,以及如何在I... 目录1. IDE安装步骤2.配置操作步骤3. JDK配置下载JDK配置JDK环境变量4. Maven配置下

Python中配置文件的全面解析与使用

《Python中配置文件的全面解析与使用》在Python开发中,配置文件扮演着举足轻重的角色,它们允许开发者在不修改代码的情况下调整应用程序的行为,下面我们就来看看常见Python配置文件格式的使用吧... 目录一、INI配置文件二、YAML配置文件三、jsON配置文件四、TOML配置文件五、XML配置文件

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi

mysql通过frm和ibd文件恢复表_mysql5.7根据.frm和.ibd文件恢复表结构和数据

《mysql通过frm和ibd文件恢复表_mysql5.7根据.frm和.ibd文件恢复表结构和数据》文章主要介绍了如何从.frm和.ibd文件恢复MySQLInnoDB表结构和数据,需要的朋友可以参... 目录一、恢复表结构二、恢复表数据补充方法一、恢复表结构(从 .frm 文件)方法 1:使用 mysq

mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespace id不一致处理

《mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespaceid不一致处理》文章描述了公司服务器断电后数据库故障的过程,作者通过查看错误日志、重新初始化数据目录、恢复备... 周末突然接到一位一年多没联系的妹妹打来电话,“刘哥,快来救救我”,我脑海瞬间冒出妙瓦底,电信火苲马扁.

golang获取prometheus数据(prometheus/client_golang包)

《golang获取prometheus数据(prometheus/client_golang包)》本文主要介绍了使用Go语言的prometheus/client_golang包来获取Prometheu... 目录1. 创建链接1.1 语法1.2 完整示例2. 简单查询2.1 语法2.2 完整示例3. 范围值

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

从零教你安装pytorch并在pycharm中使用

《从零教你安装pytorch并在pycharm中使用》本文详细介绍了如何使用Anaconda包管理工具创建虚拟环境,并安装CUDA加速平台和PyTorch库,同时在PyCharm中配置和使用PyTor... 目录背景介绍安装Anaconda安装CUDA安装pytorch报错解决——fbgemm.dll连接p

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

pycharm远程连接服务器运行pytorch的过程详解

《pycharm远程连接服务器运行pytorch的过程详解》:本文主要介绍在Linux环境下使用Anaconda管理不同版本的Python环境,并通过PyCharm远程连接服务器来运行PyTorc... 目录linux部署pytorch背景介绍Anaconda安装Linux安装pytorch虚拟环境安装cu