0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

理学療法士がKaggleで脳卒中予測に挑戦した話|EDA〜ロジスティック回帰まで

0
Posted at

理学療法士がKaggleで脳卒中予測に挑戦した話|EDA〜ロジスティック回帰まで

はじめに

理学療法士として急性期病院で2年、地域医療の現場で6年働いてきました。公衆衛生学修士(MPH)も取得していますが、普段使わないのでほぼ忘れています。現在はIT企業に勤務しています。(データ分析歴3ヶ月)

データ分析を始めた理由はシンプルで、「なんかかっこいいと思った」からです。せっかくやるなら医療データで、将来はヘルスケア分野に関わりたいと思っています。そのはじめの一歩としてこのテーマを選びました。

Pythonは初心者です。つまずいたところも含めて、正直に記録します。


データ概要

使用したのはKaggleのStroke Prediction Dataset(fedesoriano)です。

  • 行数:5110件
  • 列数:12列
  • 目的変数:stroke(0: 脳卒中なし / 1: 脳卒中あり)
  • 脳卒中あり:249件(約5%)→ 不均衡データ

EDA(探索的データ分析)

まずデータの基本的な確認から始めました。

df.shape
df.dtypes
df.describe()
df.isnull().sum()

気づいたこと:数値型でもカテゴリとして扱うべき列がある

hypertensionheart_diseaseは0/1の数値ですが、意味はカテゴリです。df.nunique()でユニーク数を確認すると見抜きやすいです。

血糖値271を外れ値と切り捨てなかった理由

avg_glucose_levelはmean=106、75%=114に対してmax=271と乖離が大きく、外れ値を疑いました。ただし血糖値271は糖尿病として臨床的にあり得る値です。医療データの外れ値はドメイン知識で判断する必要があると学びました。


前処理

欠損値の補完

欠損があったのはbmi列のみ。中央値で補完しました。

df['bmi'] = df['bmi'].fillna(df['bmi'].median())

平均値ではなく中央値を選んだのは、外れ値の影響を受けにくいからです。迷ったら中央値が安全、と覚えました。

カテゴリ変数のエンコーディング

df = pd.get_dummies(df, drop_first=True)

drop_first=Trueにする理由は、全列残すと情報が重複して(多重共線性)モデルが不安定になるからです。落とした列が基準(ベースライン)になります。最初はここの意味がわかりませんでした(何だこれ。。?)。


モデル構築と評価

層化5分割交差検証でロジスティック回帰を評価しました。

skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
model = LogisticRegression(random_state=42, max_iter=1000, class_weight='balanced')

class_weight='balanced'なし→ありで結果が激変した

Recall Precision F1
balancedなし 0.004 - -
balancedあり 0.795 0.134 0.229

balancedなしはほぼ全員をstroke=0と予測していました。不均衡データでは何もしないと多数派に引っ張られます。

Recall=感度、Precision=PPVとして読む

医療スクリーニングの文脈では、Recall(見逃さない力)を重視します。疫学でいう感度と同じ考え方です。Recall0.795は「脳卒中の約80%を拾えている」と解釈できます。


つまずいたところ

初心者丸出しのミスを残します。

  • isnullisnull()の違い → ()をつけないと関数が実行されない。属性は()不要、メソッドは()必要。
  • df('bmi')ではなくdf['bmi'] → 列の取り出しは角括弧。
  • One-Hot Encodingで順序を振ると、存在しない大小関係をモデルが学習してしまう。
  • 不均衡データでAccuracyを使うと、全員0と予測しても95%になる。最初はこれに気づかなかった。

次のステップ

ベースラインとしてロジスティック回帰まで完成しました。次はこの2点に取り組む予定です。

  1. 特徴量エンジニアリング:新しい特徴量の作成、予測に効かない変数の除外
  2. モデルの変更:決定木、ランダムフォレスト、LightGBMなどを試す

続きは別の記事で書きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?