运行大规模仿真时,合成可行性是个问题。通常仿真的分子都很难合成因此不值得关注,尽管它们在生物学上有很好的化学性质。本教程学习如何训练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字段,并按复杂度排序。
![](/qrcode.jpg)
现实中你可以用购买成本,反应步数作为你的复杂度分值。
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