一、背景介绍

本文针对计算机辅助药物设计 (CADD)中的分子生成方向进行一下总结,主要内容是根据模型生成的分子理化性质检验,包括多种性质的定义、计算公式、评价指标及实现代码。

计算机辅助药物设计 (CADD) 提高了药物发现的速度。在不同的方法中,DL方法一般通过神经网络训练大量的样本数据来学习样本的分子结构。不同于传统的相似配体(ligand)搜索,DL模型在训练过程中通过学习先验知识获取特征信息和一般规则。在深度学习领域,生成模型可以有效地生成具有所需特性的新化合物,这将降低药物发现的成本。深度学习在药物发现领域的应用带来了分子生成模型的发展和扩展,同时也带来了该领域的新挑战。从头分子生成的挑战之一是如何产生具有所需药理、理化化性质的新的合理分子。

生成模型用于生成具有分子活性的结构特征相似的新分子,并通过使用无监督学习来学习数据的分布特征。生成模型通常使用基于ASCII字符的SMILES串和基于Graph的分子图来描述,通过深度学习算法学习分子特征,从而从头生成(de novo drug generation)新的、未被发现的药物分子SMILES,但生成分子后,需要进行多步筛选,以筛选出符合条件、易于合成、具有目标理化性质的有研究价值分子,这些药物分子还需要做进一步的生物化学实验,通过大量实验数据分析才有可能成为新药。下面将主要介绍(X)种常见的分子性质检验指标。

二、配置环境

化合物(compounds)药物是一种主要的药物类型,通常进行相关研究时通常需要对其结构进行操作,展示,及分子量、化学描述符等计算。这里需要用到一个开源工具RDkit

RDKit是一个用于化学信息学的开源工具包,基于对化合物2D和3D分子操作,利用机器学习方法进行化合物描述符生成,fingerprint生成,化合物结构相似性计算,2D和3D分子展示等。基于python语言进行调取使用。

首先安装RDkit,这里建议用conda进行安装,其余方法都容易出现不同程度的报错。这里默认已经安装conda。

官方网站、pythonAPI、github链接如下:

RDKithttp://www.rdkit.org/https://github.com/rdkit/rdkithttps://github.com/rdkit/rdkithttps://rdkit.org/docs/index.htmlhttps://rdkit.org/docs/index.htmlPython API Reference — The RDKit 2021.09.1 documentationhttp://www.rdkit.org/docs/api-docs.html

先创建一个自己的虚拟环境,主要为避免不同项目之间包的冲突

conda create -n my_env python=3.7 #'my_env'自己起名,python版本按需安装

激活环境

conda env list #查看环境
conda activate my_env #激活环境

安装RDkit

conda install -c conda-forge rdkit

检验一下是否安装成功

import rdkit

导入后续需要包

import csv
import os
import pandas as pd
import numpy as np
from rdkit.Chem import Crippen
from rdkit.Chem import rdMolDescriptors
from rdkit.Chem import QED
from rdkit import rdBase, Chem
from rdkit.Chem import Draw, Descriptors
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit import DataStructs

三、分子性质检验指标

1、合成可行性分数(SA SCORE)

介绍:2009年诺华公司的研究员Ertl和Schuffenhauer在化学信息学杂志上发表了名为SAscore的Rdkit插件用于快速评估药物分子的合成难易程度。

评价指标:其将小分子合成难易程度用1到10区间数值进行评价,越靠近1表明越容易合成,越靠近10表明合成越困难。

计算公式:其计算权重为化合物的片段贡献减去复杂程度(SAscore =fragmentScore − complexityPenalty),其中片段贡献值根据PubChem数据库中上百万分子计算共性进行计算,复杂度则考虑分子中非标准结构特征的占比,例如大环、非标准环的合并、立体异构和分子量大小等方面。

研究员将40个化合物给化学家进行经验性评估其合成难易程度,并与SAscore得分进行比较发现与化学家给出的合成难易程度评分的相关性R2高达0.89,表明其在识别可合成难易程度上的可靠性较高。

代码:需要用到一个文件,在这里下载fpscores.pkl.gz,运行下面的脚本即可,主函数可以改成自己想要的分子SMILES

rdkit/Contrib/SA_Score at master · rdkit/rdkit · GitHubThe official sources for the RDKit library. Contribute to rdkit/rdkit development by creating an account on GitHub.https://github.com/rdkit/rdkit/tree/master/Contrib/SA_Score

import math
import pickle
from rdkit import Chem
from rdkit.Chem import rdMolDescriptors
import os
import os.path as op#get_sa_score start
_fscores = Nonedef readFragmentScores(name='fpscores'):import gzipglobal _fscores# generate the full path filename:if name == "fpscores":name = op.join(os.getcwd(), name)# name = op.join(op.dirname(__file__), name)data = pickle.load(gzip.open('%s.pkl.gz' % name))outDict = {}for i in data:for j in range(1, len(i)):outDict[i[j]] = float(i[0])_fscores = outDictdef numBridgeheadsAndSpiro(mol, ri=None):nSpiro = rdMolDescriptors.CalcNumSpiroAtoms(mol)nBridgehead = rdMolDescriptors.CalcNumBridgeheadAtoms(mol)return nBridgehead, nSpirodef calculateScore(m):if _fscores is None:readFragmentScores()# fragment scorefp = rdMolDescriptors.GetMorganFingerprint(m,2)  # <- 2 is the *radius* of the circular fingerprintfps = fp.GetNonzeroElements()score1 = 0.nf = 0for bitId, v in fps.items():nf += vsfp = bitIdscore1 += _fscores.get(sfp, -4) * vscore1 /= nf# features scorenAtoms = m.GetNumAtoms()nChiralCenters = len(Chem.FindMolChiralCenters(m, includeUnassigned=True))ri = m.GetRingInfo()nBridgeheads, nSpiro = numBridgeheadsAndSpiro(m, ri)nMacrocycles = 0for x in ri.AtomRings():if len(x) > 8:nMacrocycles += 1sizePenalty = nAtoms**1.005 - nAtomsstereoPenalty = math.log10(nChiralCenters + 1)spiroPenalty = math.log10(nSpiro + 1)bridgePenalty = math.log10(nBridgeheads + 1)macrocyclePenalty = 0.# ---------------------------------------# This differs from the paper, which defines:# macrocyclePenalty = math.log10(nMacrocycles+1)# This form generates better results when 2 or more macrocycles are presentif nMacrocycles > 0:macrocyclePenalty = math.log10(2)score2 = 0. - sizePenalty - stereoPenalty - spiroPenalty - bridgePenalty - macrocyclePenalty# correction for the fingerprint density# not in the original publication, added in version 1.1# to make highly symmetrical molecules easier to synthetisescore3 = 0.if nAtoms > len(fps):score3 = math.log(float(nAtoms) / len(fps)) * .5sascore = score1 + score2 + score3# need to transform "raw" value into scale between 1 and 10min = -4.0max = 2.5sascore = 11. - (sascore - min + 1) / (max - min) * 9.# smooth the 10-endif sascore > 8.:sascore = 8. + math.log(sascore + 1. - 9.)if sascore > 10.:sascore = 10.0elif sascore < 1.:sascore = 1.0return sascore
def my_score(mols:list):readFragmentScores("fpscores")print('smiles\tsa_score')for m in mols:s = calculateScore(m)smiles = Chem.MolToSmiles(m)print(smiles + "\t" + "\t%3f" % s)if __name__ == "__main__":a = Chem.MolFromSmiles('CN(C)CCC=C1C2=CC=CC=C2CCC2=CC=CC=C12')b = Chem.MolFromSmiles('[H][C@@]12CC3=CNC4=CC=CC(=C34)[C@@]1([H])C[C@H](CN2CC=C)C(=O)N(CCCN(C)C)C(=O)NCC')c = Chem.MolFromSmiles('CCOC1=NC(NC(=O)CC2=CC(OC)=C(Br)C=C2OC)=CC(N)=C1C#N')d = Chem.MolFromSmiles('OC(=O)C1=CC=CC=C1O')x = [a,b,c,d]sa_score=my_score(x)# print(sa_score)

结果如下:

smiles   sa_score
CN(C)CCC=C1c2ccccc2CCc2ccccc21     2.174229
C=CCN1C[C@H](C(=O)N(CCCN(C)C)C(=O)NCC)C[C@@H]2c3cccc4[nH]cc(c34)C[C@H]21     4.016443
CCOc1nc(NC(=O)Cc2cc(OC)c(Br)cc2OC)cc(N)c1C#N       2.591358
O=C(O)c1ccccc1O        1.425110

2、QED

QED(quantitative estimate of drug-likeness)是一种将药物相似性量化为介于0和1之间的数值的方法。是通过组合多个分子描述符来评估药物相似性的方法之一。

药物相似性

如Lippinski规则所示,获批药物的理化参数表明,这些化合物分布在狭窄的范围内。进入该化学空间的化合物称为“类药物 (drug-like)” 类药性不是化学结构的特征,而是由几个物理参数组合确定的指标。已经提出了几种评价药物毒性的指标,但最具影响力的是Ripinsky等人的Lippinski规则。

【注】Lipinski总结的五规则后总结为:

化合物的分子量小于500道尔顿;

化合物结构中的氢键给体 (包括羟基、氨基等)的数量不超过5个;

化合物中氢键受体的数量不超过10个;

化合物的脂水分配系数的对数值 (logP)在-2到5之间;

化合物中可旋转键的数量不超过10个。

QED的主要包括一下八种:

  • 分子量(MW)

  • logP(ALOGP)

  • 氢键供体的数量(HBDs)

  • 氢键受体的数量(HBAs)

  • 极表面积(PSA)

  • 可旋转键数目(ROTBs)

  • 芳环数目(AROMs)

  • 警报结构数目(ALERTS)

代码 

导入包

from rdkit.Chem import QED

调用

qed=QED.properties(Chem.MolFromSmiles('CN(C)CCC=C1C2=CC=CC=C2CCC2=CC=CC=C12'))
score = QED.default(Chem.MolFromSmiles('CN(C)CCC=C1C2=CC=CC=C2CCC2=CC=CC=C12'))
print(score)
print(qed)qed1=QED.properties(Chem.MolFromSmiles('[H][C@@]12CC3=CNC4=CC=CC(=C34)[C@@]1([H])C[C@H](CN2CC=C)C(=O)N(CCCN(C)C)C(=O)NCC'))
score1 = QED.default(Chem.MolFromSmiles('[H][C@@]12CC3=CNC4=CC=CC(=C34)[C@@]1([H])C[C@H](CN2CC=C)C(=O)N(CCCN(C)C)C(=O)NCC'))
print(score1)
print(qed1)

结果

0.8136783893547587
QEDproperties(MW=277.411, ALOGP=4.168600000000003, HBA=1, HBD=0, PSA=3.24, ROTB=3, AROM=2, ALERTS=0)
0.6049384423595515
QEDproperties(MW=451.61500000000024, ALOGP=3.193900000000001, HBA=4, HBD=2, PSA=71.68, ROTB=8, AROM=2, ALERTS=1)

关于logp和mw RDkit也提供了单独计算方法经过验证和QED结果相同

from rdkit.Chem import Crippen
from rdkit.Chem import Descriptorslogp = Crippen.MolLogP(Chem.MolFromSmiles(mol))#计算LogP
mw = Descriptors.MolWt(Chem.MolFromSmiles(smiles))#计算MW

 3、MOSES

这是一个基准平台,分子集 (MOSES)用于支持机器学习用于药物发现的研究。MOSES 实现了几种流行的分子生成模型,并提供了一组指标来评估生成分子的质量和多样性。通过 MOSES,的目标是规范分子生成的研究,并促进新模型的共享和比较。

除了标准的唯一性和有效性指标外,MOSES 还提供其他指标来访问生成分子的整体质量。片段相似度 (Frag) 和支架相似度 (Scaff) 是生成和测试集对应的片段或支架频率向量之间的余弦距离。最近邻相似度 (SNN) 是生成的分子与测试集中最近的分子的平均相似度。内部多样性 (IntDiv) 是生成分子的平均成对相似性。Fréchet ChemNet 距离 (FCD) 测量 ChemNet 最后一层激活分布的差异。新颖性是训练集中不存在的独特有效生成分子的一小部分。

论文链接:

https://arxiv.org/abs/1811.12823https://arxiv.org/abs/1811.12823github源码(有详细的安装使用教程):

https://github.com/molecularsets/moseshttps://github.com/molecularsets/moses代码(简单以单个SMILES举例,建议至少对30000分子进行采样):

import moses
a = 'CN(C)CCC=C1C2=CC=CC=C2CCC2=CC=CC=C12'
x = [a]
metrics = moses.get_all_metrics(x)
print(metrics)
{'valid': 1.0, 'unique@1000': 1.0, 'unique@10000': 1.0, 'FCD/Test': nan, 'SNN/Test': 0.31111112236976624, 'Frag/Test': 0.013181090368167392, 'Scaf/Test': 0.0, 'FCD/TestSF': nan, 'SNN/TestSF': 0.2857142984867096, 'Frag/TestSF': 0.012627479673146369, 'Scaf/TestSF': 0.0, 'IntDiv': 0.0, 'IntDiv2': 0.0, 'Filters': 0.0, 'logP': 1.7326946315185685, 'SA': 0.39536464732487514, 'QED': 0.07334471126827363, 'weight': 34.70996032350039, 'Novelty': 1.0}

4、分子所具有的自由基电子数、价电子数

from rdkit.Chem import Descriptors
re = Descriptors.NumRadicalElectrons(smiles)#分子所具有的自由基电子数
ve = Descriptors.NumValenceElectrons(smiles)#分子的价电子数

5、拓扑极性表面积(TPSA)

化合物的极性表面积(PSA)是分子表面极性部分的面积值的总和。极性部分通常在诸如氧或氮的杂元素周围,因此可以认为这些部分结构是加在一起的。PSA是描述分子的极性和脂溶性的描述符,例如辛醇/水分配比(logP)。在PSA和膜渗透性的实验数据之间发现了很好的相关性。

考虑到单一构象,计算出世界药品索引中所列化合物的PSA。另外,选择了43个包含氧,氮,磷和硫的部分结构,并且通过最小二乘法对每个部分结构的重量进行参数化以用于计算的PSA。

这样,将某个索引视为来自子结构的贡献之和的方法是一种在化学信息学中经常出现的概念。通过将每个原子分解成亚结构,也可以很容易地看到每个原子的贡献。

TPSA中,仅从分子中原子的键合模式(拓扑)估算PSA,而无需考虑分子的三维结构,这是拓扑极性表面积的名称的起源。

from rdkit.Chem import rdMolDescriptors
TPSA=rdMolDescriptors.CalcTPSA(Chem.MolFromSmiles(mol))

更多详细的信息可以关注“DrugAI”公众号,帮我了解了很多专有名词。

分子生成中常见分子描述符介绍及代码实现相关推荐

  1. 【GNN报告】腾讯AI lab 徐挺洋:图生成模型及其在分子生成中的应用

    目录 1.简介 2.An overview of Graph Generative Models and Their Applications on Molecular Generation 背景 图 ...

  2. Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介

    原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...

  3. Linux中的文件描述符与打开文件之间的关系

    1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是 ...

  4. linux c中的文件描述符与打开文件之间的关系

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通 ...

  5. Linux中对文件描述符的操作(FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    在Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描述符.读写文件也需要使用文件描述符来指定 ...

  6. linux内核中的文件描述符(四)--fd的分配--get_unused_fd

    linux内核中的文件描述符(四)--fd的分配--get_unused_fd Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123( ...

  7. linux内核中的文件描述符(一)--基础知识简介

    linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.cs ...

  8. android 布局 站位符,基于android布局中的常用占位符介绍

    大家在做布局文件是肯定会遇到过下面的这种情况 填充出现问题,所以需要用到占位符规范填充 汉字常用占位符: android:layout_width="wrap_content" a ...

  9. android 多个占位符,基于android布局中的常用占位符介绍

    大家在做布局文件是肯定会遇到过下面的这种情况 填充出现问题,所以需要用到占位符规范填充 汉字常用占位符: android:layout_width="wrap_content" a ...

最新文章

  1. Spring 使用 JSR303自定义校验注解+分组校验
  2. 派生类的赋值运算符重载【C++继承】
  3. .java生成dex文件
  4. 打开闪光灯_用手机拍照这么久,你居然还不知道闪光灯怎么用
  5. 由于CRS磁盘dismount造成的CRS进程无法启动问题
  6. C++字符串操作函数
  7. rails中weill_paginate的paginate方法中不能使用额外参数的解决办法
  8. android 垂直自动滚动条,Android实现Activity水平和垂直滚动条的方法
  9. django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV
  10. 【前端】VUE UI的安装
  11. 高一数学计算机教材,高一数学的教学计划
  12. MATLAB图像检索系统GUI设计
  13. Ubuntu下编译pcsx2要用到的包
  14. Python中文社区征稿,最高1000元/篇!
  15. 通信电子电路(3)---高频功率放大器
  16. HTML—超文本标记语言
  17. hp6960无法连接计算机,支持多种打印方式 惠普OfficeJet Pro 6960评测
  18. 【数字IC/FPGA】仲裁器进阶--Round Robin Arbiter
  19. C:\Users\用户名\AppData里面的文件可以删除吗
  20. 【微电网优化】基于粒子群优化IEEE经典微电网结构附matlab代码

热门文章

  1. 7-8 哈利·波特的考试 (25 分)
  2. JS 中常用判断为空的方法
  3. 程序员的算法趣题Q56: 鬼脚图中的横线(思路2的Python题解)
  4. 苹果WWDC21有什么可期待
  5. BurpSuite的https代理原理
  6. 每日总结-2019年12月10日(如切如磋,如琢如磨)
  7. multi-view human pose estimation相关项目配置经验
  8. 高考终于落下帷幕,而你的学习才刚刚开始
  9. 3D.处女座的训练(C++)
  10. 两个显示器分屏显示,如何设定哪个是1,哪个是2