#12 RDKit 2D descriptor である IPC の値が非常に大きい場合の対処法

yamasaKit
5 min readMar 5, 2019

--

TL; DR

RDKit 2D descriptor である IPC は値が非常に大きくなり機械学習で扱えなくなることがあります。 avg=True とすることで非常に大きな値になることを防ぐことができます。

以前にこのようなつぶやきをしました。

そしたら知人がこのつぶやきを見つけて、結局どうやったらいいの?と聞かれたのでブログにまとめておきます。

実はすでに issue にあがっており RDKit の作者の Greg さんから解答もされています。

IPC を計算するときに avg=True としたらいいよって言ってますね。

そもそも IPC ってなんじゃらほいって方はこちらをどうぞ。

Adjacency matrix に関する記述子なので大きい分子だと大きくなりそうなイメージですね。値が大きいと例えば sklearnなどで機械学習をするときにエラーが出ます。このエラーが曲者で

ValueError: Input contains NaN, infinity or a value too large for dtype('float64')

などと書いているもんですから、ついつい NaNInf ばっかり注目して探すけど「全然見つからない!なんで?」となってしまいます。

さて話を戻しますと、 avg=True あるいは avg=1 とすると平均をとるような感じで IPC の値が小さくなるようです。

ついでに言うと RDKit 2D descriptor って計算するときに呼び出すモジュールがあっちこっちにあってめんどくさいですよね?なので私は以下のような自作ライブラリにラッパー関数を作ってます。

import pandas as pd
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors
def calculate_descriptors(mols, names=None):
if names is None:
names = [d[0] for d in Descriptors._descList]
calc = MoleculeDescriptors.MolecularDescriptorCalculator(names)
descs = [calc.CalcDescriptors(mol) for mol in mols]
descs = pd.DataFrame(descs, columns=names)
return descs

計算する descriptor の名前を指定しなければ RDKit で計算できる 2D descriptor 全てを計算してくれます。今回の IPC の avg=True をオプションとして組み込むならちょっとダサいけど以下のような感じでしょうか?

import pandas as pd
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors
def calculate_descriptors(mols, names=None, ipc_avg=False):
if names is None:
names = [d[0] for d in Descriptors._descList]
calc = MoleculeDescriptors.MolecularDescriptorCalculator(names)
descs = [calc.CalcDescriptors(mol) for mol in mols]
descs = pd.DataFrame(descs, columns=names)
if 'Ipc' in names and ipc_avg:
descs['Ipc'] = [Descriptors.Ipc(mol, avg=True)
for mol in mols]
return descs

CalcDescriptors class のソースコードを見てきましたが attribute などに descriptor を計算する関数を持っているのではなくその都度呼び出しているようで、関数を書き換えられません。そこで、一回 IPC を計算してその後 avg=True で再計算した値で上書きしています。

ご参考になれば幸いです。

使い方の例の Gist ものせておきます。

RDKit (ver. 2018.09.1)

--

--