Berechnen Sie molekulare Deskriptoren und Fingerabdrücke aus SMILES und speichern Sie sie in einem Datenrahmen [Python, RDKit]

2020/1/8

Erstellen eines Datenrahmens mit molekularen Deskriptoren und Fingerabdrücken aus SMILES eines zusammengesetzten Datensatzes mit RDKit. Selbst wenn ich versucht habe, mein eigenes QSAR- / maschinelles Lernmodell zu erstellen, bin ich auf die Erstellung molekularer Deskriptoren und Fingerabdrücke gestoßen, daher werde ich sie im Folgenden zusammenfassen.

Bedeutung der Speicherung im Datenrahmen

Sie können einen Listentyp erstellen, um ihn in das maschinelle Lernen einzubeziehen. Die Verwendung eines Datenrahmens erleichtert jedoch die folgenden Schritte.

  1. Eine Vogelperspektive des zusammengesetzten Datensatzes basierend auf dem erstellten Deskriptor / Fingerabdruck
  2. Datenvorverarbeitung wie Handhabung fehlender Werte und Dimensionsreduzierung

Darüber hinaus konvertiert RDKit SMILES einmal in ein Mol-Objekt, um den Deskriptor zu berechnen. Selbst wenn es etwas gibt, das zu diesem Zeitpunkt nicht gut konvertiert werden konnte, ist der Datenrahmen einfacher zu handhaben.

Versuche zu üben

Vorbereitung

Für Beispieldaten verwenden wir SMIELS aus dem BBBP (Blut-Hirn-Schranke-Penetrationsdatensatz) von MoleculeNet.

Das RDKit mol-Objekt wird in einer Spalte namens ROMol gespeichert. Erstellen Sie daher einen darauf basierenden Deskriptor.

Referenz: Liste der zusammengesetzten Datensätze

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 name 0 p_np 0 lächelt 0 ROMol 11 dtype: int64

Der Fehler "Explizite Wertigkeit für Atom Nr. 1 N, 4 ist größer als zulässig" wird angezeigt, weil ein Molekül (Ion usw.) mit einer abnormalen Wertigkeit ("4 Atome in N") vorhanden war. Der Wert liegt über dem zulässigen Wert Wert. ")Keiner wurde in das ROMol eines solchen Moleküls zurückgebracht, und es gab hier 11 solcher LÄCHELN.

Sie können nacheinander mit ihnen umgehen, aber wenn die Anzahl klein ist, können Sie sie vorerst schnell entfernen.Verwenden Sie daher isnull (). Sum (), um nach fehlenden Werten in der ROMol-Spalte zu suchen, und entfernen Sie diese Zeilen, falls vorhanden.

Referenz: Fehlerbehebung beim Lesen zusammengesetzter Daten

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

# 欠損行の除去
df = df.dropna() 
Berechnen Sie molekulare Deskriptoren und Fingerabdrücke aus SMILES und speichern Sie sie in einem Datenrahmen

Wenn Sie "WARNUNG: Wasserstoffatome nicht ohne Nachbarn entfernen" sehen, liegt dies wahrscheinlich daran, dass die Daten Salze enthalten. RDKit speichert standardmäßig H. Wenn also ein H (z. B. Salz) nicht an den Nachbarn gebunden ist, kann dieses H nicht entfernt werden und warnt Sie.

 

Erstellen eines molekularen Deskriptors

Die Map-Funktion ist nützlich, um eine Funktion auf ein Objekt in jeder Zeile eines Datenrahmens anzuwenden.

Da die Deskriptornamen und -funktionen in "Descriptors.descList" von RDKit aufgeführt sind, dauert es etwas, aber ich konnte mit der Funktion for function und map auf einmal alles berechnen und an den Datenrahmen zurückgeben.

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

df.head()
Erstellen eines Datenrahmens für den molekularen Deskriptor

Deskriptoren für 201 Spalten wurden hinzugefügt.

Wenn Sie die resultierenden Variablen auf Scikit-Learn oder ein Deep-Learning-Framework anwenden, wird möglicherweise der Fehler "Wertfehler: Eingabe enthält NaN, unendlich oder einen Wert, der für dtype ('float64') zu groß ist" angezeigt. War in Ordnung, wenn ich das tat folgenden.

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

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

Es scheint, dass die Ursache darin besteht, dass ein Teil des Deskriptors "IPC" -Wert so groß wie unendlich erstellt wird.

Referenz: # 12 Was tun, wenn der IPC-Wert des RDKit 2D-Deskriptors sehr groß ist?
Referenz: Liste der molekularen Deskriptoren

Erstellen eines Fingerabdrucks

Es kann schnell mit der Apply-Funktion berechnet werden, aber es scheint, dass die Liste der Fingerabdrücke in einer Spalte gespeichert ist.

Da der Fingerabdruck im Format des expliziten BitVect-Objekts gespeichert ist, hat es einige Zeit gedauert, jeden Wert in einer Spalte zu speichern.

# 下準備
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)
Beim Hinzufügen einer Liste von Fingerabdrücken zu einer Spalte
Beim Speichern jedes Fingerabdruckwerts in jeder Spalte