Calculer les descripteurs moléculaires et les empreintes digitales de SMILES et les stocker dans un cadre de données [Python, RDKit]

2020er mars 1

Comment créer un cadre de données contenant des descripteurs moléculaires et des empreintes digitales à partir de SMILES d'un ensemble de données composé avec RDKit. Même si j'essayais de créer mon propre modèle QSAR / apprentissage automatique, je suis tombé sur la création de descripteurs moléculaires et d'empreintes digitales, je vais donc les résumer ci-dessous.

Importance du stockage dans la trame de données

Vous pouvez créer un type de liste simplement pour le placer dans l'apprentissage automatique, mais en faire un bloc de données facilite les opérations suivantes.

  1. Une vue d'ensemble du jeu de données composé en fonction du descripteur / de l'empreinte digitale créé
  2. Prétraitement des données tel que la gestion des valeurs manquantes et la réduction des dimensions

De plus, dans RDKit, SMILES est une fois converti en objet mol afin de calculer le descripteur, mais même s'il y a quelque chose qui n'a pas pu être correctement converti à ce moment-là, la trame de données est plus facile à gérer.

Essayez de pratiquer

Préparation

Pour des exemples de données, nous utiliserons SMIELS du BBBP (ensemble de données de pénétration de la barrière hémato-encéphalique) de MoleculeNet.

L'objet mol RDKit est stocké dans une colonne appelée ROMol, créez donc un descripteur basé sur celui-ci.

Référence: liste des jeux de données composés

import numpy as np
import pandas as pd
 
from rdkit import rdBase, Chem
from rdkit.Chem import AllChem, PandasTools, Descriptors
from rdkit.Chem.Draw import IPythonConsole
 
print('rdkit version: ',rdBase.rdkitVersion)  # rdkit version:  2019.03.4
 
# 下準備
# データセットの読み込み
df = pd.read_csv("BBBP.csv")
 
# dfのSMILES列を参照してMolオブジェクト列をデータフレームに加える
PandasTools.AddMoleculeColumnToFrame(df,'smiles')
 
# Molオブジェクトが作成できたか確認
print(df.shape)
print(df.isnull().sum())  
(2050, 4) num 0 nom 0 p_np 0 sourires 0 ROMol 11 dtype: int64

L'erreur "La valence explicite de l'atome n ° 1 N, 4, est supérieure à la valeur autorisée" s'affiche car il y avait une molécule (ion, etc.) avec une valence anormale ("4 atomes dans N"). La valeur est supérieure à la valeur autorisée valeur. ")Aucun n'a été renvoyé au ROMol d'une telle molécule, et il y avait 11 sourires de ce type ici.

Vous pouvez les traiter un par un, mais si le nombre est petit, il est rapide de les supprimer pour le moment.Par conséquent, utilisez isnull (). Sum () pour vérifier les valeurs manquantes dans la colonne ROMol et supprimez ces lignes le cas échéant.

Référence: Dépannage de la lecture de données composées

# ROMolが作成できなかったものを確認
print(df[df.ROMol.isnull()])

# 欠損行の除去
df = df.dropna() 
Calculez les descripteurs moléculaires et les empreintes digitales de SMILES et stockez-les dans un bloc de données

Si vous voyez "AVERTISSEMENT: ne pas supprimer les atomes d'hydrogène sans voisins", c'est probablement parce que les données contiennent des sels. RDKit enregistre H par défaut, donc s'il y a un H (tel que salt) qui n'est pas lié au voisin, ce H ne peut pas être supprimé et vous avertit.

 

Créer un descripteur moléculaire

La fonction Map est utile pour appliquer une fonction à un objet dans chaque ligne d'un bloc de données.

Puisque les noms et fonctions des descripteurs sont répertoriés dans "Descriptors.descList" de RDKit, cela prend un peu de temps, mais j'ai pu tout calculer en même temps avec la fonction for et la fonction map et le renvoyer dans le bloc de données.

for i,j in Descriptors.descList:
    df[i] = df.ROMol.map(j)
 
df.shape
# (2039, 205)

df.head()
Création d'une trame de données pour le descripteur moléculaire

Des descripteurs pour 201 colonnes ont été ajoutés.

Si vous appliquez les variables résultantes à scikit-learn ou à un framework d'apprentissage en profondeur, vous pouvez obtenir l'erreur "Erreur de valeur: l'entrée contient NaN, l'infini ou une valeur trop grande pour dtype ('float64')". Suivant.

for i,j in Descriptors.descList:
    df[i] = df['ROMol'].map(j)

df['Ipc'] = [Descriptors.Ipc(mol, avg=True) for mol in df['ROMol']]  

Il semble que la cause en soit qu'une partie de la valeur du descripteur "IPC" soit créée aussi grande que l'infini.

Référence: # 12 Que faire si la valeur IPC du descripteur RDKit 2D est très grande
Référence: Liste des descripteurs moléculaires

Créer une empreinte digitale

Il peut être calculé rapidement à l'aide de la fonction Apply, mais il semble que la liste des empreintes digitales soit stockée dans une colonne.

Étant donné que l'empreinte digitale est enregistrée au format d'objet BitVect explicite, il a fallu un certain temps pour stocker chaque valeur dans une colonne.

# 下準備
df = pd.read_csv("BBBP.csv")
PandasTools.AddMoleculeColumnToFrame(df,'smiles') 
df = df.dropna()
 
# 1列にfingerprintのリストを追加する場合
df['FP'] = df.apply(lambda x: AllChem.GetMorganFingerprintAsBitVect(x.ROMol, 2, 1024), axis=1)

# fingerprintの各値を各列に格納する場合
# 個別に01をデータフレームに格納する
FP = [AllChem.GetMorganFingerprintAsBitVect(mol, 2, 1024) for mol in df.ROMol]
df_FP = pd.DataFrame(np.array(FP)) 

# フィンガープリントをもとのデータフレームに結合
df_FP.index = df.index
df = pd.concat([df, df_FP], axis=1)
Lors de l'ajout d'une liste d'empreintes digitales à une colonne
Lors du stockage de chaque valeur d'empreinte digitale dans chaque colonne