乳がんデータについて理解できたので、ロジスティック回帰で分類してみるよ。
どんなふうになるか楽しみだね。
前回、scikit-learnの乳がんデータの構成を確認しました。今回は、ロジスティック回帰を利用して、乳がんデータの分類をしてみたいと思います。
前回の乳がんデータの構成についてはこちらを参照ください。
こんな人の役に立つかも
・機械学習プログラミングを勉強している人
・scikit-learnで乳がんデータの分類をしたい人
・ロジスティック回帰で乳がんデータを分類したい人
ロジスティック回帰で分類
今回は、ホールドアウト法(train_test_split)で訓練データとテストデータに分けた後、訓練データを利用して3分割の交差検証(cross_val_score)にてスコアを求めます。その後、ロジスティック回帰に訓練データを訓練させ、最後にテストデータで評価する、という流れでいきます。
この流れにつきましては、以下の記事の「train_test_splitを導入してワークフローを見直す」で説明していますので、ご参考ください。
まずはimportから
毎回やっていますが、一応1記事の中で順番に実行できると便利だと思うので、書かせていただきますm__m
#ホールドアウトのimport
from sklearn.model_selection import train_test_split,cross_val_score
#乳がんデータ
from sklearn.datasets import load_breast_cancer
#ロジスティック回帰
from sklearn.linear_model import LogisticRegression
import numpy as np
panda_box = load_breast_cancer()
X = panda_box.data
y = panda_box.target
scikit-learnの乳がんデータを、訓練データとテストデータに分割します。さりげなく25%の訓練データ量に変更しています。デフォルトでtrain_test_splitは25%なので、このパラメータは省略が可能です。
#訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, stratify=y)
今回、乳がんデータの分類は初めてなので、訓練データがstratifyになっているかどうかを確認してみます。
stratifyについて不明な方は、こちらの記事で取り上げていますのでご参考ください。
#訓練データとテストデータがstratifyであることの確認
print("訓練データのラベル「0」の割合")
print("{:.2f}" .format(y_train[y_train==0].shape[0]/y_train.shape[0]))
print("テストデータのラベル「0」の割合")
print("{:.2f}" .format(y_test[y_test==0].shape[0]/y_test.shape[0]))
numpyは、配列の中に条件を書くことで、その条件に該当するデータのみを取り出した配列にすることができます。「y_train[y_train==0]」とすることで、値が0のみのデータのインデックスを指定した配列にすることができます。
.shapeは、配列のデータ個数を表示するもで、今回利用する2次元配列は(行,列)のように表示されます。そのため、shapeの[0]番目のデータには、(行,列)の「行」の値が入っています。
なので、「y_train[y_train==0].shape[0]」は「値が0のデータの個数」が入っていることになります。「y_train.shape[0]」は、すべてのデータの個数なので、分母とすることで値が0のデータが全体の何割なのかを求めることができます。
テストデータでも同様に値が0のデータの割合を表示しています。
小数2桁までの表示で、訓練データ、テストデータともに37%の割合で答えが0のデータとなっていることがわかりました。stratifyになっています。
訓練データのラベル「0」の割合
0.37
テストデータのラベル「0」の割合
0.37
stratifyになってますな
ロジスティック回帰で分類
ロジスティック回帰を訓練データで、交差検証します。
交差検証についてはこちらの記事をご参考ください。
#ロジスティック回帰
cls = LogisticRegression(max_iter=10000)
#3分割で交差検証を行う。
score = cross_val_score(cls, X_train, y_train, cv=3)
print("交差検証の結果")
print(score)
print("交差検証の平均")
print("{:.4f}".format(np.mean(score)))
#訓練~テスト
cls.fit(X_train,y_train)
print("テストデータの評価")
print("{:.4f}".format(cls.score(X_test, y_test)))
ロジスティック回帰のパラメータ「max_iter」の指定は以下のワーニングがでたので追加しました。
ConvergenceWarning: lbfgs failed to converge (status=1):STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
機械学習が訓練をするとき、ちょうど良い感じに分類できる境界の式を求めるために、何回も訓練データを試して、ちょうど良い式の係数というものを求めていきます。
その時に、最大の繰り返し回数まで繰り返してもちょうど良い係数が見つからなかった・・・というものらしいです。なので、最大繰り返し回数を10000回にしてみました。今回は運よく10000回までの繰り返しで係数が求められたみたいです。
10000回まで試していいよ、と言っているため、処理が少し長くなりました。
交差検証の結果
[0.93661972 0.94366197 0.93661972]
交差検証の平均
0.9390
テストデータの評価
0.9790
まとめ
乳がんデータに対して今まで学んだホールドアウトや交差検証を利用してロジスティック回帰で分類を行うことができました。何となく分類問題に対する理解も深まってきました。実は、ロジスティック回帰などのアルゴリズムがどのように訓練をしているかなど、いろいろ勉強しているのですが、いまいち腑に落ちた感がないのが現状です^^;
scikit-learnを利用すれば、手順さえちゃんと整えれば、ブラックボックスに機械学習アルゴリズムを利用できてしまうのですが、やはりどのように動作しているのか知りたいところです。