DeepChem教程23:合成的可行性

运行大规模仿真时,合成可行性是个问题。通常仿真的分子都很难合成因此不值得关注,尽管它们在生物学上有很好的化学性质。本教程学习如何训练ScScore模型。

该模型的思想是训练成对的分子,其中一个分子比另一个分子更复杂。然后用神经网络来打分,以试图排序分子对。最后的结果的一个可以给出分子相对复杂度的模型。

论文用reaxys的每个反应训练,声明产品比反应更复杂。由于训练集很贵,我们用人工的分子来训练,如果SMILES字串越长我们就认为分子越复杂。实际上你可以任意使用复杂性的量度。

本教程,我们使用Tox21数据集来训练简单的合成可行怀模型。

生成数据集

我们来加载一些分子来进行工作。我们加载Tox21,指明splitter=None,因此只返回一个数据集。

In [1]:

import deepchem as dc

tasks, datasets, transformers = dc.molnet.load_tox21(featurizer='Raw', splitter=None)

molecules = datasets[0].X

因为ScScore是用相对复杂来训练,我们希望x张量有3(sample_id, molecule_id, features)molecule_id 维大小为2,因为样本是成对分子。标签为1,如果第一个分子比第二个分子复杂。下面的create_dataset函数从给定的列表中取随机的SMILES字段,并按复杂度排序。

现实中你可以用购买成本,反应步数作为你的复杂度分值。

In [2]:

from rdkit import Chem

import random

from deepchem.feat import CircularFingerprint

import numpy as np

def create_dataset(fingerprints, smiles_lens, ds_size=100000):

    """

    m1: list of np.Array

        fingerprints for molecules

    m2: list of int

        length of a molecules SMILES string

   

    returns:

        dc.data.Dataset for input into ScScore Model

       

    Dataset.X

        shape is (sample_id, molecule_id, features)

    Dataset.y

        shape is (sample_id,)

        values is 1 if the 0th index molecule is more complex

                  0 if the 1st index molecule is more complex

    """

    X, y = [], []

    all_data = list(zip(fingerprints, smiles_lens))

    while len(y) < ds_size:

        i1 = random.randrange(0, len(smiles_lens))

        i2 = random.randrange(0, len(smiles_lens))

        m1 = all_data[i1]

        m2 = all_data[i2]

        if m1[1] == m2[1]:

            continue

        if m1[1] > m2[1]:

            y.append(1.0)

        else:

            y.append(0.0)

        X.append([m1[0], m2[0]])

return dc.data.NumpyDataset(np.array(X), np.expand_dims(np.array(y), axis=1))

有了复杂度排序我们现在可以构建数据集。我们随机分割分子列表到训练集和测试集。

In [3]:

molecule_ds = dc.data.NumpyDataset(np.array(molecules))

splitter = dc.splits.RandomSplitter()

train_mols, test_mols = splitter.train_test_split(molecule_ds)

我们用带手性的ECFP指纹特征化所有的分子(与源论文匹配),然后有上面的函数构建成对数据集。

In [4]:

n_features = 1024

featurizer = dc.feat.CircularFingerprint(size=n_features, radius=2, chiral=True)

train_features = featurizer.featurize(train_mols.X)

train_smiles_len = [len(Chem.MolToSmiles(x)) for x in train_mols.X]

train_dataset = create_dataset(train_features, train_smiles_len)

现在已经创建了数据集,我们用数据集来训练ScScoreModel 

In [5]:

model = dc.models.ScScoreModel(n_features=n_features)

model.fit(train_dataset, nb_epoch=20)

Out[5]:

0.03494557857513428

模型的性能

我们评估一下模型工作的如何。SaScores会跟踪没有看到的分子的SMILES字串的长度。

In [6]:

import matplotlib.pyplot as plt

%matplotlib inline

In [7]:

mol_scores = model.predict_mols(test_mols.X)

smiles_lengths = [len(Chem.MolToSmiles(x)) for x in test_mols.X]

我们matplotlib来作图,画出SMILES长度与SaScore

In [8]:

plt.figure(figsize=(20,16))

plt.scatter(smiles_lengths, mol_scores)

plt.xlim(0,80)

plt.xlabel("SMILES length")

plt.ylabel("ScScore")

plt.show()

如我们所见,模型通常跟踪SMILES长度。在8-30个字符之间有很好的丰度,而对于大的和小SMILES字串的都特别不好。

现在你可以用更有意义的量度来训练模型而不是SMILES长度!

下载全文请到www.data-vision.net,技术联系电话13712566524

猜你喜欢

转载自blog.csdn.net/lishaoan77/article/details/114376687
今日推荐