Pythonの機械学習入門(4)~乳癌の症状をk近傍法で判定

Pythonの機械学習ライブラリ「scikit-learn」の使い方を簡単に説明します。今回は機械学習を用いて乳癌の症状を判定します。

乳癌データの入手

先ずは、機械学習で使用する乳癌データを入手します。今回はscikit-learnに内蔵されているデータセットを使用します。

使用するのは乳癌の細胞核に関する特徴データです。データのレコード数は569、カラム数は30です。

データには下記のような項目が存在します。今回は乳癌が「悪性腫瘍」か「良性腫瘍」かを判定します。

a)半径(中心から周囲の点までの距離の平均)
b)テクスチャ(グレースケール値の標準偏差)
c)周囲
d)面積
e)滑らかさ(半径の長さの局所的変化)
f)コンパクト性
g)凹み(輪郭の凹部の程度)
h)凹点(輪郭の凹部の数)
i)対称性
j)フラクタル次元

※https://goo.gl/U2Uwz2より引用

データの読込み

# 乳癌データの読込み
cancer = load_breast_cancer()

データの読込みはscikit-learnのdatasets内のload_breast_cancer関数を使用します。

特徴量データと教師データに分離

# 特徴量データと教師データに分離
X = cancer.data
y = cancer.target

データを特徴量データ教師データに分離します。Xは特徴量データで、569×30の行列データです。これは、30の特徴量から成るレコードが569個あることを意味します。

yは教師データで、569×1の行列データです。これは、乳癌の症状(悪性「0」、良性「1」)のレコードが569個あることを意味します。

教師データの乳癌の症状(悪性「0」、良性「1」)を「ラベル」と呼びます。以降で、乳癌に関する30の特徴量に応じて、乳癌の症状を判定することになります。

※cancer.dataは乳癌に関する30の特徴量データ、cancer.targetは乳癌の症状データが格納

学習データとテストデータに分割

# 学習データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

機械学習の性能を検証するために、学習に使用するデータセット(X_train、y_train)と、テストに使用するデータセット(X_test、y_test)に分割しておきます。

今回は学習データ:テストデータ=8:2にしました。比率はパラメータのtest_sizeで自由に設定できます。テストデータは慣習的におよそ20~25%くらいに設定します。

モデルの学習

# モデルの学習
pipe = Pipeline([('pre', StandardScaler()), ('est', KNeighborsClassifier())])
pipe.fit(X_train, y_train)

今回は乳癌の症状を判定するために、k近傍法(K Nearest Neighbor)の学習アルゴリズムを使用しました。

機械学習の分類のアルゴリズムはいくつかあり、データ数やデータの特性に応じて最適なものを選択する必要があります。

※k近傍法はデータ間の距離を算出することで、距離が近いk個のデータのラベルをもとに判定を行うアルゴリズムです。

なお、今回は各データ項目の単位やスケールがそれぞれ異なるため、上手く機械学習させるためにデータの前処理を行う必要があります。

そこで、データの前処理とモデルの学習を一括で行う「パイプライン」という仕組みを使用しました。

データの前処理には「標準化(StandardScaler)」を、学習アルゴリズムには「k近傍法(K Nearest Neighbor)」を設定しました。

次にfitメソッドにて学習データセットを与えて学習させます。

これで、学習済みの「モデル」(または「学習器」)が完成しました。以降は、このモデルを用いて性能を評価したり、未知のデータに対する予測を行います。

※標準化の式は「(x – μ)/ σ」(x:データの値、μ:平均、σ:標準偏差)

モデルの性能評価

# モデルの性能評価
y_pred = pipe.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print ("正解率 = ", accuracy)

ここで、学習済みのモデルの性能を評価します。新しいデータセットに対して、乳癌の症状をどれだけ正しく判定できるかを確認します。

predictメソッドにて特徴量のテストデータを与えて、予測した乳癌の症状をy_predに保存します。

そして、accuracy_scoreメソッドでy_predと、実際の乳癌の症状データy_testの正解率を算出します。値は0~1で、1は100%合致していたことを意味します。

ソースコードを実行する度に、accuracyの値が変化します。これは、学習データとテストデータに分割したtrain_test_splitメソッドがランダムにデータを分割するからです。

概ね0.9~1の値になると思います。かなり高い正解率を出すことに成功しています。

accuracy score

未知のデータの予測

# 未知のデータの予測
data = pandas.read_csv('unknown_data.csv')
X_pred = data.iloc[:, :].values
y_pred = pipe.predict(X_pred)

if y_pred == 0:
    result = "悪性腫瘍"
elif y_pred == 1:
    result = "良性腫瘍"

print ("判定結果は「", result, "」")

上手く学習できたモデルを使って、実際に未知のデータを予測してみましょう。実際のレコードに近い30の特徴量の値を入力したレコードを1つ作成します。

今回は下記のようなCSVファイルからレコードを読込みました。

unknown data

そして、predictメソッドにて乳癌の症状を判定しました。

実行結果を表示させると、判定された症状を取得することができました。実際のレコードと同じ症状が得られたと思います。

predict unkown

まとめ

今回はPythonの機械学習ライブラリ「scikit-learn」を使用して、乳癌の症状を判定するモデルを作成しました。

押さえておきたいポイントとしては、

  • データを「特徴量データ」と「教師データ」に分離した
  • モデルの性能を評価するために、「学習データ」と「テストデータ」に分割した
  • 上手く学習させるためにデータの前処理(標準化)を行った
  • 学習済みのモデルを使って、「未知のデータ」に対して判定を実行した

参考文献

Breast Cancer Wisconsin (Diagnostic) Data Set
(https://goo.gl/U2Uwz2)