RDKitでフィンガープリントを使った分子類似性の判定

pythonの代表的なケモインフォマティクスライブラリであるRDKitについて,これまで化合物の性質を表現するために記述子について学びました.

記述子は芳香環や回転可能な結合の総数といった構造に関連するものから,脂溶性を表すLogPなど物性に関連するものまで色々ありますが,基本的には分子の部分的な特徴を表現しているに過ぎません.とは言っても例えば構造に関する記述子を多数まとめれば,分子全体の構造的特徴を網羅できそうなことは想像できると思います.

今回扱うフィンガープリントもそういったある一定のルールに基づいて分子全体を1つの表現型で表したものになります.人間1人1人の指紋が異なるように,異なる化合物間ではフィンガープリントは異なりますが,類似した化合物では似たものになるように設計されています.

「類似した化合物」の定義が場合によって異なりますので,データセットや目的によって最適なフィンガープリントは異なります.そのため様々なフィンガープリントが開発されています.

今回はRDKitに実装されているフィンガープリントについて簡単に見ていきながら,どのようにして類似度を評価するか,類似度をどのように可視化するかについて学んでいきます.

ライブラリと分子の準備

まずはいつものように必要なライブラリのimportを行っておきましょう.今回はある程度類似した化合物のセットが欲しいので,SDFには東京化成で検索したサリチル酸誘導体を使います.

import pandas as pd
from rdkit import rdBase, Chem, DataStructs, Draw
print(rdBase.rdkitVersion) # 2017.09.1
from rdkit.Avalon import pyAvalonTools
from rdkit.Chem import AllChem
from rdkit.Chem.Fingerprints import FingerprintMols
from rdkit.Chem.AtomPairs import Pairs, Torsions
suppl = Chem.SDMolSupplier('./sdf_20180716131641.sdf')
mols = [x for x in suppl if x is not None]
len(mols) # 73

分子類似性:なぜ似た化合物に興味があるのか?

我々がなぜ類似化合物に興味があるかというと,「類似した化合物は似た性質を持つ」というsimilar property principleというものに由来します.ある生理活性を持つ化合物と似た構造の化合物はやはり同じような生理活性を持つというわけです.この「法則」自体はこれまでの数多くの検証によって正当性が確かめられています.

問題は先ほども述べたように,何をもって似ているとするかは場合によって異なるので,万能な方法がないということになります.

フィンガープリントの作成方法

フィンガープリント作成には色々なルールがあると述べましたが,例えば部分構造のを数え上げていくタイプを考えてみます.その場合,「芳香環の数」=3,「窒素原子の数」=4,,,といった形である部分構造とその数をペアとした辞書型のデータができあがると考えられます.しかしこのままではコンピュータで処理をしにくく,類似度の評価などが困難です.

そこで得られた辞書型のデータにある処理を施すことで,長さ一定(1024や2048が多いです)のビット配列に0か1を埋め込んだ形式に変換を行うことが多いです.この作業のことをハッシュ化と呼びます.

これから実際のメソッド名を紹介していきますが,その中に「GetHashedFingerprintAs’XXX’」といった記載があるのはHashed化されたフィンガープリントを‘XXX’の形で取得といった意味になります.大抵のメソッドは対象とするMolオブジェクトの他に,nBitsというビットの長さを指定する引数を取ることができます.

類似度の評価

ここまでの説明から,化合物の類似度をコンピュータを使って考えるにあたって,化合物のフィンガープリントが必要なことはわかっていただけたかと思います.それでは2つの化合物のフィンガープリントが与えられたときにどのようにして類似度を評価すればよいでしょうか?

困ったことにフィンガープリント同様に,様々な評価方法が提唱されていますが,最もよく使われている「タニモト係数」と呼ばれるものです.2つの分子AとBのビット配列フィンガープリントからタニモト係数を計算するに下記の式を使います.

$$ S_{AB} = \frac{c}{a + b – c} $$

ここで,aは分子Aのビット配列で1が立っている数bは分子Bのビット配列で1が立っている数cは分子AとBで共通に1が立っている数を示します.タニモト係数はその定義から0から1の値を取ることになります.

下に示した仮想のフィンガープリントを使ってタニモト係数は計算してみましょう.

この場合,a=8,b=6,c=5(赤色の数字の数)となりますから,タニモト係数は

$$ S_{AB} = \frac{5}{8 + 6 – 5} = 0.56 $$

と求まります.

他によく使われる評価方法としてDice係数があって,こちらの定義式は

$$ S_{Dice} = \frac{2c}{a + b} $$

で表されます.a,b,cの定義はタニモト係数と同じです.

より一般的なTverskyインデックスというものがあり,こちらは

$$ S_{Tversky} = \frac{c}{\alpha (a-c) + \beta (b-c) + c} $$

になります.つまりタニモト係数は「α=β=1」の場合,Dice係数は「α=β=0.5」の場合に相当します.

タニモト係数やDice係数は例えばZINCデータベースで類似度構造検索する際に使われています.

RDKitでのフィンガープリントを用いた類似度評価の行い方


・1分子ごとに計算
DataStructs.FingerprintSimilarity(fp1, fp2, metric)
DataStructs.TanimotoSimilarity(fp1, fp2)
DataStructs.DiceSimilarity(fp1, fp2)
・まとめて計算
DataStructs.BulkTanimotoSimilarity(refFP, FP_list)
DataStructs.BulkDiceSimilarity(refFP, FP_list)

フィンガープリントの比較にはrdkit.DataStructsモジュールにあるメソッドを使います.

分子1つずつを比較する場合にはFingerprintSimilarityを用います.その際にmetricを指定することでどの基準で比較するかを選択できます.デフォルトではタニモト係数で比較されますが,他にもいくつかの方法を選択可能です.

また各metricごとにメソッドが用意されていてタニモト係数を計算したい場合にはTanimotoSimilarityを,Dice係数を計算したい場合にはDiceSimilarityを使います.

さらにある分子のフィンガープリントを使って,一連のフィンガープリントリストに対する係数を一挙に計算したい場合が多々ありますが,その場合にはBulk‘XXX’メソッドを使うことで計算可能です.具体的には後ほどコードを使って見ていきます.

RDKitに実装されているフィンガープリントのまとめ

MACCS Keys

Chem.MACCSkeys.GenMACCSKeys(mol)
AllChem.GetMACCSKeysFingerprint(mol)

どちらも同じものです

ケモインフォマティクスでは非常に有名なMDL社の開発した化学構造データベースに由来するフィンガープリントです.

全部で166の部分構造についての有無を調べ上げたもので,RDKit内の情報保持のために1ビット使っているため全部で167ビットのフィンガープリントになります.部分構造を有する場合は1が,ない場合は0が格納されています.

maccs_fps = [AllChem.GetMACCSKeysFingerprint(mol) for mol in mols]
maccs = DataStructs.BulkTanimotoSimilarity(maccs_fps[0], maccs_fps[1:])

Topologicalフィンガープリント (RDKitフィンガープリント)

Chem.RDKFingerprint(mol)

ハッシュ化フィンガープリントの中では有名なDaylightフィンガープリントに類似したものと考えてよいです.RDKitフィンガープリントとも呼ばれています.

一定の結合数に相当する原子と結合種類を格納する方法で,事前に部分構造を用意する必要がないことから,より柔軟に分子構造を表現することが可能です.

rdkit_fps = [Chem.Fingerprints.FingerprintMols.FingerprintMol(mol) for mol in mols]
rdkit = DataStructs.BulkTanimotoSimilarity(rdkit_fps[0], rdkit_fps[1:])

Morganフィンガープリント (Circularフィンガープリント)

・ECFP類似
AllChem.GetMorganFingerprint(mol, radius)
AllChem.GetMorganFingerprintAsBitVect(mol, radius, nBits)
・FCFP類似
AllChem.GetMorganFingerprint(mol, radius, useFeatures=True)

原子からある距離にある部分構造を数え上げていく,「circular substructures」と呼ばれるタイプのフィンガープリントです.radiusの値で距離を設定します.いわゆるECFP(Extended Connectivity Fingerprint)フィンガープリントと類似のものですが,探索距離の定義が異なる点に注意が必要です.

よく使われるECFP4はradius=2の設定(デフォルト)と大体同じとのことです.FCFP(Functional Connectivity Fingerprint)様のフィンガープリントを用いたい場合にはuseFeatures=Trueを設定します.

RDKitのMorganフィンガープリントとECFPフィンガープリントの違いについては「Morgan Fingerprints (Circular Fingerprints)」を参照してください.:
“When comparing the ECFP/FCFP fingerprints and the Morgan fingerprints generated by the RDKit, remember that the 4 in ECFP4 corresponds to the diameter of the atom environments considered, while the Morgan fingerprints take a radius parameter. So the examples above, with radius=2, are roughly equivalent to ECFP4 and FCFP4.”

また標準のGetMorganFingerprintでは非常に長いフィンガープリントが得られてきますので,ビット長を指定したGetMorganFingerprintAsBitVectを用いる方がよいでしょう.これから最も頻繁に使っていくフィンガープリントになると思います.

morgan_fps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2, 2048) for mol in mols]
morgan = DataStructs.BulkTanimotoSimilarity(morgan_fps[0], morgan_fps[1:])

Avalonフィンガープリント

rdkit.Avalon.pyAvalonTools.GetAvalonFP(mol)
rdkit.Avalon.pyAvalonTools.GetAvalonCountFP(mol)

RDKitから用いることのできるAvalon Chemoinformatics TookKitにもフィンガープリントが実装されています.

avalon_fps = [pyAvalonTools.GetAvalonFP(mol) for mol in mols]
avalon = DataStructs.BulkTanimotoSimilarity(avalon_fps[0], avalon_fps[1:])

アトムペアと二面角

Chem.AtomPairs.Pairs.GetAtomPairFingerprint(mol)
Chem.AtomPairs.Torsions.GetTopologicalTorsionFingerprint(mol)

アトムペアを用いるフィンガープリントは全ての原子同士についてその最小結合パスを記録します.各原子には原子の種類,結合する原子のうち水素以外の元素の数,π電子数の情報も記録されます.

二面角を用いるフィンガープリントは,二面角を形成する4連続原子について,やはり原子の種類,結合する原子のうち水素以外の元素の数,π電子数を記録します.

各フィンガープリントの比較

ここではRDKit,MACCS,Morgan,Avalonの各フィンガープリントについて相関を見てみましょう.先に求めた最初の分子のフィンガープリントに対するタニモト係数を使って比べてみます.

df = pd.DataFrame({'RDKit': rdkit,
                  'Avalon': avalon,
                  'MACCS': maccs,
                  'Morgan': morgan})
df.corr().round(2)
RDKit MACCS Morgan Avalon
RDKit 1.00 0.79 0.85 0.88
MACCS 0.79 1.00 0.68 0.64
Morgan 0.85 0.68 1.00 0.79
Avalon 0.88 0.64 0.79 1.00

同じ分子を同じ方法で類似度を比較しても,用いるフィンガープリントによって随分と値がことなることが見て取れると思います.

BitVectオブジェクト(ExplicitBitVect)の扱い方

BitVect.GetNumBits()
BitVect.GetNumOffBits()
BitVect.GetNumOnBits()
BitVect.GetOnBits()
BitVect.GetBit(idx)

フィンガープリントのビット配列はExplicitBitVectオブジェクトと呼ばれ,ビット配列の長さや1が立っているビットの数,位置などの情報が取得可能です.下の例ではMorganフィンガープリントを用いてデフォルトの長さと,長さ2048のビット配列へと短縮した場合について長さを求めています.デフォルトのMorganフィンガープリントはExplicitBitVectオブジェクトではないので,メソッド名が若干異なりますが意味は通じると思います.

morgan_default = AllChem.GetMorganFingerprint(mols[0], 2)
morgan_bitvect = AllChem.GetMorganFingerprintAsBitVect(mols[0], 2, 2048)
print(morgan_default.GetLength(), morgan_bitvect.GetNumBits())
(4294967295, 2048)

化合物の類似性を可視化する

各ビットの構造情報を可視化

RDKitの2018.09のアップデートから,RDKitフィンガープリントやMorganフィンガープリントのビット配列を可視化するコードが追加されました.このコードを用いると下のように,各ビットがどのような化学的な意味を表しているかを掴むことが可能になります.

この可視化方法については,「RDKitでフィンガープリントの可視化」という記事で具体的に解説していますので,参照してみてください.

分子全体の特徴を表現する方法として,「RDKitでフィンガープリントを使った分子類似性の判定」という記事では分子のフィンガープリントを導入し...

原子ごとの寄与率を用いた可視化方法

・規格化
SimilarityMaps.GetSimilarityMapForFingerprint(refMol, prbMol, fp_F)
・ウェイトの絶対値を利用
SimilarityMaps.GetAtomicWeightsForFingerprint(refMol, prbMol, fp_F)
SimilarityMaps.GetSimilarityMapFromWeights(mol, weight)

アトムペア,二面角,そしてMorganフィンガープリントを用いた場合には,原子ごとに類似度の寄与率を可視化することが可能です.寄与度を規格化する場合と,しない場合の2通りの方法が選択可能です.

下のコードでは,何れもシュガー構造を有するmols[8]とmols[18]を用いて,Morganフィンガープリントへの各原子の寄与度を可視化してみます.

Draw.MolsToGridImage([mols[8], mols[18]], subImgSize=(300,400), legends=['mols[8]', 'mols[18]'])
weight = SimilarityMaps.GetAtomicWeightsForFingerprint(mols[8], mols[18], SimilarityMaps.GetMorganFingerprint)
fig = SimilarityMaps.GetSimilarityMapFromWeights(mols[18], weight, size=(400,400))


予想通りシュガー構造の部分とサリチル酸誘導体部位の寄与が大きいことがわかります.

RDKitの類似度マップを用いて原子ごとの寄与を可視化する」という記事では,フィンガープリントだけではなく原子電荷MolLogPなどといった他の化合物の性質についても同様の手法によって可視化する方法を解説しています.参考にしてください.

終わりに

今回は分子の個々の性質を表現する記述子の考え方をさらに発展させることで,分子全体の特徴を表すフィンガープリントを扱いました.さまざまなフィンガープリントがあることを学び,ビット文字列で表されたフィンガープリントを比較することで,分子の類似度を評価しました.さらに類似分子では実際にどの構造が類似しているかを知るために,フィンガープリントにおける原子毎の寄与率を求め可視化しました.

なお今回は扱いませんでしたが,RDKitには2Dファーマコフォアによるフィンガープリントも実装されています.こちらはファーマコフォアを扱う際に触れる予定です.

今回求めた分子同士の類似度は,分子全体の類似になります.次回は分子同士の部分構造に着目し,共通構造を探し出す手法,Maximum Common Subgraph (Substructure)を扱います.次々と新しいコンセプトが出てきますが,その分できることがどんどん増えていっています.焦らずに,地に足をつけて学習していきましょう.

>>次の記事:「RDKitを用いた部分構造検索とMCSアルゴリズム

シェアする

  • このエントリーをはてなブックマークに追加

フォローする