Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで学ぶロジスティック回帰:基礎から実装・結果の解釈まで徹底解説

ロジスティック回帰とは

ロジスティック回帰(Logistic Regression)は、二値の結果(合格/不合格、はい/いいえなど)を予測するための統計手法です。金融、医療、犯罪学をはじめとする社会科学など、幅広い分野で長年にわたり活用されている実績あるアプローチです。

本記事では、Pythonを使ってロジスティック回帰を実装する方法を解説します。なお、同じ処理はRなどの他の言語でも実装可能です。

必要なライブラリのインストール

サンプルプログラムでは、以下のライブラリを使用します。

  • NumPy:数値配列や行列の定義に使用
  • Pandas:データの読み込み・操作・加工に使用
  • Statsmodels:パラメータ推定や統計的検定に使用
  • Pylab:グラフの描画に使用

これらのライブラリはpipで簡単にインストールできます。CLIで以下のコマンドを実行してください。

>pip install numpy pandas statsmodels

ロジスティック回帰のユースケース例

Pythonでのロジスティック回帰を検証するために、UCLA(Institute for Digital Research and Education)が提供するロジット回帰用データセットを使用します。CSV形式のデータは以下のリンクから取得できます。

https://stats.idre.ucla.edu/stat/data/binary.csv

ここでは、このCSVファイルをローカル環境に保存して読み込む方法を紹介します(URLから直接読み込むことも可能です)。このデータセットを使って、大学院入学の合否に影響を与えるさまざまな要因を分析していきます。

ライブラリのインポートとデータセットの読み込み

Pandasのread_csv関数を使ってデータを読み込みます。

import pandas as pd
import statsmodels.api as sm
import pylab as pl
import numpy as np

df = pd.read_csv('binary.csv')
# URLから直接読み込む場合はこちら
# df = pd.read_csv('https://stats.idre.ucla.edu/stat/data/binary.csv')
print(df.head())

出力結果

    admit   gre  gpa  rank
0       0   380  3.61     3
1       1   660  3.67     3
2       1   800  4.00     1
3       1   640  3.19     4
4       0   520  2.93     4

出力を見ると、列名の一つに「rank」があります。しかし「rank」はPandasデータフレームのメソッド名でもあるため、名前の衝突が発生する恐れがあります。そこで、トラブルを避けるために列名を「prestige」に変更しておきましょう。

df.columns = ["admit", "gre", "gpa", "prestige"]
print(df.columns)

出力結果

Index(['admit', 'gre', 'gpa', 'prestige'], dtype='object')

これで前準備は完了です。次に、データセットの中身をより深く掘り下げて確認していきます。

データの要約

Pandasのdescribe関数を使うと、データ全体の統計サマリーを一括で確認できます。

print(df.describe())

出力結果

          admit         gre         gpa    prestige
count  400.000000  400.000000  400.000000  400.000000
mean     0.317500  587.700000    3.389900    2.485000
std      0.466087  115.516536    0.380567    0.944460
min      0.000000  220.000000    2.260000    1.000000
25%      0.000000  520.000000    3.130000    2.000000
50%      0.000000  580.000000    3.395000    2.000000
75%      1.000000  660.000000    3.670000    3.000000
max      1.000000  800.000000    4.000000    4.000000

さらに、各列の標準偏差や、「prestige」と合否を組み合わせたクロス集計表も簡単に確認できます。

# 各列の標準偏差を確認
print(df.std())

出力結果

admit        0.466087
gre        115.516536
gpa          0.380567
prestige     0.944460
dtype: float64
# prestigeと合否のクロス集計表
print(pd.crosstab(df['admit'], df['prestige'], rownames=['admit']))

出力結果

prestige   1   2   3   4
admit
0         28  97  93  55
1         33  54  28  12

続いて、データセットの全列をヒストグラムとして可視化してみましょう。

# 全列のヒストグラムを描画
df.hist()
pl.show()

出力結果

Pythonで学ぶロジスティック回帰:基礎から実装・結果の解釈まで徹底解説

ダミー変数の作成

PythonのPandasライブラリは、カテゴリ変数の扱いにおいて高い柔軟性を提供します。get_dummies関数を使えば、カテゴリ変数を0/1のフラグを持つダミー変数へ簡単に変換できます。

# prestigeをダミー変数化
dummy_ranks = pd.get_dummies(df['prestige'], prefix='prestige')
print(dummy_ranks.head())

出力結果

   prestige_1  prestige_2  prestige_3  prestige_4
0           0           0           1           0
1           0           0           1           0
2           1           0           0           0
3           0           0           0           1
4           0           0           0           1

次に、回帰分析用に整形されたデータフレームを作成します。基準カテゴリとなるprestige_1を除外し、残りのダミー変数を元のデータに結合します。

# 回帰分析用のクリーンなデータフレームを作成
cols_to_keep = ['admit', 'gre', 'gpa']
data = df[cols_to_keep].join(dummy_ranks.loc[:, 'prestige_2':])

※旧バージョンのPandasでは.ixが使われていましたが、現在は廃止されているため、上記のコードでは.locを使用しています。

出力結果

   admit  gre   gpa  prestige_2  prestige_3  prestige_4
0      0  380  3.61           0           1           0
1      1  660  3.67           0           1           0
2      1  800  4.00           0           0           0
3      1  640  3.19           0           0           1
4      0  520  2.93           0           0           1

回帰分析の実行

いよいよロジスティック回帰を実行します。手順は非常にシンプルで、予測したい目的変数の列と、モデルが予測に使用する説明変数の列を指定するだけです。

ここでは、gre、gpa、およびダミー変数(prestige_2、prestige_3、prestige_4)に基づいて、admit列(合否)を予測します。

train_cols = data.columns[1:]
# Index([gre, gpa, prestige_2, prestige_3, prestige_4], dtype=object)

logit = sm.Logit(data['admit'], data[train_cols])

# モデルのフィッティング
result = logit.fit()

出力結果

Optimization terminated successfully.
Current function value: 0.573147
Iterations 6

結果の解釈

Statsmodelsのsummary2関数を使えば、モデルの詳細なサマリーを出力できます。

print(result.summary2())

出力結果

                         Results: Logit
=================================================================
Model:              Logit            No. Iterations:   6.0000
Dependent Variable: admit            Pseudo R-squared: 0.083
Date:               2019-03-03 14:16 AIC:              470.5175
No. Observations:   400              BIC:              494.4663
Df Model:           5                Log-Likelihood:   -229.26
Df Residuals:       394              LL-Null:          -249.99
Converged:          1.0000           Scale:            1.0000
-----------------------------------------------------------------
             Coef.   Std.Err.    z     P>|z|   [0.025  0.975]
-----------------------------------------------------------------
gre          0.0023    0.0011  2.0699  0.0385  0.0001  0.0044
gpa          0.8040    0.3318  2.4231  0.0154  0.1537  1.4544
prestige_2  -0.6754    0.3165 -2.1342  0.0328 -1.2958 -0.0551
prestige_3  -1.3402    0.3453 -3.8812  0.0001 -2.0170 -0.6634
prestige_4  -1.5515    0.4178 -3.7131  0.0002 -2.3704 -0.7325
intercept   -3.9900    1.1400 -3.5001  0.0005 -6.2242 -1.7557
=================================================================

結果オブジェクトからは、モデル出力の一部だけを取り出して個別に確認することもできます。例えば、各係数の信頼区間は以下のように取得できます。

# 各係数の信頼区間を確認
print(result.conf_int())

出力結果

                   0         1
gre         0.000120  0.004409
gpa         0.153684  1.454391
prestige_2 -1.295751 -0.055135
prestige_3 -2.016992 -0.663416
prestige_4 -2.370399 -0.732529
intercept  -6.224242 -1.755716

この出力から、合格確率と出身校のランク(prestige)との間に逆相関関係があることが読み取れます。つまり、上位ランクの学部出身者(prestige_1=True)は、下位ランクの学校(prestige_3やprestige_4)の出身者に比べて、大学院への合格確率が高くなる傾向があるのです。


  1. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが

  2. PyTorchでCNNを実装してMNISTの手書き数字を認識する方法

    この記事では、PyTorchを使ってCNN(畳み込みニューラルネットワーク)を訓練し、MNISTデータセットによる手書き数字の分類器を構築する方法を解説します。MNISTは手書き文字認識タスクで広く利用されているデータセットで、ラベル付きの28×28ピクセル・グレースケール画像が7万枚以上収録されています。内訳は約6万枚の訓練画像と1万枚のテスト画像です。ここでは、6万枚の訓練画像でモデルを学習し、その後1万枚のテスト画像で分類精度を評価します。環境準備まず、最新版のPyTorchとtorchvisionが必要です。まだインストールしていない場合は、ターミナルで以下のコマンドを実行してください