非プログラマーのためのインフォマティクス入門。(仮)

非プログラマーがインフォマティクスについて勉強したことを記録します。主にKNIMEというソフトを使用しています。

非プログラマーのためのインフォマティクス入門。(仮)

【KNIME】お手軽に機械学習してみませんか? 〜random_forest_regression〜

久しぶりに記事を書きます。二児の親となり、家のことを忙しくしつつ、最近は機械学習をかじり始めました。始めたといっても、いろいろを触って、動かしてみている程度。きっちり取り組んでいる方には怒れらてしまいそうですが、様々なツールも出回り、コモディティ化が進んでいるなかで、まったくいじったことがないというのも良くないと思いまして。

今回は、"学習用データがある場合"に可能&お手軽簡単に数値予測ができるKNIMEのノード を紹介しようと思います。

 

Random Forest Learner & Predictor (regression)

 最近の流行は、やっぱりdeeplearningだと思うのですが、それだけが全てではないです。現在、私もDeepChemを使ってDLに挑戦していますが、wetのケミストが気楽にアクセスできる感じではありません(プログラミング経験のある方なら、何とかなるかもしれませんが)。

そんな中、今回の方法

KNIMEを使って、ECFP4を入力としてRandom Forestで回帰する

は殆ど頭を使うことがないので誰でも使える!と断言できます(但し、得られる結果については個人で判断してくださいね)。では早速KNIMEのフローを見ていきます。

f:id:sumtat:20180127152027p:plain

全体図は上のキャプチャの通りです。今回の題材としては

http://deepchem.io.s3-website-us-west-1.amazonaws.com/datasets/delaney-processed.csv

からgetできるdelaney_processed.csvを使っていこうと思います。

CSV Reader

f:id:sumtat:20180127152657p:plain

基本的には読みたいcsvの場所をInput locationに指定するだけでOKなのですが、今回の場合、column(列)のヘッダはあるけど、row(行)のヘッダはないので、Has Row Headerのチェックは外しておきます。また読み込むファイルにはSMILESが含まれるので、デフォルトでComment Charに入っている#を消しておきましょう。三重結合が入っているとsmilesが上手く読めなくなっちゃうからです。

Molecule Type Cast

分子構造に関する記述があるcolumnの属性を直してくれるノードです。つまり、今回読み込んだcsvには構造がsmiles記法でかかれていますが、データの属性としてはstring(文字列)として認識されています。これをKNIMEに「これはsmilesだよ!構造式だよ!」と分からせるための処理です。

f:id:sumtat:20180127153256p:plain

ノードを通す前後のテーブル内容も貼り付けておきます。

f:id:sumtat:20180127153839p:plain

f:id:sumtat:20180127153902p:plain

Fingerprints (CDK)

分子構造の入っているcolumnと、吐き出させたいfingerprintを指定します。今回はECFP4を採用しました。

f:id:sumtat:20180127154058p:plain

 

Partitioning

データを二つに分けます。今回の設定は見ての通り、ランダムに80%(出口▶︎上)と20%(出口▶︎下)に分割します。80%をtrain_dataset、20%をさらに半分にしてvalid_dataset, test_datasetにしています。

f:id:sumtat:20180127154303p:plain

その後、node8, 10, 11のString Manipulationを使って、各datasetにラベルをつけました(column名はsplit)。まあ、この作業はなくてもいいんですけどね。

f:id:sumtat:20180127154905p:plain
f:id:sumtat:20180127154919p:plain
f:id:sumtat:20180127154932p:plain

 

Rondom Forest Learner

f:id:sumtat:20180127155344p:plain

どんな値を予測したいのか?をTarget Columnに指定します。今回は溶解度ですね。で、先ほど出したECFP4を入力に使うのでUse fingerprint attributeにチェックをいれて、columnを指定します。fingerprintからじゃなくて、他のパラメータを入力にしたい場合はUse column attributesにチェックを入れて、下の緑枠内に使うcolumnを入れてください。*1

設定は以上なんですが、設定画面の下の方に(キャプチャでは切れてます。ごめんなさい。)Forest OptionとしてNumber of modelsというのがあります。これを増やせばmodelの数が増えるのでデータ量が多くなった時にも対応できます。

これで実行すると、もう予測モデルが出来上がっちゃいます。

 

Random Forest Predictor

出来上がったモデルに予測させたいデータを当てるノードです。learnerの出口灰色predictorの入口灰色につないでやることでmodelの受け渡しが行われます。modelに当てたいデータはpredictor入力下側▶︎に入れてあげてください。例では上のpredictor(node 4)にvalid_datasetを、下のpredictor(node 12)にtest_datasetを入れています。predictorが2個ありますが、に流しているmodelは同じものなので、両者は全く同じです。

f:id:sumtat:20180127160902p:plain

設定は、予測後の値を入れるcolumn名を決めるだけです。デフォルトのままが嫌ならば、change prediction column nameにチェックを入れて、下の入力欄に好きな名前を指定してあげてください。

 

結果はこんな感じです!

2D/3D Scatterplotを利用して元の値(x)と予測値(y)をplotしました。

f:id:sumtat:20180127161435p:plain
f:id:sumtat:20180127161452p:plain

ちょっと細かいですが、validのr2_scoreが0.6348, testのr2_scoreが0.6982となりました。まあまあではないでしょうか?(ちなみにtrainはr2=0.6558。modelの数を増やしてみましたが、train_scoreは上がりませんでした)。参考になるか否かはわかりませんが、とにかくお手軽です。難しく考えず、ちょっと使ってみてはどうでしょう?

 

おまけ(deepchem, graphconv)

同じデータセットを使って、deepchemのgraphconvolutionを使って同じことをやってみました。

f:id:sumtat:20180127164024p:plain
f:id:sumtat:20180127164228p:plain

 全く同じデータセットです。切り方も同じです。参考までに、train_datasetの最初の方のidを載せておきました。

で、実際に動かしてみた結果がこの後のキャプチャです。コーディングとかほとんどやったことないので、図としてしか貼り付けができませんでした…。

f:id:sumtat:20180127164423p:plain

f:id:sumtat:20180127164518p:plain

私も勉強中なんで、詳細には触れませんがr2_scoreが約0.85。直接比較して良いか微妙ではありますが、こちらの方が良い結果です(ちなみに、パラメータの最適化等はしていません)。こういったスキルも身につけていこうとモチベーションが上がります。

 

しかし!

様々な予測手法・モデルが万能であるとは思っていません。実際に使ってみようと思った時に、

  • どんなdatasetを用意できるか?
  • datasetの切り分け(train, valid, test)は適切か?

などなど、学習前に気にしなきゃいけないことがあると思います。新しい技術を正しく活用できるように理解を深めていければいいなと思っています。また、その上で「どんな場面で活用できるか」をイメージできるようになりたいものです。

 

お手軽簡単法を説明したあとで、"他の方法のが良い結果のでるものがある"というと、使ってみようという気が削がれるかもしれません。しかし、「簡単に使える!アクセスできる!」というのはとても重要なポイントです*2。KNIMEにはRFR以外にも様々な機械学習ノードがあります。色々試してみてはいかがでしょうか?

*1:fingerprintと併用したい場合は、[010]で示されているfingerprint(属性:bit vector)をExpand bit vectorノードを使ってtableのカラムとして展開しちゃえば使えると思います。多分ね。

*2:一応、GPU搭載機を使っています。CPUマシンではちょっとgraphconvは重い気がするので、まず投資が必要だったりします