Logistic回帰~cancer~Pythonではじめる機械学習より

モデルの精度

breast_cancerデータセットに対してscikit-learnLogisticRegression適用し、訓練データとテストデータのスコアを計算してみる。

(注)solverに関する警告と計算結果

上のコードを実行したとき、結果は書籍と整合しているが、警告表示が出た

この時点でscikit-learnのバージョンが古く(0.21.3)、将来のデフォルトが変更されるとのこと。そこでインスタンス生成時にデフォルトのソルバーを明示的にsolver='liblinear'と指定して実行すると、警告は出ず値もそのまま。

なお、solver='lbfgs'としてみたところ、計算が収束しない旨の警告が出た。

そこで収束回数を増やしていったところ、最大回数2000では収束せず、3000で収束し、警告は出なくなった。

その後、scikit-learnのバージョンを0.23.0にアップグレードしたところ、デフォルトで警告は表示されず、収束回数に関する警告が同じように出て、結果も再現された。以下、ソルバーとしてliblinearを明示的に指定し、random_stateの値も書籍と同じ値として確認する。

学習精度の向上

先のC=1.0liblinearによるスコアは、訓練データに対して0.953、テストデータに対して0.958と両方に対して高い値となっている。ここで、訓練データとテストデータのスコアが近いということは、適合不足の可能性がある。そこでC=100と値を大きくして、より柔軟なモデルにしてみる(柔軟なモデルとは、正則化を弱めて訓練データによりフィットしやくしたモデル)。

訓練データ、テストデータともそれぞれ若干向上している。なお、Cの値を1000、10000ともっと大きくしてもスコアはほとんど変わらない。

今度は逆に、Cの値を1.0より小さくして正則化を強めてみると、訓練データ、テストデータ両方に対するスコアが下がってしまう。

Cを変化させたときの学習率曲線は以下の通り。Cが10より小さいところでは正則化が強く学習不足、そこを超えると学習率が頭打ちで、学習率の改善はそれほど顕著ではない。

特徴量の係数

L2正則化の場合

breast_cancerデータセットに対してLogisticRegressionを学習させた場合の、30個の特徴量に対する係数をプロットする。liblinearソルバーで、デフォルトでL2正則化を行っている。Cの値が大きいほど正則化の効果が弱く、係数の絶対値が大きくなっている。

書籍で注意喚起しているのは3番目の特徴量mean perimeterで、モデルによって正負が入れ替わることから、クラス分類に対する信頼性を問題にしている。

ここで書籍について以下の点が気になった。

  • logreg001のインスタンス生成時にC=0.01としているが、凡例で”C=0.001″としている(グラフの結果はあまり変わらない)
  • logreg100C=100とすると、書籍にあるような結果にならない(worst concave pointsが-8以下になるなど、分布が大幅に変わってくる)
  • C=20とすると、概ね書籍と同じ分布になる(若干異なる部分は残る)

いずれにしても”Pythonではじめる機械学習”は、入門者にとってとてもありがたいきっかけを提供してくれる良著であることに変わりはない。

L1正則化の場合

ソルバーを同じliblinearとして、penalty='l1'と明示的に指定する。今回はL2正則化の時と違って、C=0.001はコード中に明示され、C=100としてスコアの計算結果まで合う。ただしset_ylim()によって表示範囲を制限しており、C=100に対するいくつかの点が枠外にある。

L1正則化によって、多くの係数がゼロとなり、少ない特徴量によるシンプルなモデルでそれなりのスコアを出している。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です