
【前処理編】肺のCT画像からCOVID19かどうかの判断は可能か?【機械学習】
2021.12.20
前処理編~肺のCT画像からCOVID19か予想できるのか?

今回は、肺の CT 画像から、COVID 19か否かを予測する深層学習モデルを、「PyTorch」で実装してみたいと思います。
PyTorch を採用した理由は、「Kaggle」での実装例も多く、公式ドキュメントも充実しているためです。
というわけで、Kaggle に公開されているデータセットを用いて、「二値分類」をしていきたいと思います。
実行は、すべて Kaggle の notebook 上で行っているので、自宅にGPUがない方でも、すぐに試すことができます。
ちなみに、こちらの記事は「プログラミングで分類に挑戦する」ということが目的で、COVID 19を確実に分類できるわけではありませんので、予めご了承をお願い致します。
データの下見と前処理
今回使用するデータセットは、「COVID 19の画像」と「そうではない画像」とで、フォルダ分けして与えられています。
DataFrameにまとめる
使いやすいよう、「Pandas」のデータフレームに、まとめておくことにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #make dataFrame import pandas as pd import glob import os os.chdir('/kaggle/input/computed-tomography-of-lungs-datase-for-covid19') train_posi=glob.glob('CODE19 Data/Training Data/Covid/*') train_nega=glob.glob('CODE19 Data/Training Data/Non Covid/*') test_posi=glob.glob('CODE19 Data/Testing Data/Covid/*') test_nega=glob.glob('CODE19 Data/Testing Data/Non Covid/*') train_df_posi=pd.DataFrame(columns=['filename',"covid"]) train_df_posi["filename"]=train_posi train_df_posi["covid"]=1 train_df_nega=pd.DataFrame(columns=['filename',"covid"]) train_df_nega["filename"]=train_nega train_df_nega["covid"]=0 train_df=pd.concat([train_df_nega,train_df_posi]) tes_df_posi=pd.DataFrame(columns=['filename',"covid"]) tes_df_posi["filename"]=test_posi tes_df_posi["covid"]=1 tes_df_nega=pd.DataFrame(columns=['filename',"covid"]) tes_df_nega["filename"]=test_nega tes_df_nega["covid"]=0 test_df=pd.concat([tes_df_nega,tes_df_posi]) #reset_index train_df = train_df.reset_index(drop=True) test_df = test_df.reset_index(drop=True) |
以下のように、「covid」の列が疾患か否かを示しており、疾患である場合のラベルは「1」です。

1 2 3 4 5 6 7 8 9 10 11 12 | train_df["covid"].describe() >>> count 746.000000 mean 0.467828 std 0.499299 min 0.000000 25% 0.000000 50% 0.000000 75% 1.000000 max 1.000000 Name: covid, dtype: float64 |
「train」「test」ともに、COVID 19である割合は、5割ほどで乖離はなさそうでした。
画像をみてみる
画像分類をするとき、「何枚かの画像は、自分の目で見る」ということが大事です。
特に医療画像では、作成された過程などにより、かなりの差異が生じます。
たとえば、下の3枚の画像が似ていないことは、明らかですね。



また、画像のサイズも、均一ではなさそうです。
この差をなくすために、前処理が一般的に必要とされていますが、今回はお試しなので割愛します。
ちなみに COVID 19では、肺の部分が、白く抜けたようになります。
交差検証をする
機械学習モデルの作成において大事なことは、「特徴量生成」や「どのモデルを使うか」より、適切な Validation をとることだ。
という金言があるように、データの分け方を考えることは、かなり重要です。
とりあえずの層化抽出
今回は、「正例」と「負例」との割合と、fold ごとに等しくする層化抽出を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 | if CFG.debug: folds = train_df.sample(n=200, random_state=CFG.seed).reset_index(drop=True).copy() else: folds = train_df.copy() train_labels = folds[CFG.target_col].values kf = StratifiedKFold(n_splits=CFG.n_fold, shuffle=True, random_state=CFG.seed) for fold, (train_index, val_index) in enumerate(kf.split(folds.values, train_labels)): print("num_train,val",len(train_index),len(val_index),len(val_index)+len(train_index)) print(max(train_index)) folds.loc[val_index, 'fold'] = int(fold) folds['fold'] = folds['fold'].astype(int) folds.head() |
メタデータが与えられている場合なら、他の分け方を考えても良いと思います。
CT 画像の形式としてよくある「DICOM データ」では、患者 ID が付随している可能性が高いです。
この場合は、「GroupKFold」を用いることが、選択肢となります。
理由は、同じ患者の画像が別の fold に混ざることで、不当に精度が上がることを防ぐため。
同じ患者であれば、「画像が似ている」か「同じ疾患を持っている」、という判断もできます。
準備編へつづく!
こちらの記事は、【準備編】へつづきます。
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン
ITエンタメ7月 14, 2023【クリス・ワンストラス】GitHubが出来るまでとソフトウェアの未来