RDkit四:数据处理过程中smiles编码的清洗统一化

之前写过一篇博客介绍smiles编码,smart编码及摩根指纹(ECFP):

(1条消息) RDkit:介绍smiles编码,smart编码及摩根指纹(ECFP)_随便叫点什么……的博客-CSDN博客

smiles编码具有唯一性:每个SMILES编码对应唯一一个化学结构,刚刚接触smiles编码的时候一定会有这样的疑问,为什么同一个化学分子smiles编码有多种表示形式:

c1cccc(c1OC(=O)C)C(O)=O
C(=O)(c1ccccc1OC(C)=O)O
c1c(c(OC(=O)C)ccc1)C(=O)O
c1(OC(C)=O)c(cccc1)C(O)=O
c1cc(c(C(O)=O)cc1)OC(C)=O
c1c(C(=O)O)c(OC(C)=O)ccc1
c1(c(cccc1)C(O)=O)OC(C)=O
c1cccc(C(=O)O)c1OC(=O)C
c1cccc(c1C(=O)O)OC(C)=O
c1cc(c(cc1)C(=O)O)OC(C)=O

当把上面的十个smiles编码作图时,发现得到的是一样的,都是阿司匹林

import rdkit
from rdkit import Chem
from rdkit.Chem import Draw

smiles = ['c1cccc(c1OC(=O)C)C(O)=O','C(=O)(c1ccccc1OC(C)=O)O','c1c(c(OC(=O)C)ccc1)C(=O)O','c1(OC(C)=O)c(cccc1)C(O)=O',
            'c1cc(c(C(O)=O)cc1)OC(C)=O','c1c(C(=O)O)c(OC(C)=O)ccc1','c1(c(cccc1)C(O)=O)OC(C)=O','c1cccc(C(=O)O)c1OC(=O)C',
            'c1cccc(c1C(=O)O)OC(C)=O','c1cc(c(cc1)C(=O)O)OC(C)=O']
mols = [Chem.MolFromSmiles(smile) for smile in smiles]
Draw.MolsToGridImage(mols, molsPerRow=10)

# 结果分子图显示均为阿司匹林

同一种格式的smiles编码的形式可以用不同的方式表示,起始原子序号不同,多种表达形式,可根据此特点来对数据进行数据增强。

https://zhuanlan.zhihu.com/p/92748733

但在数据清洗筛选的过程,就会造成错误和麻烦,假如你从不同的数据库爬取了多条信息,可能出现同一个分子用多个smiles编码表示的情形,分子生成时也会出现类似状况现象,为避免这种状况,需要我们对分子的smiles编码进行统一化,标准化。

下面的脚本,能做到这一点:

# Name = Cleaner.py
import argparse
from tqdm import tqdm
from rdkit import Chem, RDLogger
from rdkit.Chem import MolStandardize

class MolClean(object):
    def __init__(self):
        self.normizer = MolStandardize.normalize.Normalizer()
        self.lfc = MolStandardize.fragment.LargestFragmentChooser()
        self.uc = MolStandardize.charge.Uncharger()

    def clean(self, smi):
        mol = Chem.MolFromSmiles(smi)
        if mol:
            mol = self.normizer.normalize(mol)
            mol = self.lfc.choose(mol)
            mol = self.uc.uncharge(mol)
            # 此处需注意这里的isomericSmiles及canonical这两个参数,后面会说明
            smi = Chem.MolToSmiles(mol,  isomericSmiles=False, canonical=True)
            return smi
        else:
            return None

def main(input_file, output_file, **kwargs):
    mc = MolClean()

    with open(input_file, 'r') as f:
        smiles = [r.rstrip() for r in f]

    print(f'input SMILES num: {len(smiles)}')
    print('Clean Up Started ...')

    mc_smiles = [mc.clean(smi) for smi in tqdm(smiles)]

    print('Cleanup Completed')
    print(f'output SMILES num: {len(mc_smiles)}')

    with open(output_file, 'w') as f:
        for smi in mc_smiles:
            f.write(smi + '\n')

    return

if __name__ == '__main__':
    print('cleaner')
    parser = argparse.ArgumentParser()
    parser.add_argument('input', help='input file')
    parser.add_argument('output', help='output file')

    args = parser.parse_args()
    main(args.input, args.output)

在shell中运行:

# 需要统一化标准化的文件名:test.csv,处理后的输出文件名:result.csv
python Cleaner.py test result

下面介绍一下isomericSmiles及canonical这两个参数,在进行smile和mol格式之间转换时(Chem.MolToSmiles),可以设置这两个参数:isomericSmiles代表有立体异构的smiles编码,canonical表示没有标准的没有手性异构的smiles编码。

以布洛芬分子为例:

import rdkit
from rdkit import Chem
from rdkit.Chem import Draw

smi = ['OC(C)CC1=CC=CC=C1','C[C@H](O)CC1=CC=CC=C1']
mol_1 = Chem.MolFromSmiles(smi[0])
mol_1
RDkit四:数据处理过程中smiles编码的清洗统一化_第1张图片
mol_2 = Chem.MolFromSmiles(smi[1])
mol_2
RDkit四:数据处理过程中smiles编码的清洗统一化_第2张图片
smi_1 = Chem.MolToSmiles(mol_1,isomericSmiles=False, canonical=True)
print(smi_1)
# CC(O)Cc1ccccc1
smi_2 = Chem.MolToSmiles(mol_2,isomericSmiles=False, canonical=True)
print(smi_2)
# CC(O)Cc1ccccc1

需要文中test.csv文件请私信

你可能感兴趣的:(RDkit,数据挖掘,人工智能)