#author("2024-03-15T15:06:21+00:00","","") #author("2024-03-15T15:06:45+00:00","","") [[技術資料]] * 目次 [#x52bb263] -研究背景 -1節:必要な事前知識(特に4節)についての説明 -2節:環境構築 --Jupyter コードを実行するのに必要 -3節:データ加工 --この研究で用いるデータセットを作成する手順の補足 -4節:数値実験の再現 --データセットのEC番号分類を実行 --必要に応じて,1節を参考 #contents * 研究背景 [#x9ca977e] 有機合成=化合物を合成して目的の有機化合物を生成する(反応の設計) -有機合成では効率性や環境面から化学反応の設計に生体触媒(酵素)が利用される機会が増加 --酵素は化学触媒よりも環境に優しく,特定の反応物に強く作用して化学反応を早く進める -酵素は4桁のEC番号で分類されている -EC番号を機械学習で予測することで,酵素分析(以下)を行う実験コストや時間の削減になる --代謝経路の解析で得られた未知の酵素の性質の特定 --特定の化学反応を触媒する酵素の探索 * 目的 [#sbcb0996] -反応物から生成物に変化する化学反応に用いるべき最適な酵素候補をEC番号として提示する機械学習モデル(EC番号予測システム)の開発 --最適な酵素の探索は合成実験などで行われるが,探索範囲を予測されたEC番号内の酵素製品に絞り込むことができ,実験時間・コストの短縮になる. -代謝経路の探索よりも有機合成に焦点を当ててEC番号を予測する * 1. 事前知識 [#p3465c17] 修論で用いた機械学習・特徴量エンジニアリング手法についての説明 EC番号予測で重要な考えや先行研究の背景などは[[修論研究>武藤/修論研究(22.04-24.03)/最終テーマ]]を参照 ** 多クラス分類について[#f92c088d] -機械学習の分類タスクに該当 -正解クラス(ラベル)が与えられた学習データを正しいクラスに分類する問題を分類器に学習させ,分類モデルを作成 -テストデータを分類モデルに入力し,正しいクラスに分類できるかを評価する -クラスが3種以上ある場合が多クラス分類(2種は2クラス分類) *** 評価指標 [#d9771c12] -混同行列などを用い,Precision・Recall・F1-Scoreで評価するケースがよく見られる -Accuracyでも評価することはあるが,クラスのデータ数に偏りがあると,データの多いクラスの正解率に左右されてしまい,データの少ないクラスの分類精度を適切に評価できない場合がある. --特に酵素反応のEC番号データは偏りが非常に大きいため,F1-Scoreが重要となる #ref(https://dse-souken.com/2021/03/26/ai-15/,,2値分類TP, FPなどの説明) #ref(https://tech-blog.optim.co.jp/entry/2021/05/31/100000,,4評価指標の説明, Precision・Recallのトレードオフについて) #ref(https://dse-souken.com/2021/03/26/ai-15/,,多クラス分類での4評価指標,Macro・Micro F1-Scoreの違い) #ref(METRICS FOR MULTI-CLASS CLASSIFICATION_AN OVERVIEW.pdf,,混同行列からのMacro・Micro F1-Scoreの導出,その他多クラス分類評価指標) ** Random Forests (RF)について [#t71f3b06] 以下のページ参照 [[機械学習と特徴選択]] #ref(【詳解】ランダムフォレスト.pdf,,RF詳細) #ref(RandomForests -Breiman2001_Article.pdf,,RF原著) *** RFを選んだ理由 [#waf148d2] 説明可能な機械学習モデルを用いたため -有機合成の研究者に将来的に利用してもらうため,「なぜそのような予測をしたのか」の説明ができないとシステムの信頼性に欠ける -深層学習などの手法では度々なぜそのような予測をしたのかの説明が難しい(ブラックボックス)場合がある --説明可能にするような手法もある -RFはいわゆる「人の手で出来ないレベルのIF分岐」を行うモデルで,「決定木のそれぞれのノードで特徴量に応じてデータが分類されている」という説明ができる --これはあくまで卒論向けの主張であり,現在はRFよりも良い手法があると考えている -論文参考文献[5]の手法では,深層学習系の多層パーセプトロンで高精度予測しているだけでなく,Shaplay値系の手法を組み込むことで,化合物のどの部分構造がEC番号分類に大きく寄与しているかを説明(可視化)できるようにしている. ** 交差検証について [#i016cfe8] 以下のページ参照 [[データ分割と交差検証]] #ref(https://www.codexa.net/cross_validation/,, 図解交差検証) #ref(https://zenn.dev/monda/articles/kaggle-cv-template,, 層化k分割交差検証について) #ref(https://www.case-k.jp/entry/2021/02/14/155742,, StratifiedShuffleSplit) ** 特徴選択について [#q6dc8839] 以下参照 #ref(https://qiita.com/shimopino/items/5fee7504c7acf044a521#step-forward,, 特徴選択のまとめ) 修論で用いたのはWrapper MethodのStep Forward法 ~ *** Wrapper Method(ラッパー法)の適用について [#i829b1fc] Step Forwardは1つずつ追加,Step Backwardは1つずつ削減,Exhaustive Searchは全パターンの探索 -Exhaustive Search が最もコストが高く,記述子200種では,200C1 + 200C2 + ・・・ + 200C200 通りとなり途方もない -Step backward は初め200で,199, 198, ・・・と閾値まで毎回1種ずつ削除していく --最初200種の記述子を用いてRF分類が実行されるため計算コスト高め -Step Forwardは最適組み合わせを選ぶため,200C1, 199C1, 198C2通り,・・・と閾値まで毎回1種ずつ追加される --1種から始まり,追加されるたび未選択の記述子が減っていくのでコスト低め --修論のデータセットでは20種超えたあたりから評価値が伸び悩むため,閾値30種とした ** オーバーサンプリングについて [#q6dc8839] 不均衡データへの対策 -特徴ベクトルのデータ数はEC番号(クラス)によってバラバラ -データが多いクラス(多数クラス)の方が少数クラスよりも予測しやすい(=不均衡) -少数クラスのデータを増やして不均衡を軽減する *** SMOTE [#g7934d66] -ランダムに増やす手法(Random Over Sampling)は過学習の懸念 -(次元的に距離の近い)同じ少数クラス間に新たにデータを生成する #ref(https://qiita.com/ps010/items/38880fad0b8e71464a54,, SMOTEの種類) #ref(https://qiita.com/eigs/items/8ae0970afe188a1124d1,, SMOTEの種類2) -[[imblearn.over_sampling.SMOTEドキュメント>https://imbalanced-learn.org/stable/references/generated/imblearn.over_sampling.SMOTE.html]]には,SMOTEの拡張手法やアンダーサンプリング手法が豊富に収録している -用いるデータによってはこれらの中から選択する,組み合わせる方が良いのかもしれない -卒論ではBorderlineSMOTE,修論では,SMOTETomekやPipelineモジュールでNearMiss(アンダーサンプリング)とSMOTE(オーバーサンプリング)の組合せを試みたが,上手くいっていない --各ドキュメントのReferences論文を読んで適切な手法を選ぶ ~ //*修論プログラム実装 [#j6bf374b] * 2.1 環境構築 [#lc15b9d6] 本プログラムはAnaconda上で実装する ** Anacondaインストール [#yb5cfc46] [[このページ>https://www.anaconda.com/download#downloads]]からインストール ** rdkitチャネル(仮想環境)の作成 [#s7741da4] *** 仮想環境の補足 [#j491ba9e] -Anacondaは通常"base"と呼ばれるチャネル(仮想環境)を用いるが,新しいチャネル"rdkit"を作る -バージョンが1.0.2(2021年版)のscikit-learnを用いるため,メイン環境として"base",本技術資料のの再現環境として"rdkit"を用いることを推奨 *** 手順 [#d089ce69] WindowsボタンからAnaconda3 → Anaconda Promptを開く バージョン取得 python -V rdkitチャネル作成 # 研究当時のバージョン conda create -n rdkit python=3.8.8 -y ※baseチャネルからrdkitチャネルに変更(Anaconda Prompt) conda activate rdkit rdkitライブラリの導入(pipでは不可) conda install rdkit -c conda-forge jupyterカーネル導入 pip install jupyter environment_kernels jupyter起動 jupyter notebook *** 補足 [#f50ffa62] -Jupyterの画面が通常でないなど,やむを得ない場合は,Anaconda3 → Juputer Notebbok で起動する --この場合,base環境でプログラム実行していく必要があり,scikit-learn=1.0.2にすることで問題が生じる場合は,Jupyter以外の環境で新バージョンの利用を推奨 ~ ** Jupyterのプログラムを起動するとき [#wc6d771f] anaconda promptを起動し,(base)の部分で以下を入力 (base) C:\Users\~~~>activate rdkit base→rdkitに切り替わったら,Jupyter起動 (rdkit) C:\Users\~~~>jupyter notebook -インストールしたモジュールはbaseではなく,rdkitチャネル内のディレクトリに保存される *** プログラムファイルの辿り方 [#fa1d98d9] #ref(jupyter_dir.jpg,,50%) -あらかじめ2.2で「master_ECprediction」をDLし,任意フォルダで解凍する. -ディレクトリを辿って「master_ECprediction」まで行き,「~.ipynb」を起動する * 2.2 プログラム実行の説明 [#lc15b9d6] ** ファイルダウンロード [#t2bc2653] Google Drive 「iie.lab.tpu.1920」の「マイドライブ→OK.IIE.IS.TPU→学生→20_o4武藤」まで行き,保存期間5年の修論(プログラム)の「master_ECprediction」をDLし,任意のフォルダで解凍する. ** 実行するプログラムファイル [#v5632acd] プログラムは3ファイルで構成される. -機械学習に用いるデータセットの作成を行う「ECprediction_dataset.ipynb」 -データセットから多クラス分類モデルを作成し,EC番号予測を行う「ECprediction_model.ipynb」 -数値実験の予備実験1を実行するための「ECprediction_pre1.ipynb」 --上記以外は分類モデルを保存したファイルや,途中結果のデータとなっている ** プログラムの取り扱い説明 [#n3f1d3f5] -プログラムはそれぞれセルで分割されており,1セルずつ順次実行していく --計算に時間がかかる箇所の状態確認が重要のため,通常のPythonファイルとは異なり,あえてプログラムを分割している -セルをクリックし,shift + enterでセル内のプログラムを実行できる --変数名,もしくはprint(変数名)をセルの下部に記載することで変数の中身を確認可能 -初回時は最上セルのpipインストールでモジュールを導入 ~ *** リスタートポイントについて [#f490911f] 途中からプログラムを実行できるようにあらかじめ保存したファイルを読み込み再開できる仕組み -上部セルのimportを実行したあと,任意のリスタートポイントから実行可能('''のコメントアウトを外す) -プログラムを完全再現するのに8日程度かかるため,実行時間が長いセルは飛ばし,最寄りのリスタートポイントから次のセルに進むことを推奨する --実行時間(Intel Core i7-9700K 3.6GHz の場合)を参考にして次に進む --特に各反応式の特性値の計算,記述子選択,パラメータ調整に多大な時間がかかる -リスタートポイントから読み込まれるファイル名の語尾には「0」を記載し,通常実行で保存されるファイルと区別している * 3. モデル構築用データセット作成(ECprediction_dataset.ipynb) [#l4f9e2e9] -各セルでどのような処理を行っているかの大まかな説明はコメントアウトに記載 -以下では,セル実行時の補足を記載 * 3.1 プログラム順次実行 [#ea316bda] 各セルの処理内容は,既に出ている実行結果やコメントアウトで確認 各セルの処理内容は,既に出ている実行結果やコメントアウトで確認 ** モジュールインストール [#hfc41c00] pip install rdkit -バージョンの確認 import rdkit rdkit.__version__ -2022.03.5以降が必須(記述子208→210種類になっている必要) -通常インストールしても上記以前のバージョンならAnaconda側で実行 conda install rdkit -c conda-forge ** 元データセットを1つの化合物SMILESに分解 [#a5bb3bd1] -元データセット((D. Probst, "An explainability framework for deep learning on chemical reactions exemplified by enzyme-catalysed reaction classification", Journal of Cheminformatics, Vol. 15, No. 1, pp. 113, 2023))は,左辺と右辺のSMILESを連結している -左辺と右辺を隔てる'|X.X.X.X>>'と,第1項~第N項を隔てる'.'に着目し,左辺のSMILESリスト,右辺のSMILESリストに分解 --MetaNetXにおけるEC 2.A.3.1などのデータは削除している -2次元配列のleft_sms,right_smsにそれぞれ格納 **特性値計算不可の化合物SMILES削除 [#m55b9397] SMILES形式の化合物から210種の特性値を計算する際,発散値を持つ化合物が存在するため,そのような化合物を除去 リスタートポイント1から5の前までのセル -右辺左辺から全ての化合物(51478個)を抽出し,RDKit構造オブジェクトに変換(~初めの3セル). -1化合物に208種類の特性値を計算し,発散値とnan値を持つ削除化合物リストの作成(~リスタートポイント4) --バージョン依存の関係から2種の記述子を除外して実行 -SMILES反応式の左辺と右辺を走査し,削除化合物リストを含む反応式を除去(~リスタートポイント5手前) 整理された左辺と右辺のSMILES反応式データフレームが出力される(left_smsDF5, right_smsDF5) ** 210次元特徴ベクトルの作成 [#wd61d429] リスタートポイント5から最後までのセル -左辺と右辺のSMILES反応式をRDKit構造オブジェクトに変換(~初めの3セル) --構造オブジェクトでは計算不可の特性値を持つ化合物を検索できないため,検索後もう一度変換 -左辺,右辺それぞれの化合物に対して,210種類の特性値を計算(~リスタートポイント6) --重い処理のため,Jupyter以外のブラウザやプログラムを閉じることを推奨 -左辺の各特性値の和と右辺の各特性値の和の差を取り,210種の特性値変化量を要素に持つ特徴ベクトルを作成(~最後のセルまで) ~ * 4. EC番号分類モデルの作成,テストデータの分類 (ECprediction_model.ipynb) [#n0e19c33] -各セルでどのような処理を行っているかの大まかな説明はコメントアウトに記載 -以下では,セル実行時の補足を記載 ~ * 4.1. モジュールインストール(多クラス分類,SMOTE用) [#z0d5e07f] pip install scikit-learn==1.0.2 pip install imblearn -2021年12月バージョンをインストール --通常インストールすると1.3.2が入る(2024年2月現在に作成したrdkit仮想環境) -分類モデルを圧縮保存した「pickle.gz」が1.0.2で作られており,最新バージョンで読んだ際,以下の互換性エラーが生じるのを回避している [[https://stackoverflow.com/questions/76612971/serialized-machine-learning-model-pickle-on-streamlit-web-app-throws-an-error]] ValueError: node array from the pickle has an incompatible dtype: -今後,1.0.2のモデルファイルが使えなくなった場合は,新バージョンでモデルを再構築する必要あり? * 4.2. データ削減1 [#s82d43e8] 「データ削減」セル1,2 ** SPS記述子の除去 [#nb278521] -計算不可の構造オブジェクトが多いためdrop()で除外 ~ ** 相関係数1の記述子・データの片方削除(下図参照) [#a6823d74] #ref(duplicated_data.jpg,,50%) -全て同じ値になる記述子は過学習の原因のため片方のみ残す --多重共線性などの問題で相関係数が高い特徴量を除外するケースは結構存在する -データも同様に片方のみ残す --クラスのデータ数を減らさないため,あえて違うクラスとして残して予測している研究もあるが,異なるクラスに誤分類される可能性も高まることから,本研究では対象外 ~ *** np.float32の最小・最大値を超える要素を持つ特徴ベクトルの削除 [#v5188b38] -mlxtendの特徴選択を実行すると以下のエラー発生 ValueError: Input contains NaN, infinity or a value too large for dtype('float32') -特徴選択では,float32の値が扱われているようだが,データフレームの特性値は全てfloat64(おそらくPythonのデフォルト)型のため,float32の扱う桁以上の値があるとエラーを出す -float32の許容範囲のデータだけマスクし,それ以外のnp.infをnp.nanにして全て削除 --1.2.の削除化合物リストの中身はnan値限定で,np.inf値のものは対処しきれなかった模様 *** 全ての特性値で0のデータを削除 [#dacebb11] #ref(dropped_all0.jpg,,70%) -どのクラスにも属することができるため除外 --この構造オブジェクト自体が計算不可の可能性 ~ * 4.3. データ削減2 [#i83bf894] 「データ削減」セル最後 ** データ数が5個以下のものを削除する [#c23f895a] -層化5分割交差検証を実行するためにはデータ6個以上必要 -- 6個では学習:テスト = 4:1分割で,学習5個/テスト1個となり,学習データのみに交差検証を行うため -10分割などの場合も,どのクラスもテストデータに最低1個は含まれる必要がある -【未実施】確率で同じデータを抽出する層化シャッフル抽出の場合は学習データが3個でも可能? ~ ** EC番号が3桁目まで存在するクラスのみ抽出 [#g351a74e] -現状のデータはEC T.X.X.X (T=1,2, ... ,7)でラベル付けされている. -本研究では3桁目の予測のため,3桁まで分かっているデータのみ用いる --遺伝子配列の手法では4桁まで予測されており,いずれはフィンガープリント・物理化学特性値でも開発されると予想(or 開発する必要がある) -正規表現のOR演算記法(|)を用い,EC X.X.X.X,EC X.X.X.-,EC X.X.X.S(Sは MetaNetX 固有の文字区別)のデータを抽出する *** 削除するデータ [#a052f6cc] -EC7のデータ(データ数が少ないため) -EC X.-.-.-やEC X.X.-.-などのデータ(1桁分類,1~2桁分類になら使用可能) *** 【懸念事項】ラベル変更によるクラス分布の変動(交差検証) [#g6876c64] 4桁までのクラスで層化抽出したデータを1桁or1~3桁に変更した場合,各クラスの学習データとテストデータの割合は一定かどうか(層化抽出が崩れていないか) -割合を検証したところ,どのクラスも学習75~85%,テスト15~25%で分布していたため,train_test_splitの標準通りと考えられる. -少なくとも4桁の時点で最低5個あるので,3桁クラスでは必ず5個以上ある(5分割可能) * 4.4. 予備実験2 [#t7bd64ac] -本実験に用いる記述子組合せの決定と各分類モデルの精度検証 -1桁目(EC1~EC6),2,3桁目(EC T.X.X (T=1,2, ... ,6))のクラス分類それぞれで,精度を向上させる記述子組合せを選択し,(本実験用に)マージ・重複削除する. ** 学習データ(Xtrain)・テストデータ(Xtest)の分割 [#ja94bc92] この研究では,データのラベル付与が重要となる -初めにEC番号が3桁または4桁まで分かっているデータを学習:テスト=4:1で分割する --分割割合はデータセットに応じて設定 -1桁目分類の際は,学習・テストデータそれぞれでEC番号3,4桁→1桁にラベルを貼り替え --「EC X (1桁目)クラス分類」セクションのセル2を参照 -2,3桁目分類の際は,1桁目がTの学習(テスト)データのみを抽出し,3,4桁→3桁にラベルを貼り替え --「EC 1.X.X (EC 1の2,3桁目)クラス分類」セクションのセル2参照 *** 記述子選択を分けて行う理由 [#c7cf5770] 本来ならラベルの貼り替えなしで,3,4桁のラベルが付いた状態で,1~3桁目 or 1~4桁目のクラス分類(記述子選択)を行う方が効率的 -【時間的な制約】Xtrainに対し交差検証で1~3桁目分類する場合,実行時間が75時間以上(その間PCオーバフローの懸念)推定されていた.(37672データ,148クラス) --4桁目までの分類となるとクラス数が増加し,さらに時間を要する --EC X分類(37672データ,6クラス),EC 1.X.X(6380データ,64クラス)と分けて分割することで,実行負担を減らせる -【先行研究と同様】タンパク質配列を用いた手法((N. Watanabe, et al, "EnzymeNet: residual neural networks model for Enzyme Commission number prediction", Bioinformatics Advances, Vol. 3, No. 1, 2023.))では,1桁目を分類した後,2~4桁目を分類するモデルが作成されており,その方法に倣った. --実際,テストデータを1桁目分類モデルに入力し,正解したデータのみ2,3桁目分類モデルに入力して,正解したデータ数を調べることも可能だが,この研究では行っていない #ref(Xtrain_dist.jpg,,70%) *** 予備実験2の意義 [#l13256f0] 本実験をやるだけなら記述子選択で終了し,グリッドサーチとテストデータの分類精度を確認する必要はない -わざわざ,7つそれぞれの分類精度を確認しているのは,逐次予測を想定していたため --1桁目予測→正解したデータだけ EC T.X.Xモデルに入力して分類精度を確認する方法(先行研究と同様) -1~3桁を同時に高精度で分類する記述子(本実験)よりも,1桁のみを高精度で分類するための記述子(分類モデル) + 2,3桁目のみを高精度で分類する記述子(分類モデル)と分けた方が,予測精度が向上する可能性がある --一方で,1桁目で外れたデータは除外されるので,本実験よりもテストデータが少なるという欠点もある ** EC X (1桁目)クラス分類 [#r3042a19] -学習時間を考慮して1桁目のみ25種まで選択する -SMOTEなしで記述子選択を行う --SMOTEなしでも18時間要する & 高精度なため #ref(XtrainX_dist.jpg,,70%) ** EC T.X.X (T=1,2, ... ,6) 分類 [#hf35e2ae] SMOTEありの記述子選択 -SMOTEとRF分類を連続で行うPinelineを作成し,記述子選択(SFS)インスタンスの引数にしている -交差検証の1~5分割目それぞれの検証用学習データのみオーバーサンプリングし,RF分類モデルを作るような形式となっている *** 補足 [#ie6c52aa] -7つのクラス分類いずれも,最上部セルのモジュールを読み込み,リスタートポイント1.0から実行することで,「EC 〇 クラス分類のセクションから実行できる」 --適宜,記述子選択後の結果から始める「リスタートポイント1.1」,グリッドサーチ後から始める「リスタートポイント1.2」などを用いる * 4.5. 本実験 [#r5f0fa24] ** 7回分の記述子リストのマージ & 重複削除 [#o17bf547] 30種までの記述子選択で,F1-Scoreが4回未更新になる直前の記述子リストをマージ -記述子数が20を超えた時点でスコアが増加しにくいケースが多く,精度が向上しないうえに記述子リストが冗長(過学習の懸念)となるのを防いでいる 重複を削除するset()は起動の度に記述子の並びが変わり,予測精度が変動する(再現性なしになる)ため,あえて実験当時の並びを読み込んでいる -Random Forestsの構造上,精度の変動は仕方ないと思っている ** 1~3桁目分類のパラメータ調整 [#bb21fcd1] 分割した学習データとテストデータをマージし,グリッドサーチ -7回分のグリッドサーチの結果から,大きめのパラメータを設定 -実行時間が約51時間かかるうえ,PC動作が非常に重くなるので,Jupyterホーム画面と,プログラム画面以外のプログラムを全て閉じて,待機することを推奨 ** 1~3桁目分類 結果について [#u1769669] -weighted avgは少数クラスのスコアを重み付けした結果(全クラス平均) -macro avgはどのクラススコアも平等に平均した結果 --研究として評価するなら,厳しい方のmacro avg F1-Scoreを用いるのが妥当 ~ *本技術の応用先 [#n168166c] [[修論研究の「修論の改善点と応用」>武藤/修論研究(22.04-24.03)/最終テーマ]]を参照(1番最後の研究会資料や修論5章考察,6章なども)