DeepChem教程2:处理数据集
数据是机器学习的中心。本教程介绍DeepChem用于贮存和管理数据的Dataset类。它为有效处理大量的数据提供了简单而有力的工具。它也是为了便于与其它流行的Python框架如NumPy, Pandas, TensorFlow和PyTorch交互而设计的。
设置
首先要安装和运行DeepChem。我们推荐用Google Colab来运行本序列教程。你可以执行下以命令以将DeepChem安装到你的colab记事本中。注意这将花费5分钟来运行你的实例。
!curl -Lo conda_installer.py
https://raw.githubusercontent.com/deepchem/deepchem/master/scripts/colab_install.py
import conda_installer
conda_installer.install()
!/root/miniconda/bin/conda info -e
!pip install --pre deepchem
现在你可以导入deepchem包进行偿试了。
In [1]:
import deepchem as dc
dc.__version__
Out[1]:
'2.4.0-rc1.dev'
数据集剖析
上一个教程我们加载了分子的溶解度数据集Delaney。现在我们重新加载它。
In [2]:
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer='GraphConv')
train_dataset, valid_dataset, test_dataset = datasets
我们有三个数据集对象:训练集、验证集、测试集。它们都包含哪些信息呢?我们可以从打印输出它们的字符串表示来获得一个想法。
In [3]:
print(test_dataset)
<DiskDataset X.shape: (113,), y.shape: (113, 1), w.shape: (113, 1), ids: ['C1c2ccccc2c3ccc4ccccc4c13' 'COc1ccccc1Cl'
'COP(=S)(OC)Oc1cc(Cl)c(Br)cc1Cl' ... 'CCSCCSP(=S)(OC)OC' 'CCC(C)C'
'COP(=O)(OC)OC(=CCl)c1cc(Cl)c(Cl)cc1Cl'], task_names: ['measured log solubility in mols per litre']>
这里有很多信息,所以我们从头开始。它以"DiskDataset"标签开始。Dataset是一个抽象的类。它有一些子类与不同的数据存贮方法对应。DiskDataset是存贮于磁盘的数据集。数据以高效访问的方式贮存,即便数据量远远大于你的计算机内存容量。
ImageDataset是一个更加特殊的类,它存贮一些或所有图像文件的数据于磁盘中。对于处理以图像作为输入的模型来说,它是有用的。
现在我们来考虑一下数据集的内容。每个数据集贮存一个样本的列表。简单的来说,一个样本就是一个数据点。这种情况下,每一个样本就是一个分子。其它的数据集中,一个样本可能对应于实验的含量,细胞种类,一张图像,或者其它东西。对于每个数据集,贮存如下信息:特征,称作X。这是用于表示样本的传递给模型的输入。
标签,称作y。这是模型的期望输出。在训练过程中,它试图使模型对每个样本的输出尽可能的接近y。
权重,称作w。这可以指示一些数据值比一些数据值更重要。下一个教程我们将看到如何使用它。
一个ID,它是样本的唯一标识。它可以是任意值,只要是唯一的就行。有时它只是一个整数索引,但是本数据集中ID是描述分子的SMILES字串。
注意, X, y, 和w的第一维大小是113.即数据集有113个样本。
最后一个信息是 task_names。有些数据集的样本有多个信息。如,如果一个样本表示分子,数据集可能记录这个分子的多个不同实验结果。本数据集只有一个简单的任务:“测定对数溶解度,单位为mols每升。”
还要注意y和w的形状 (113, 1). 数组的第二维与任务数相匹配。
从数据集中访问数据
有多种方法访问数据集中的数据。最简单的就是直接访问X, y, w,和ids属性。这些都会返回相应的NumPy数组信息。
In [4]:
test_dataset.y
Out[4]:
array([[-1.7065408738415053],
[0.2911162036252904],
[-1.4272475857596547],
[-0.9254664241210759],
[-1.9526976701170347],
[1.3514839414275706],
[-0.8591934405084332],
[-0.6509069205829855],
[-0.32900957160729316],
[0.6082797680572224],
[1.8295961803473488],
[1.6213096604219008],
[1.3751528641463715],
[0.45632528420252055],
[1.0532555151706793],
[-1.1053502367839627],
[-0.2011973889257683],
[0.3479216181504126],
[-0.9870056231899582],
[-0.8161160011602158],
[0.8402352107014712],
[0.22815686919328],
[0.06247441016167367],
[1.040947675356903],
[-0.5197810887208284],
[0.8023649343513898],
[-0.41895147793873655],
[-2.5964923680684198],
[1.7443880585596654],
[0.45206487811313645],
[0.233837410645792],
[-1.7917489956291888],
[0.7739622270888287],
[1.0011838851893173],
[-0.05445006806920272],
[1.1043803882432892],
[0.7597608734575482],
[-0.7001382798380905],
[0.8213000725264304],
[-1.3136367567094103],
[0.4567986626568967],
[-0.5732728540653187],
[0.4094608172192949],
[-0.3242757870635329],
[-0.049716283525442634],
[-0.39054877067617544],
[-0.08095926151425996],
[-0.2627365879946506],
[-0.5467636606202616],
[1.997172153196459],
[-0.03551492989416198],
[1.4508934168465344],
[-0.8639272250521937],
[0.23904457364392848],
[0.5278054308132993],
[-0.48475108309700315],
[0.2248432200126478],
[0.3431878336066523],
[1.5029650468278963],
[-0.4946920306388995],
[0.3479216181504126],
[0.7928973652638694],
[0.5609419226196206],
[-0.13965818985688602],
[-0.13965818985688602],
[0.15857023640000523],
[1.6071083067906202],
[1.9006029485037514],
[-0.7171799041956278],
[-0.8165893796145915],
[-0.13019062076936566],
[-0.24380144981960986],
[-0.14912575894440638],
[0.9538460397517154],
[-0.07811899078800374],
[-0.18226225075072758],
[0.2532459272752089],
[0.6887541053011454],
[0.044012650441008896],
[-0.5514974451640217],
[-0.2580028034508905],
[-0.021313576262881533],
[-2.4128215277705247],
[0.07336211461232214],
[0.9017744097703536],
[1.9384732248538328],
[0.8402352107014712],
[-0.10652169805056463],
[1.07692443788948],
[-0.403803367398704],
[1.2662758196398873],
[-0.2532690189071302],
[0.29064282517091444],
[0.9443784706641951],
[-0.41563782875810434],
[-0.7370617992794205],
[-1.0012069768212388],
[0.46626623174441706],
[0.3758509469585975],
[-0.46628932337633816],
[1.2662758196398873],
[-1.4968342185529295],
[-0.17800184466134344],
[0.8828392715953128],
[-0.6083028596891439],
[-2.170451759130003],
[0.32898647997537184],
[0.3005837727128107],
[0.6461500444073038],
[1.5058053175541524],
[-0.007585601085977053],
[-0.049716283525442634],
[-0.6849901692980588]], dtype=object)
这是访问数据非常容易的方法,但是你要小心的使用它。它要求每个样本的数据都一次性加载到内存中。这对于小型数据集来说是可行的,但是对于大型的数据集它需要容量会超出你所拥用的内存。
一个更好的方法是迭代每个数据集。这样它就一次只加载一个小量的数据,然后在加载下一个数据点时释放内存。你可以用 itersamples()方法来一次一个的迭代所有的样本。
In [5]:
for X, y, w, id in test_dataset.itersamples():
print(y, id)
[-1.70654087] C1c2ccccc2c3ccc4ccccc4c13
[0.2911162] COc1ccccc1Cl
[-1.42724759] COP(=S)(OC)Oc1cc(Cl)c(Br)cc1Cl
[-0.92546642] ClC(Cl)CC(=O)NC2=C(Cl)C(=O)c1ccccc1C2=O
[-1.95269767] ClC(Cl)C(c1ccc(Cl)cc1)c2ccc(Cl)cc2
[1.35148394] COC(=O)C=C
[-0.85919344] CN(C)C(=O)Nc2ccc(Oc1ccc(Cl)cc1)cc2
[-0.65090692] N(=Nc1ccccc1)c2ccccc2
[-0.32900957] CC(C)c1ccc(C)cc1
[0.60827977] Oc1c(Cl)cccc1Cl
[1.82959618] OCC2OC(OC1(CO)OC(CO)C(O)C1O)C(O)C(O)C2O
[1.62130966] OC1C(O)C(O)C(O)C(O)C1O
[1.37515286] Cn2c(=O)n(C)c1ncn(CC(O)CO)c1c2=O
[0.45632528] OCC(NC(=O)C(Cl)Cl)C(O)c1ccc(cc1)N(=O)=O
[1.05325552] CCC(O)(CC)CC
[-1.10535024] CC45CCC2C(CCC3CC1SC1CC23C)C4CCC5O
[-0.20119739] Brc1ccccc1Br
[0.34792162] Oc1c(Cl)cc(Cl)cc1Cl
[-0.98700562] CCCN(CCC)c1c(cc(cc1N(=O)=O)S(N)(=O)=O)N(=O)=O
[-0.816116] C2c1ccccc1N(CCF)C(=O)c3ccccc23
[0.84023521] CC(C)C(=O)C(C)C
[0.22815687] O=C1NC(=O)NC(=O)C1(C(C)C)CC=C(C)C
[0.06247441] c1c(O)C2C(=O)C3cc(O)ccC3OC2cc1(OC)
[1.04094768] Cn1cnc2n(C)c(=O)n(C)c(=O)c12
[-0.51978109] CC(=O)SC4CC1=CC(=O)CCC1(C)C5CCC2(C)C(CCC23CCC(=O)O3)C45
[0.80236493] Cc1ccc(O)cc1C
[-0.41895148] O(c1ccccc1)c2ccccc2
[-2.59649237] Clc1cc(Cl)c(cc1Cl)c2cc(Cl)c(Cl)cc2Cl
[1.74438806] NC(=O)c1cccnc1
[0.45206488] Sc1ccccc1
[0.23383741] CNC(=O)Oc1cc(C)cc(C)c1
[-1.791749] ClC1CC2C(C1Cl)C3(Cl)C(=C(Cl)C2(Cl)C3(Cl)Cl)Cl
[0.77396223] CSSC
[1.00118389] NC(=O)c1ccccc1
[-0.05445007] Clc1ccccc1Br
[1.10438039] COC(=O)c1ccccc1OC2OC(COC3OCC(O)C(O)C3O)C(O)C(O)C2O
[0.75976087] CCCCC(O)CC
[-0.70013828] CCN2c1nc(C)cc(C)c1NC(=O)c3cccnc23
[0.82130007] Oc1cc(Cl)cc(Cl)c1
[-1.31363676] Cc1cccc2c1ccc3ccccc32
[0.45679866] CCCCC(CC)CO
[-0.57327285] CC(C)N(C(C)C)C(=O)SCC(=CCl)Cl
[0.40946082] Cc1ccccc1
[-0.32427579] Clc1cccc(n1)C(Cl)(Cl)Cl
[-0.04971628] C1CCC=CCC1
[-0.39054877] CN(C)C(=S)SSC(=S)N(C)C
[-0.08095926] COC1=CC(=O)CC(C)C13Oc2c(Cl)c(OC)cc(OC)c2C3=O
[-0.26273659] CCCCCCCCCCO
[-0.54676366] CCC(C)(C)CC
[1.99717215] CNC(=O)C(C)SCCSP(=O)(OC)(OC)
[-0.03551493] Oc1cc(Cl)c(Cl)c(Cl)c1Cl
[1.45089342] CCCC=O
[-0.86392723] CC4CC3C2CCC1=CC(=O)C=CC1(C)C2(F)C(O)CC3(C)C4(O)C(=O)COC(C)=O
[0.23904457] CCCC
[0.52780543] COc1ccccc1O
[-0.48475108] CC1CC2C3CCC(O)(C(=O)C)C3(C)CC(O)C2(F)C4(C)C=CC(=O)C=C14
[0.22484322] ClC(Cl)C(Cl)(Cl)Cl
[0.34318783] CCOC(=O)c1ccccc1C(=O)OCC
[1.50296505] CC(C)CO
[-0.49469203] CC(C)Cc1ccccc1
[0.34792162] ICI
[0.79289737] CCCC(O)CCC
[0.56094192] CCCCCOC(=O)C
[-0.13965819] Oc1c(Cl)c(Cl)cc(Cl)c1Cl
[-0.13965819] CCCc1ccccc1
[0.15857024] FC(F)(Cl)C(F)(F)Cl
[1.60710831] CC=CC=O
[1.90060295] CN(C)C(=O)N(C)C
[-0.7171799] Cc1cc(C)c(C)cc1C
[-0.81658938] CC(=O)OC3(CCC4C2CCC1=CC(=O)CCC1C2CCC34C)C#C
[-0.13019062] CCOP(=S)(OCC)N2C(=O)c1ccccc1C2=O
[-0.24380145] c1ccccc1NC(=O)c2c(O)cccc2
[-0.14912576] CCN(CC)C(=S)SCC(Cl)=C
[0.95384604] ClCC
[-0.07811899] CC(=O)Nc1cc(NS(=O)(=O)C(F)(F)F)c(C)cc1C
[-0.18226225] O=C(C=CC=Cc2ccc1OCOc1c2)N3CCCCC3
[0.25324593] CC/C=C\C
[0.68875411] CNC(=O)ON=C(CSC)C(C)(C)C
[0.04401265] O=C2NC(=O)C1(CCCCCCC1)C(=O)N2
[-0.55149745] c1(C(C)(C)C)cc(C(C)(C)C)cc(OC(=O)NC)c1
[-0.2580028] Oc2cc(O)c1C(=O)CC(Oc1c2)c3ccc(O)c(O)c3
[-0.02131358] O=C(c1ccccc1)c2ccccc2
[-2.41282153] CCCCCCCCCCCCCCCCCCCC
[0.07336211] N(Nc1ccccc1)c2ccccc2
[0.90177441] CCC(CC)CO
[1.93847322] Oc1ccncc1
[0.84023521] Cl\C=C/Cl
[-0.1065217] CC1CCCC1
[1.07692444] CC(C)CC(C)O
[-0.40380337] O2c1ccc(N)cc1N(C)C(=O)c3cc(C)ccc23
[1.26627582] CC(C)(C)CO
[-0.25326902] CC(C)(C)C(=O)C(Oc1ccc(Cl)cc1)n2cncn2
[0.29064283] Cc1cc(no1)C(=O)NNCc2ccccc2
[0.94437847] CC=C
[-0.41563783] Oc1ccc(Cl)cc1Cc2cc(Cl)ccc2O
[-0.7370618] CCOC(=O)Nc2cccc(OC(=O)Nc1ccccc1)c2
[-1.00120698] O=C1c2ccccc2C(=O)c3ccccc13
[0.46626623] CCCCCCC(C)O
[0.37585095] CC1=C(C(=O)Nc2ccccc2)S(=O)(=O)CCO1
[-0.46628932] CCCCc1ccccc1
[1.26627582] O=C1NC(=O)C(=O)N1
[-1.49683422] COP(=S)(OC)Oc1ccc(Sc2ccc(OP(=S)(OC)OC)cc2)cc1
[-0.17800184] NS(=O)(=O)c1cc(ccc1Cl)C2(O)NC(=O)c3ccccc23
[0.88283927] CC(C)COC(=O)C
[-0.60830286] CC(C)C(C)(C)C
[-2.17045176] Clc1ccc(c(Cl)c1Cl)c2c(Cl)cc(Cl)c(Cl)c2Cl
[0.32898648] N#Cc1ccccc1C#N
[0.30058377] Cc1cccc(c1)N(=O)=O
[0.64615004] FC(F)(F)C(Cl)Br
[1.50580532] CNC(=O)ON=C(SC)C(=O)N(C)C
[-0.0075856] CCSCCSP(=S)(OC)OC
[-0.04971628] CCC(C)C
[-0.68499017] COP(=O)(OC)OC(=CCl)c1cc(Cl)c(Cl)cc1Cl
大部分的深度学习模型可以一次批量的处多个样本。你可以用iterbatches()方法迭代样本的所有批次。
In [6]:
for X, y, w, ids in test_dataset.iterbatches(batch_size=50):
print(y.shape)
(50, 1)
(50, 1)
(13, 1)
当训练模型时iterbatches()还有其它的属性可以使用。例如, iterbatches(batch_size=100, epochs=10, deterministic=False)将在10次迭代完所有的样本,每次有不同的随机顺序。
Datasets也可以使用为TensorFlow和Pytorch提供的标准接口访问数据。为了获得tensorflow.data.Dataset,调用make_tf_dataset()函数。为获得torch.utils.data.IterableDataset, 调用make_pytorch_dataset()。详见 API文档。
最后一个访问数据的方法是to_dataframe()。它拷贝数据到Pandas DataFrame。它要求一次性贮存所有的数据到内存中,所以你应当用它来处理小型数据集。
In [7]:
test_dataset.to_dataframe()
Out[7]:
X y w ids
0 <deepchem.feat.mol_graphs.ConvMol object at 0x... -1.706541 1.0 C1c2ccccc2c3ccc4ccccc4c13
1 <deepchem.feat.mol_graphs.ConvMol object at 0x... 0.291116 1.0 COc1ccccc1Cl
2 <deepchem.feat.mol_graphs.ConvMol object at 0x... -1.427248 1.0 COP(=S)(OC)Oc1cc(Cl)c(Br)cc1Cl
3 <deepchem.feat.mol_graphs.ConvMol object at 0x... -0.925466 1.0 ClC(Cl)CC(=O)NC2=C(Cl)C(=O)c1ccccc1C2=O
4 <deepchem.feat.mol_graphs.ConvMol object at 0x... -1.952698 1.0 ClC(Cl)C(c1ccc(Cl)cc1)c2ccc(Cl)cc2
... ... ... ... ...
108 <deepchem.feat.mol_graphs.ConvMol object at 0x... 0.646150 1.0 FC(F)(F)C(Cl)Br
109 <deepchem.feat.mol_graphs.ConvMol object at 0x... 1.505805 1.0 CNC(=O)ON=C(SC)C(=O)N(C)C
110 <deepchem.feat.mol_graphs.ConvMol object at 0x... -0.007586 1.0 CCSCCSP(=S)(OC)OC
111 <deepchem.feat.mol_graphs.ConvMol object at 0x... -0.049716 1.0 CCC(C)C
112 <deepchem.feat.mol_graphs.ConvMol object at 0x... -0.684990 1.0 COP(=O)(OC)OC(=CCl)c1cc(Cl)c(Cl)cc1Cl
113 rows × 4 columns
创建数据集
现在来讨论一下你将如何创建你自已的数据集。 创建NumpyDataset非常简单:只需传递包含数据的数组给构建子。让我们来创建一些随机数组,然后打它们打包到NumpyDataset。
In [8]:
import numpy as np
X = np.random.random((10, 5))
y = np.random.random((10, 2))
dataset = dc.data.NumpyDataset(X=X, y=y)
print(dataset)
<NumpyDataset X.shape: (10, 5), y.shape: (10, 2), w.shape: (10, 1), ids: [0 1 2 3 4 5 6 7 8 9], task_names: [0 1]>
注意我们没有提明权重或IDs。它们是可选的,同样,y也是可选的。只有X是必需的。
由于我们没有管它们,所以就自动的为我们构建了w和ids,所有的权重设为1,设置IDs为整数索引。
In [9]:
dataset.to_dataframe()
Out[9]:
X1 X2 X3 X4 X5 y1 y2 w ids
0 0.547330 0.919941 0.289138 0.431806 0.776672 0.532579 0.443258 1.0 0
1 0.980867 0.642487 0.460640 0.500153 0.014848 0.678259 0.274029 1.0 1
2 0.953254 0.704446 0.857458 0.378372 0.705789 0.704786 0.901080 1.0 2
3 0.904970 0.729710 0.304247 0.861546 0.917029 0.121747 0.758845 1.0 3
4 0.464144 0.059168 0.600405 0.880529 0.688043 0.595495 0.719861 1.0 4
5 0.820482 0.139002 0.627421 0.129399 0.920024 0.634030 0.464525 1.0 5
6 0.113727 0.551801 0.536189 0.066091 0.311320 0.699331 0.171532 1.0 6
7 0.516131 0.918903 0.429036 0.844973 0.639367 0.464089 0.337989 1.0 7
8 0.809393 0.201450 0.821420 0.841390 0.100026 0.230462 0.376151 1.0 8
9 0.076750 0.389277 0.350371 0.291806 0.127522 0.544606 0.306578 1.0 9
如何创建DiskDataset呢?如果你有数据在NumPy数组中,你可以调用DiskDataset.from_numpy()将它保存在磁盘中。由于仅是教程,我们将它保存在临时目录中。
In [10]:
import tempfile
with tempfile.TemporaryDirectory() as data_dir:
disk_dataset = dc.data.DiskDataset.from_numpy(X=X, y=y, data_dir=data_dir)
print(disk_dataset)
<DiskDataset X.shape: (10, 5), y.shape: (10, 2), w.shape: (10, 1), ids: [0 1 2 3 4 5 6 7 8 9], task_names: [0 1]>
对于超过内存的大数据集如何处理?如果你的磁盘中有包含上亿个分子数据的巨型数据呢?从它们中创建DiskDataset一点麻烦。幸运的是DeepChem的DataLoader框架可以为你自动化绝大部分的工作。对于大的对象,我们将在下一个教程介绍。
你可以到http://www.data-vision.net下载本文。技术联系电话13712566524。