#はじめに
RDKitのフィンガープリントをPandasのデータフレームに取り込んで使い倒そう の続編。
前回は、Morgan FingerprintとAtomPair Fingerprintについてはハッシュの例しかなかったため、今回はアンハッシュの例を示す。
環境
- RDKit 2020.09.3
前準備
前回同様、本記事のソースを動かすにあたり、以下のモジュールをインポートしておく必要がある。
import numpy as np
import pandas as pd
from rdkit import rdBase, Chem
from rdkit import DataStructs
from rdkit.DataStructs import ExplicitBitVect
from rdkit.Chem import AllChem, Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors
#ハッシュ方式とアンハッシュ方式の違い
- ハッシュ方式はビット数固定だが、アンハッシュ方式はビット数が可変となる。
- ハッシュ方式はビットが衝突するため、一部の情報が失われてしまう。
フィンガープリントの説明
では、ここからMorgan Fingerprint(アンハッシュ)とAtomPair Fingerprint(アンハッシュ)について、フィンガープリントを求めてpandasに取り込む方法について説明する。
なお、以下のコード例は全て前提としてmols
という変数にRDkitのMolオブジェクトのリストが格納されていることを前提としている。
また、Pandasのデータフレームのindexは指定していないので、化合物名のリスト等、適宜補ってほしい。
Morgan Fingerprint (アンハッシュ)
Pandasに取り込む方法
ここでは、GetMorganFingerprint関数に半径3を指定して計算した結果を取り込む例を示す。
前回のTopologicalTorsion Fingerprintでもふれたが、計算を行うまでどんなビットがでてくるか分からないという特徴がある。化合物によって得られるビットも異なってくる。
従って計算しながらビット名をキーとして保持し、後から全化合物に対し存在しないビットの値を0で補完する処理が必要となる。
# Morganのフィンガープリントの計算
from collections import defaultdict
mg_fps_tmp = []
keys = set()
for mol in mols:
fp = AllChem.GetMorganFingerprint(mol, 3)
mg_fps_tmp.append(fp.GetNonzeroElements())
for key in fp.GetNonzeroElements():
keys.add(key)
mg_fps = defaultdict(list)
for fp in ap_fps_tmp:
for key in keys:
if key in fp:
mg_fps[key].append(fp[key])
else:
mg_fps[key].append(0)
df = pd.DataFrame(data=mg_fps)
AtomPair Fingerprint(アンハッシュ)
こちらもMorgan と全く同様の処理となる。
Pandasに取り込む方法
from collections import defaultdict
ap_fps_tmp = []
keys = set()
for mol in mols:
fp = AllChem.GetAtomPairFingerprint(mol)
ap_fps_tmp.append(fp.GetNonzeroElements())
for key in fp.GetNonzeroElements():
keys.add(key)
ap_fps = defaultdict(list)
for fp in ap_fps_tmp:
for key in keys:
if key in fp:
ap_fps[key].append(fp[key])
else:
ap_fps[key].append(0)
df = pd.DataFrame(data=ap_fps)
おわりに
アンハッシュ方式は、情報の損失がなくなる半面、説明変数の数が多くなるため変数選択が重要となる。うまく使い分けてモデルを作成しよう。
参考