アメリエフの技術ブログ

Amelieff Staff Blog

【機械学習】乳がんのデータセットから悪性か良性か予測する【Python】

こんにちは、受託コンサルティングチームの hosor です。

じわじわと暑くなってきたので、最近はサーキュレーターを扇風機代わりに使っています。


バイオデータに対して機械学習を使ってみたいものの、なんだか難しそうで手が出ないという方も多いのではないでしょうか。

今回は、必要最小限のスクリプトで乳がんのデータセットから悪性か良性か予測 (分類) していこうと思います。

ブログを通じて、意外と難しくないと思っていただけますと幸いです!

分類

作業環境

  • CentOS Linux release 7.4.1708 (Core)
  • Python v3.12.0
    • pandas v2.2.2
    • scikit-learn v1.5.0

使用データ

scikit-learn で提供されている、569 サンプル分の乳がんの診断データを使用しました。

各サンプルには 30 種類のがんの特徴量 (がんの大きさや色など) と、がんが悪性か良性か (悪性: 0, 良性: 1) の診断結果が含まれています。

データの詳細については公式ドキュメント*1や、日本語記事*2の解説が充実しているので、興味がある方はそちらをご参照ください。

スクリプト

まず、必要なライブラリなどを読み込みます。

import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score


次に、乳がんのデータセットを読み込みます。

また、30 種類のがんの特徴量を X_df に、がんが良性か悪性かの診断結果を y_df に格納します。

同時にそれぞれの中身の確認もしておきます。

data_breast_cancer = load_breast_cancer()
X_df = pd.DataFrame(data_breast_cancer["data"], columns = data_breast_cancer["feature_names"])
y_df = pd.DataFrame(data_breast_cancer["target"], columns = ["target"])

print(X_df)
     mean radius  mean texture  mean perimeter  mean area  mean smoothness  ...  worst compactness  worst concavity  worst concave points  worst symmetry  worst fractal dimension
0          17.99         10.38          122.80     1001.0          0.11840  ...            0.66560           0.7119                0.2654          0.4601                  0.11890
1          20.57         17.77          132.90     1326.0          0.08474  ...            0.18660           0.2416                0.1860          0.2750                  0.08902
2          19.69         21.25          130.00     1203.0          0.10960  ...            0.42450           0.4504                0.2430          0.3613                  0.08758
3          11.42         20.38           77.58      386.1          0.14250  ...            0.86630           0.6869                0.2575          0.6638                  0.17300
4          20.29         14.34          135.10     1297.0          0.10030  ...            0.20500           0.4000                0.1625          0.2364                  0.07678
..           ...           ...             ...        ...              ...  ...                ...              ...                   ...             ...                      ...
564        21.56         22.39          142.00     1479.0          0.11100  ...            0.21130           0.4107                0.2216          0.2060                  0.07115
565        20.13         28.25          131.20     1261.0          0.09780  ...            0.19220           0.3215                0.1628          0.2572                  0.06637
566        16.60         28.08          108.30      858.1          0.08455  ...            0.30940           0.3403                0.1418          0.2218                  0.07820
567        20.60         29.33          140.10     1265.0          0.11780  ...            0.86810           0.9387                0.2650          0.4087                  0.12400
568         7.76         24.54           47.92      181.0          0.05263  ...            0.06444           0.0000                0.0000          0.2871                  0.07039

[569 rows x 30 columns]

print(y_df)
     target
0         0
1         0
2         0
3         0
4         0
..      ...
564       0
565       0
566       0
567       0
568       1

[569 rows x 1 columns]


乳がんのデータセットを、訓練データとテストデータに分割します。

訓練データはモデルを学習させるために使うデータで、テストデータはモデルを評価するために使うデータです。

ここでは、訓練データ数:テストデータ数=7:3 になるように分割しています。

X_train, X_test, y_train, y_test = train_test_split(X_df, y_df, test_size = 0.3, random_state = 0)


そして、訓練データを用いてモデルを学習させます。

今回はランダムフォレストというアルゴリズムを使用しています。

ものすごくざっくり説明すると、「がんの大きさが 〇〇 以下で、がんの色合いが ×× 以下なら良性と判定する」のような条件分岐を大量に作って予測するようなアルゴリズムです。

ランダムフォレストの呼び出し、訓練データを用いた学習、テストデータに対する予測を行います。

rf_model = RandomForestClassifier(random_state = 0)
rf_model.fit(X_train, y_train)
y_pred = rf_model.predict(X_test)


最後に、予測結果と実際の診断結果を比べて、正解率を計算します。

accuracy = accuracy_score(y_test, y_pred)
print("Accuracy: {}".format(accuracy))
Accuracy: 0.9590643274853801


正解率が約 96 % であることが分かりました!

つまり、30 種類のがんの特徴量があれば、悪性か良性かをほぼ間違いなく判定できるということになります。

今回はすごくシンプルなモデルで学習と予測を行ったのみですが、実際には以下のような手順で進めていくことが多いです。

  • 探索的データ分析
  • 特徴量エンジニアリング
  • アルゴリズム手法の選択
  • モデルの学習・予測
  • ハイパーパラメータチューニング
  • モデルの評価

バイオデータの機械学習に関することでお困りごとがあれば、ぜひアメリエフにお声がけください!