class: center, middle, inverse, title-slide # Featurización y modelación ### JPAG ### Modelación Predictiva ### 2021/05/07 --- # Featurización Para realizar aprendizaje automático en moléculas, se transforman en vectores de características (*feature*) que se pueden usar como entradas para los modelos. En `DeepChem`, el submódulo de características de `dc.feat` caracteriza moléculas en una variedad de formas. `DeepChem` usa cadenas SMILES (*Simplified Molecular-Input Line-Entry System*) para representar moléculas con cadenas de texto. Algunos modelos aceptan directamente cadenas de SMILES como entradas, pero con mucha más frecuencia, primero se convierte la cadena en una representación diferente (o la caracterizamos) que se adapte mejor al problema en cuestión. `DeepChem` depende de otro paquete en quiminformática, `RDKit`, para trabajar con cadenas SMILES, y convertir las cadenas en gráficas moleculares u otras representaciones. Las *huellas químicas* son vectores de unos y ceros que representan la presencia o ausencia de características específicas en una molécula, definida por alguna disposición local de átomos. Las ECFP (*Extended-connectivity fingerprints*) toman moléculas de tamaño arbitrario y las convierten en vectores de longitud fija, lo que permite tomar moléculas de muchos tamaños y usarlas con el mismo modelo. --- # Luego, el algoritmo trabaja hacia afuera, combinando cada átomo con todos los unos a los que está unido. Esto define un nuevo conjunto de características y se reestablecen los elementos correspondientes del vector. La variante más común de esta técnica es el algoritmo ECFP4, que permite que los subfragmentos tengan un radio de dos enlaces alrededor de un átomo central. Las ECFP tienen una la desventaja de codificar una gran cantidad de información sobre la molécula, pero parte de la información se pierde. Es posible que dos moléculas diferentes tengan huellas dactilares idénticas, y dada una huella dactilar, es imposible determinar de forma única de qué molécula proviene. Alternativamente, es útil describir moléculas con varias cantidades estructurales, como el coeficiente de partición logarítmica o el área de la superficie polar. Esta caracterización tenderá a funcionar mejor para predecir propiedades relativamente genéricas y es poco probable que funcione para predecir propiedades que dependen de la disposición de los átomos. Las *redes convolucionales de gráficas* usan vectores para cada nodo y/o borde que representan propiedades químicas de cada átomo, como su elemento, carga o estado de hibridación. Luego, calcula un nuevo vector para cada nodo y/o borde. Al no involucrar conformación molecular suelen ser adecuadas para moléculas pequeñas rígidas. --- # Modelación Entrenemos un modelo para predecir la solubilidad cargando datos de MoleculeNet. ```ptyhon tasks, datasets, transformers = dc.molnet.load_delaney(featurizer='GraphConv') train_dataset, valid_dataset, test_dataset = datasets ``` La facilidad con la que una molécula se disuelve en agua es de vital importancia para cualquier fármaco ya que si no se disuelve fácilmente, puede ser imposible que llegue una cantidad suficiente al torrente sanguíneo para que tenga un efecto terapéutico en pacientes. La opción `featurizer = 'GraphConv'` va a utilizar un modelo convolucional gráfico, y esto le dice a MoleculeNet que transforme la cadena SMILES para cada molécula en el formato requerido por el modelo. Entrenando se tiene: ```ptyhon model = dc.models.GraphConvModel(n_tasks=1, mode='regression', dropout=0.2) model.fit(train_dataset, nb_epoch=100) ``` --- # Se especifica una tarea para tener un valor de solubilidad para cada muestra, un modelo de regresión donde las etiquetas son números continuos y una tasa *dropout* del `\(20\%\)`. Ahora se evalua el modelo para ver qué tan bien funciona. Usaremos el coeficiente de correlación de Pearson como nuestra métrica de evaluación. ```ptyhon metric = dc.metrics.Metric(dc.metrics.pearson_r2_score) print("Training set score") print(model.evaluate(train_dataset, [metric], transformers)) print("Test set score") print(model.evaluate(test_dataset, [metric], transformers)) ``` `## Training set score` <br> `## {'pearson_r2_score': 0.9091030152194134}` <br> `## Test set score` <br> `## {'pearson_r2_score': 0.7136629027680488}` Esto informa un coeficiente de correlación de `\(0.90\)` para el conjunto de entrenamiento y `\(0.71\)` para el conjunto de prueba. Se observa un sobreajuste, por lo que el coeficiente de correlación puede ser representativo para ciertas situaciones donde el modelo predice con éxito las solubilidad. --- # Para predecir las solubilidades de nuevas moléculas supongamos que estamos interesados en las siguientes cinco moléculas, especificadas como cadenas SMILES: ```ptyhon smiles = ['COC(C)(C)CCCC(C)CC=CC(C)=CC(=O)OC(C)C', 'CCOC(=O)CC', 'CSc1nc(NC(C)C)nc(NC(C)C)n1', 'CC(C#C)N(C)C(=O)Nc1ccc(Cl)cc1', 'Cc1cc2ccccc2cc1C'] ``` Se usa `RDKit` para analizar las cadenas SMILES y `DeepChem` para convertirlas al formato esperado por la convolución de la gráfica. ```ptyhon from rdkit import Chem mols = [Chem.MolFromSmiles(s) for s in smiles] featurizer = dc.feat.ConvMolFeaturizer() x = featurizer.featurize(mols) ``` Finalmente, pasamos las entradas y las predicciones son: ```ptyhon predicted_solubility = model.predict_on_batch(x) for m,s in zip(smiles, predicted_solubility): print() print('Molecule:', m) print('Predicted solubility:', s) ``` --- `## Molecule: COC(C)(C)CCCC(C)CC=CC(C)=CC(=O)OC(C)C` <br> `## Predicted solubility: [-1.009957]` <br> `## Molecule: CCOC(=O)CC` <br> `## Predicted solubility: [1.4707849]` <br> `## Molecule: CSc1nc(NC(C)C)nc(NC(C)C)n1` <br> `## Predicted solubility: [-0.10435241]` <br> `## Molecule: CC(C#C)N(C)C(=O)Nc1ccc(Cl)cc1` <br> `## Predicted solubility: [-0.06695265]` <br> `## Molecule: Cc1cc2ccccc2cc1C` <br> `## Predicted solubility: [-0.8429378]`