yoheikikuta / paper-reading

Notes about papers I read (in Japanese)
156 stars 4 forks source link

[2202.05240] ChemicalX: A Deep Learning Library for Drug Pair Scoring #64

Open yoheikikuta opened 2 years ago

yoheikikuta commented 2 years ago

論文リンク

https://arxiv.org/abs/2202.05240

公開日(yyyy/mm/dd)

2022/02/10

概要

drug pair scoring task (2 つの drug を入力にして例えば特定の癌細胞を殺せるか否かなどを予測する) を解くための deep learning library である ChemicalX を構築したという論文。 pair scoring はいくつかの具体的なタスクが想定されており、複数の薬を使うことによる副作用、複数の薬の相互作用(効果が増強されたり打ち消されたりする)、複数の薬のシナジー効果(ある疾患を治療する時に複数の薬を使うことで単独の薬を足す以上の効果を発揮する)、などがある。 この論文自体では新しいモデルを提案したというものではなくて、上記のような具体的なタスクを抽象化して pair scoring task という一つの枠組みに統一したこと、それらにマッチするように色々なデータセットを整理して扱えるようにしたこと、先行研究で提案された主要なモデルを使って scoring task に適用できるようにしたこと、それらを ChemicalX という一つのライブラリにまとめたこと、が主たる貢献となる。

公式実装: https://github.com/AstraZeneca/chemicalx

yoheikikuta commented 2 years ago

論文を色々眺めていた時に見つけた論文。 薬の相互作用を調べるとか具体的にはどういうタスクで現状どういうことができるようになってるのかな、というのをちょっと学んでみようと思ったので読んでみることにした。

yoheikikuta commented 2 years ago

deep learning を chemical 分野に応用しようという動きは他分野と同様活発に実施されているが、先行研究は single drug task (入力が 1 つの drug の化学式で出力が何かしらの化学的活性を予測する、みたいなタスク) しか扱っていなかった。

この論文では drug pair を対象にする。 drug pair を扱うこと自体はこの論文が最初ということではなくて先行研究が色々あるが、さまざまなタスクを統一的に扱えるように抽象的な定式化をして、様々なモデルを扱えるようにした上でライブラリとして提供するぞ、というのがこの論文の目的。

個別タスクの詳細なところを理解するには色々勉強しないといけないことがあると思うけど、大まかな全体像を眺めてみるという意味ではよさそうかなと思って読んでいる。

yoheikikuta commented 2 years ago

今回解きたい問題設定をお気持ちで図示すると以下のような図になる。

入力は 2 つの drug になる。これは本質的には構造式を入力している(実装上は TorchDrug https://torchdrug.ai/ というライブラリで定義されるオブジェクトになるのだが、情報量としては構造式と思っておけばよい)。

2 つの drug は encoder で分散表現へと変換され、2 つの分散表現を head layer で混ぜ合わせて出力をする。 出力はいくつかのタスクを統一的に扱えるようにするために少し複雑になっている。drug application context は図を見ても意味がわからないが、これはデータセットごとの情報であり、例えば特定の癌細胞を殺す機能みたいなものが含まれ、それが one-hot encoding された情報として格納されている。それに加えて、その機能が実際に発現するかを {0,1} で表現するための出力もある。 なので例えば、context が [0,1,0,...] みたいになっててこれが特定の癌細胞を殺す機能を示すもので、ラベルが 1 であれば発現する(0 であれば発現しない)というものになる。

yoheikikuta commented 2 years ago

この辺りの問題を取り扱うのに重要になる観点は以下のようなものがある。

分子の表現と特徴量

分子の情報を余すことなく使いたい場合は 3 次元の配位情報と電磁気情報を使う必要があるが、それはフルで扱うのは大変なので proxy として 2 次元の化学式の情報を使う。この 2 次元情報は高校化学でやるようなケクレ構造式(水素の共有結合を線で表現するやつ)を用いる。 とはいえこのような 2 次元の情報であってもその表現と取り扱いが大変なので、これを 1 次元の string 情報である SMILES https://en.wikipedia.org/wiki/Simplified_molecular-input_line-entry_system などで扱えるようにしている。この SMILES 記法というのは自分は知らなかったが、例えば イソシアン酸メチル CH3N=C=O という分子は CN=C=O と表現されるらしい。 この 1 次元表記は構造の曖昧性がないとのことで、基本的にはこの SMILES 記法での string 表現を分子の表現として扱う(各種ライブラリではここから 2 次元のケクレ構造式を描写する機能が提供されていることが多い)。

2 次元構造は古典的には分子の部分構造の有無に基づいた離散的特徴量(この部分構造があるとかないとか)を作るのに使われていた。 その後 1 次元 string 情報に言語モデルを適用して連続的特徴量(分散表現)を獲得するようになった。

最近ではグラフ畳み込みを使って分子グラフの連続的特徴量を直接学習するようになっている。原子をノード、原子間結合をエッジとしてグラフとして扱い、原子の特徴量を集めて permutation invariant な pooling function を通すことで分子(ここでは drug )の特徴量を抽出する。

permutation invariant なのは(エッジの情報を取り込んだ)ノードの特徴量を使っているためである。 エッジとノードの両方を考えれば当然 permutation invariant ではないが、message passing layer でエッジでつながる隣接ノードの特徴量を作りというのを繰り返すと遠くのエッジの情報まで取り込んだ各ノードの特徴量が抽出できる。これらの特徴量は既にエッジの情報を取り込んでるので、どの順番に並べても同じ情報を表現しているので permutation invariant となっている必要があるということである。

(全ての drug の特徴量抽出に GCN を使っているというわけではなく、単なる feedfoward network のモデルとかもある。典型的には GCN を使うものが多いということ)

drug pair scoring でやりたいこと

冒頭で挙げたように 3 つある。

drug discovery に使えるソフトウェア

色々あるらしく論文では以下のように紹介されている。 operate on drug と caption では書いてあるが、実際には GCN を扱えるライブラリみたいな括りでまとめられており、なので表は drug domain と pair scoring の両方がバツになっているものが多い。 読み取るべきは PyTorch が多いということと、この論文で実装した ChemicalX が pair scoring を提供していること、である。

yoheikikuta commented 2 years ago

drug pair scoring の定式化の部分を見ていく。 先に言っておくと、定式化はシンプルで特に難しいところはない。ただし具体的にどういうデータになっているのかというのは分からないい。実装を見ても元データを加工して feature vector にした json があるのみでそれがどういう意味なのかが分からない。元データを見にいってもこの json のデータとどういう関係性があるかはパッとは分からない。よくデータを使ってる人からすると分かるのかもしれないが、これは description がないと分からないのであって欲しかった...

まずは drug feature set の定義。 特徴ベクトルは電荷量などを並べたもの。例えば DrugDatabank DDI の Trioxsalen では Physiological Charge が 0 という具合である: https://go.drugbank.com/drugs/DB04571#summary このほかにもいろいろな特徴量があることがわかる。 あとはグラフ構造と node と edge の matrix を合わせて feature set としている。 実装においてはこれは https://github.com/AstraZeneca/chemicalx/blob/bc71eb43f32bb245327a30e44b731be1d203b4d8/dataset/drugbankddi/drug_set.json のように与えられている。

次に context feature set の定義。 これはどういうコンテキストで予測をするかをコントロールするためのもの。例えばがん細胞を殺すか?というコンテキストを表現し、それが yes か no かを予測する、というように使う。 実装においてはこれは https://github.com/AstraZeneca/chemicalx/blob/bc71eb43f32bb245327a30e44b731be1d203b4d8/dataset/drugbankddi/context_set.json のように one-hot encoding で与えられている(めちゃ無駄な持ち方をしているが)。

次に labeled drug pair の定義。 これは drug の pair とコンテキスト、そしてそれを yes, no で予測するためのラベル、という組みから成っている。 実装においてはこれは https://github.com/AstraZeneca/chemicalx/blob/bc71eb43f32bb245327a30e44b731be1d203b4d8/dataset/drugbankddi/labeled_triples.csv のように与えられている。

次に drug encoder の定義。 これは drug feature を入力にして NN を介して分散表現での特徴量を抽出する。これは straightforward である。

次に context encoder の定義。 これは context feature を入力にして NN を介して分散表現での特徴量を抽出する。これも straightforward である。

次に scoring head layer の定義。 これは drug1, drug2, context feature の分散表現を入力にして NN を介してスコアを算出する。これは label が positive である確率を計算するもので、例えば drug1,2 がその組み合わせによってあるがん細胞を殺すというコンテキストを考えたときに、yes/no を予測するというものになる。

最後に loss function の定義。 これは普通の loss function で、基本的には Binary Cross Entropy を使う。論文ではほとんど触れられていないが、コードでは CASTER というモデルも実装されていて、このモデルはやや複雑な loss function になっている(encode したものを decode して reconstruction loss も入れてるとか): https://github.com/AstraZeneca/chemicalx/blob/646314711cd516b7e58cc41e86109b6e1ae6fb3a/chemicalx/loss.py

yoheikikuta commented 2 years ago

feature が実際にはどういうものかという話。

データがどういうものなのかを知りたかったが、情報が少なくて残念だった。 データセットのサイズ感は以下のように成っている。薬のデータだからそんなに数が多くないね。

yoheikikuta commented 2 years ago

あとは学習の仕方とか scalability と称してバッチサイズを変えた時の時間とか薬の数を変えた時の時間とか測ってるけど、あまり情報量がないので割愛。

あとは予測精度がどんなものかは以下。 この論文では新しいモデルを提案してるわけではないので全て先行研究のモデルだけど、DeepSynergy という feedforward のモデルか MR-GNN という GCN のモデルがよさそうな性能を出している。 DrugComb という synergy を調べるためのデータセットでの予測は AUROC 0.744 が最高性能ということで、現状のデータではそんなに予測精度が高くない(難しいタスクではあると思うけど、まだまだデータが足りないんだろうなぁきっと)。

yoheikikuta commented 2 years ago

potential user として、腫瘍学の専門家、計算化学者、薬の安全性の研究者、を挙げている。 現時点では十分なデータがなさそうな雰囲気も感じるけど、経済的なポテンシャルも大きな分野だし、将来的には AlphaFold みたいに世界を変え得るモデルが出てくると面白そう。

ということで一通り読んでみた。 データセットの理解をもう少ししたいところだったが情報が乏しくてちょっと厳しかった。