Calcule o descritor molecular e a impressão digital de SMILES e armazene-os no quadro de dados [Python, RDKit]

2020 ano 1 mês 8 dia

Como criar um quadro de dados contendo descritores moleculares e impressões digitais de SMILES de um conjunto de dados composto com RDKit. Mesmo se eu tentasse fazer meu próprio modelo QSAR / aprendizado de máquina, me deparei com a criação de descritores moleculares e impressões digitais, portanto, vou resumi-los abaixo.

Significado do armazenamento no quadro de dados

Você pode criar um tipo de lista apenas para colocá-lo no aprendizado de máquina, mas usar um quadro de dados torna mais fácil fazer o seguinte.

  1. Uma visão panorâmica do conjunto de dados composto com base no descritor / impressão digital criado
  2. Pré-processamento de dados, como manipulação de valor ausente e redução de dimensão

Além disso, no RDKit, SMILES é convertido em um objeto mol para calcular o descritor, mas mesmo se houver algo que não possa ser convertido bem naquele momento, o quadro de dados é mais fácil de manipular.

Tente praticar

Preparação

Para dados de amostra, usaremos SMIELS do BBBP (conjunto de dados de penetração da barreira hematoencefálica) da MoleculeNet.

O objeto RDKit mol é armazenado em uma coluna chamada ROMol, portanto, crie um descritor com base nisso.

Referência: Lista de conjuntos de dados compostos

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 nome 0 p_np 0 sorrisos 0 ROMol 11 dtipo: int64

O erro "Valência explícita para o átomo # 1 N, 4, é maior do que o permitido" é exibido porque havia uma molécula (íon, etc.) com uma valência anormal ("4 átomos em N"). O valor está acima do permitido valor. ")Nenhum foi devolvido ao ROMol de tal molécula, e havia 11 desses SMILES aqui.

Você pode lidar com eles um por um, mas se o número for pequeno, é rápido removê-los por enquanto.Portanto, use isnull (). Sum () para verificar se há valores ausentes na coluna ROMol e remova essas linhas, se houver.

Referência: Resolução de problemas de leitura de dados compostos

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

# 欠損行の除去
df = df.dropna() 
Calcule o descritor molecular e a impressão digital do SMILES e armazene-o no quadro de dados

Se você vir "AVISO: não removendo átomos de hidrogênio sem vizinhos", provavelmente é porque os dados contêm sais. O RDKit salva H por padrão, então se houver um H (como o salt) que não está vinculado ao vizinho, tal H não pode ser removido e avisa você.

 

Criação de um descritor molecular

A função Map é útil para aplicar uma função a um objeto em cada linha em um quadro de dados.

Como os nomes e funções do descritor estão listados em "Descriptors.descList" do RDKit, leva um pouco de tempo, mas consegui calcular tudo de uma vez com a função for e a função map e retorná-la ao quadro de dados.

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

df.head()
Criação de um dataframe para o descritor molecular

Descritores para 201 colunas foram adicionados.

Ao aplicar a variável obtida ao scikit-learn ou a uma estrutura de aprendizado profundo, você pode obter o erro "Erro de valor: a entrada contém NaN, infinito ou um valor muito grande para dtype ('float64')". Tudo bem se eu fizesse o seguinte .

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

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

Parece que a causa é que uma parte do valor do descritor "IPC" é criada com tamanho infinito.

Referência: # 12 O que fazer se o valor IPC do descritor RDKit 2D for muito grande
Referência: Lista de descritores moleculares

Criação de uma impressão digital

Pode ser calculado rapidamente usando a função aplicar, mas parece que a lista de impressões digitais é armazenada em uma coluna.

Como a impressão digital é salva no formato de objeto BitVect explícito, demorava algum tempo para armazenar cada valor em uma coluna.

# 下準備
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)
Ao adicionar uma lista de impressões digitais a uma coluna
Ao armazenar cada valor de impressão digital em cada coluna