化学信息学RDKit | 操作与实践理论与计算化学

RDKit|分子指纹提取、相似性比较及应用

2020-05-15  本文已影响0人  最会设计的科研狗

一、分子指纹提取

1.Topological Fingerprints

也叫RDKit topological fingerprint。该算法受Daylight fingerprint启发而产生,它会计算所有介于minPath和maxPath之间的分子路径(子图,subgraphs),对每个子图进行哈希运算,产生一个原始的bit ID。对bit ID取模(除数是fpSize),并在相应的位上进行设置。
对子图做哈希运算,其实就是对原子和键做哈希,它考虑了原子类型、芳香性、键的类型三种特征

对每个子图生成指纹的大致流程:

使用rdkit来生成拓扑分子指纹

>>> ms = [Chem.MolFromSmiles('CCOC'), Chem.MolFromSmiles('CCO'), Chem.MolFromSmiles('COC')]
>>> fps = [Chem.RDKFingerprint(x) for x in ms]
>>> fps
[<rdkit.DataStructs.cDataStructs.ExplicitBitVect at 0x7538300>,
 <rdkit.DataStructs.cDataStructs.ExplicitBitVect at 0x75383f0>,
 <rdkit.DataStructs.cDataStructs.ExplicitBitVect at 0x7538670>]

先简单地进行一下相似性比较

>>> DataStructs.FingerprintSimilarity(fps[0], fps[1])
0.6
>>> mol = Chem.MolFromSmiles('c1ccccc1CC1CC1')
>>> rdkinfo = {}
>>> rdkfp = Chem.RDKFingerprint(mol, bitInfo=rdkinfo)
>>> Draw.DrawRDKitBit(mol, list(rdkinfo.keys())[0], rdkinfo)
1

2.MACCS

是一种基于SMARTS的,长度为167的分子指纹,每一位所代表的含义可以参考openbabel的介绍

>>> from rdkit.Chem import MACCSkeys
>>> fps = [MACCSkeys.GenMACCSKeys(x) for x in ms]
>>> DataStructs.FingerprintSimilarity(fps[0],fps[1])
0.5
>>> fps[0].GetNumBits()
167

3.Atom Pairs and Topological Torsions

这两种指纹算法的概念在30多年前提出,比较相似,指纹会包括原子序号、π电子数和相邻原子数三个维度的信息。此外还可以通过参数,加入手性的信息。两种指纹都可以用sparse form和explicit form形式来表示,并且可以查看指纹所代表的化学信息。

>>> from rdkit.Chem.AtomPairs import Pairs
>>> fps = [Pairs.GetAtomPairFingerprint(x) for x in ms]
>>> fps[2].GetNonzeroElements()
{541730: 1, 1606689: 2}
>>> Pairs.ExplainPairScore(1606689)
(('C', 1, 0), 1, ('O', 2, 0))

该结果表示这样一种子结构:有1个相邻原子和0个π电子的碳原子,通过一个键,与有2个相邻原子和0个π电子的氧原子相连。

>>> pairFps = [Pairs.GetAtomPairFingerprintAsBitVect(x) for x in ms]
>>> pairFps[0].GetNumBits()
8388608
>>> DataStructs.DiceSimilarity(pairFps[0],pairFps[1])
0.2222222222222222
>>> from rdkit.Chem.AtomPairs import Torsions
>>> ttfp = Torsions.GetTopologicalTorsionFingerprintAsIntVect(ms[0])
>>> ttfp.GetNonzeroElements()
{4320149536: 1}
>>> Torsions.ExplainPathScore(4320149536)
(('C', 1, 0), ('C', 2, 0), ('O', 2, 0), ('C', 1, 0))

4.Morgan Fingerprints (Circular Fingerprints)

摩根分子指纹,也成为圆形指纹,是采用摩根算法而产生。使用时,需要提供原子半径。这里只展示最基本的使用方法,更多关于指纹生成、提取与展示的操作可以参考这篇文章

>>> mfp = [AllChem.GetMorganFingerprint(x, 2) for x in ms]
>>> mfp[0].GetLength()
4294967295
>>> mfp[2].GetNonzeroElements()
{864674487: 1, 2154640335: 1, 2246728737: 2, 3975275337: 2}
>>> mfp = [AllChem.GetMorganFingerprintAsBitVect(x, 2, nBits=10) for x in ms]
>>> print(mfp[0].GetNumBits())
10
>>> print(mfp[0].ToBitString())
0010100100
>>> print(DataStructs.DiceSimilarity(mfp[0], mfp[1]))
0.75

二、相似性

1.相似性比较

分子指纹的应用之一就是比较分子间相似性。

>>> ms = [Chem.MolFromSmiles('CCOC'), Chem.MolFromSmiles('CCO')]
>>> fps = [Chem.RDKFingerprint(x) for x in ms]
>>> DataStructs.FingerprintSimilarity(mfp[0], mfp[1])
0.6
>>> metic_list = ['DataStructs.TanimotoSimilarity',
>>>               'DataStructs.DiceSimilarity',
>>>               'DataStructs.CosineSimilarity',
>>>               'DataStructs.SokalSimilarity',
>>>               'DataStructs.RusselSimilarity',
>>>               'DataStructs.KulczynskiSimilarity',
>>>               'DataStructs.McConnaugheySimilarity']
>>> for i in metic_list:
>>>     print(DataStructs.FingerprintSimilarity(fps[0], fps[1], metric=eval(i)))
0.6
0.75
0.7745966692414834
0.42857142857142855
0.0029296875
0.8
0.6
>>> DataStructs.TanimotoSimilarity(fps[0], fps[1])
0.6

2.相似性地图

相似性地图是一种用来可视化分子中原子相似性程度的方法,具体可以参考rdkit中的rdkit.Chem.Draw.SimilarityMaps模块

>>> mol = Chem.MolFromSmiles('COc1cccc2cc(C(=O)NCCCCN3CCN(c4cccc5nccnc54)CC3)oc21')
>>> refmol = Chem.MolFromSmiles('CCCN(CCCCN1CCN(c2ccccc2OC)CC1)Cc1ccc2ccccc2c1')

相似性地图模块支持三种分子指纹的比较和可视化:atom pairs、topological torsions和Morgan fingerprints。

>>> from rdkit.Chem.Draw import SimilarityMaps
>>> fp = SimilarityMaps.GetAPFingerprint(mol, fpType='normal')
>>> fp1 = AllChem.GetAtomPairFingerprint(mol)
>>> print(fp == fp1)
True
>>> fp = SimilarityMaps.GetTTFingerprint(mol, fpType='normal')
>>> fp1 = AllChem.GetTopologicalTorsionFingerprint(mol)
>>> print(fp == fp1)
True
>>> fp = SimilarityMaps.GetMorganFingerprint(mol, fpType='bv')
>>> fp1 = AllChem.GetMorganFingerprintAsBitVect(mol, 2)
>>> print(fp == fp1)
True
>>> fig, maxweight = SimilarityMaps.GetSimilarityMapForFingerprint(refmol, mol, SimilarityMaps.GetMorganFingerprint)
2

3.相似性应用——构建多样化分子库

有时会遇到这种任务,需要从整个分子库中,挑出一个子集,使子集的多样性最高,或者能最大程度地代表原始分子库的化学空间。Rdkit在rdkit.SimDivFilters模块中提供了一系列的方法用来处理这种需求,最有效的是MaxMin算法,有文章报道该方法优于k-means。使用MaxMin算法从N个分子的库中挑选k个分子作为子集的大致流程如下:

>>> from rdkit.SimDivFilters.rdSimDivPickers import >>> >>> MaxMinPicker
>>> ms = [Chem.MolFromSmiles('CCOC'),
>>>       Chem.MolFromSmiles('CCO'),
>>>       Chem.MolFromSmiles('COC'),
>>>       Chem.MolFromSmiles('CCC=C'),
>>>       Chem.MolFromSmiles('CCCO'),
>>>       Chem.MolFromSmiles('CCC=O'),
>>>       Chem.MolFromSmiles('CC(=O)C'),
>>>       Chem.MolFromSmiles('CCNC'),
>>>       Chem.MolFromSmiles('CCCCN'),
>>>       Chem.MolFromSmiles('CCC(N)C'),
>>>       Chem.MolFromSmiles('c1ccccc1'),
>>>       Chem.MolFromSmiles('c1cocc1'),]
>>> fps = [AllChem.GetMorganFingerprint(x, 2) for x in ms]
>>> Draw.MolsToGridImage(ms, molsPerRow=5)
3
>>> def distij(i, j, fps=fps):
>>>     return 1-DataStructs.TanimotoSimilarity(fps[i],fps[j])
>>> picker = MaxMinPicker()
>>> pickIndices = picker.LazyPick(distij, len(ms), 4, seed=1)
>>> picks = [ms[x] for x in pickIndices]
>>> Draw.MolsToGridImage(picks, molsPerRow=4)
4

本文参考自rdkit官方文档
代码及源文件在这里

上一篇 下一篇

猜你喜欢

热点阅读