mordredで記述子を計算する

今回の記事では、記述子計算ソフトウェアのmordredの使い方を紹介したいと思います。

mordredはそれまでの記述子計算ソフトウェアにあった不具合がなく、python3にも対応させたソフトウェアです。さらに、二次元記述子と三次元記述子を合わせて約2000個の記述子を計算できる優れものです。

mordredの使用例

mordredはcondaでのインストールを推奨していますが、今回は簡単に終わらせるためにpipを使ってインストールしました。その他、rdkit, deepchemについてもpipでインストールしています。

pip install 'mordred[full]' rdkit-pypi deepchem

それでは以下にmordredで記述子計算をするサンプルコードを記載したいと思います。

from rdkit import Chem
from rdkit.Chem import AllChem
from mordred import Calculator, descriptors
from deepchem.molnet import load_freesolv


tasks, datasets, transformers = load_freesolv()
train_dataset, val_dataset, test_dataset = datasets

train_mols = []
train_molhs = []
for smiles in train_dataset.ids[:20]:
    mol = Chem.MolFromSmiles(smiles)
    train_mols.append(mol)
    
    molh = Chem.AddHs(mol)
    AllChem.EmbedMolecule(molh, AllChem.ETKDG())
    train_molhs.append(molh)

calc_2d = Calculator(descriptors, ignore_3D=True)
df_train_2d = calc_2d.pandas(train_mols)
df_train_2d.to_csv("descriptors_2d.csv")

calc_3d = Calculator(descriptors, ignore_3D=False)
df_train_3d = calc_3d.pandas(train_molhs)
df_train_3d.to_csv("descriptors_3d.csv")

df_train_2d_missing = calc_3d.pandas(train_mols)
df_train_2d_missing.to_csv("descriptors_2d_missing.csv")

print(df_train_2d.shape)
print(df_train_2d_missing.shape)
print(df_train_3d.shape)

個々について解説します。

tasks, datasets, transformers = load_freesolv()
train_dataset, val_dataset, test_dataset = datasets

今回は記述子計算のための化合物情報がいくつかあればよかったのでデータセットは重要な話ではありませんが、一応紹介しておきたいと思います。使用したデータセットはFreeSolvデータセットです。deepchemを使用することで簡単に使用できます。SMILES情報はidsというattributeに格納されています。

train_mols = []
train_molhs = []
for smiles in train_dataset.ids[:20]:
    mol = Chem.MolFromSmiles(smiles)
    train_mols.append(mol)
    
    molh = Chem.AddHs(mol)
    AllChem.EmbedMolecule(molh, AllChem.ETKDG())
    train_molhs.append(molh)

全てのデータに対して記述子を計算すると時間がかかるので20個だけにしています。rdkitを使ってSMILESからmolオブジェクトに変換します。計算するのが二次元記述子のみでいい場合は、そのmolオブジェクトをリストに追加しておくだけですが、三次元記述子が必要な場合は立体配座を生成する必要があります。この処理もrdkitを使って実現することができます。ここで採用している手法はETKDGですが、rdkitには他にも立体配座を計算する手法がありますので確認してみて下さい。

calc_2d = Calculator(descriptors, ignore_3D=True)
df_train_2d = calc_2d.pandas(train_mols)
df_train_2d.to_csv("descriptors_2d.csv")

calc_3d = Calculator(descriptors, ignore_3D=False)
df_train_3d = calc_3d.pandas(train_molhs)
df_train_3d.to_csv("descriptors_3d.csv")

df_train_2d_missing = calc_3d.pandas(train_mols)
df_train_2d_missing.to_csv("descriptors_2d_missing.csv")

まず、二次元記述子のみ計算する場合はCalculatorの引数ignore_3DをTrueにします。これにより三次元記述子が計算されなくなります。df_train_2d_missingは比較のためにignore_3DをFalseにして計算をしています。

print(df_train_2d.shape)
print(df_train_2d_missing.shape)
print(df_train_3d.shape)

# >>> (20, 1613)
# >>> (20, 1826)
# >>> (20, 1826)

最後に生成したデータフレームを確認します。二次元記述子は1613個、これに三次元記述子を追加したものは1826個のカラムが生成されていることがわかります。立体配座を計算せずにignore_3DをFalseにしたものも1826個のカラムが生成されていますが、このデータフレームの三次元記述子のカラムにはエラーメッセージが入っています。例えば、MOMI-X, MOMI-Y, MOMI-Z, PBFのカラムは以下のようになります。

MOMI-XMOMI-YMOMI-ZPBF
missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (PBF)
missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (PBF)
missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (PBF)
missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (PBF)
missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (MOMI-X/mordred.MomentOfInertia.PrincipalAxis())missing 3D coordinate (PBF)

以上が簡単なmordredの使い方になります。Calculatorのignore_3D=Falseですぐに試せるようなサンプルコードが探しても見つからなかったので記事にしてみました。どなたかの助けになれれば幸いです。