python sklearn でロジスティック回帰。fit して predict、引数 C で正則化


簡単なデータでロジスティク回帰を試してみます。やるのは2クラスの分類ですが、理論的なことはとりあえず置いといて、 python の scikit-learnライブラリ を使ってみます。このライブラリの
LogisticRegression というクラスがロジスティック回帰です。

メソッド fit、predict、score、属性 coef_、intercept_、パラメータ C を使ってみました。

- 目次 -

スポンサーリンク

データ

データとして、二次元正規分布のかたまりを 2 組つくっておきます。

区分が 0 のデータを 50個1 のデータを 50個 用意し、訓練データとテストデータを 7:3 に分割します。

下記はプロット結果。×訓練データテストデータ です。

ロジスティック回帰 データ

訓練

訓練は LogisticRegression のメソッド fit にデータを渡すだけです。

訓練終了。

では、訓練したモデルにテストデータを当てはめてみます。分類は predict、精度の確認は score メソッドで行います。

精度は 96.7 %。残念ながら 100 % に届きませんでしたが、この精度はパラメータ C を指定することで変化します(後述)。

プロット

ロジスティック回帰の訓練結果は境界線

\(w_0+w_1x+w_2y=0\)

の 重み \(w_0\)、\(w_1\)、\(w_2\)ですが、その値は属性 intercept_coef_ に入っています。値を取得し、境界線をプロットしてみます。

ロジスティック回帰 結果

精度が 96.7 %でしたが、確かに、テストデータ 30個のうち 1個のデータ(青丸)が境界線をはみ出しています。

C を指定

C を指定することで精度が変化すると書きました。実際にやってみます。C はデフォルトで 1.0 とされており、ここでは 10、100、1000 で試してみます。

ロジスティック回帰 結果

C を変化させると境界線が徐々に変化し、C=1000 で精度 100% の位置を探し当てています。以下は、それぞれの C で導き出された 重み です。

C
1.0
10.0
100.0
1000.0
w_0
0.1331
0.00025
-0.35115
-0.85447
w_1
1.821
3.76
8.465
19.084
w_2
2.268
4.133
6.673
10.556

C が大きくなるにつれて w_1w_2 が大きくなっています。C とは一体何でしょうか?

C は正則化のパラメータ

LogisticRegression の正則化は、デフォルトの場合、L2正則化です。L2正則化では、コスト関数

\(J(\mathbf{w})=\sum_{i=1}^n \Bigl[ -y^{(i)} log \big( \phi \big(z^{(i)}\big) \big)- \big(1-y^{(i)}\big)log \big(1-\phi \big(z^{(i)} \big) \big) \Bigr] \)

に対して、正則化項

\( \large{\frac{ \lambda }{2}} \ \normalsize{\sum_{j=1}^m w^2_j} \)

が付加されます。ここで \(\lambda\) を指定して正則化の強さを指定しますが、LogisticRegression では \(\lambda\) の代わりに C を指定します。C と \(\lambda\) は

\(C=\large{\frac{1}{\lambda }}\)

の関係にあり、コスト関数はこうなります。

\(J(\mathbf{w})=\sum_{i=1}^n \Bigl[ -y^{(i)} log \big( \phi \big(z^{(i)}\big) \big)- \big(1-y^{(i)}\big)log \big(1-\phi \big(z^{(i)} \big) \big) \Bigr] +\large{\frac{1}{2\bf{C}}} \ \normalsize{\sum_{j=1}^m w^2_j}\)

C の値を大きくすると正則化が弱くなり、その結果、重みが大きくなったのが先のサンプルです。

スポンサーリンク

コメントはお気軽に