記事内にはプロモーションが含まれています

【Python】ロジスティック回帰分析の実装手順!scikit-learnとstatsmodelsでのp値・オッズ比・可視化まで

【Python】ロジスティック回帰分析の実装手順!scikit-learnとstatsmodelsでのp値・オッズ比・可視化まで Python

ある事象が「起こる確率」を予測したり、要因が結果にどれくらい影響しているかを分析したりする際、最も基本的かつ強力な手法の一つが「ロジスティック回帰分析」です。

ビジネスの現場では、「顧客が商品を購入するかどうか」「メールがスパムかどうか」といった2つのクラスに分類する問題(二値分類)で頻繁に使用されます。

Pythonでこれを実装する場合、目的によって使うべきライブラリが異なります。
予測精度を重視するなら「scikit-learn」、要因分析やp値の確認を重視するなら「statsmodels」が適しています。

この記事では、Pythonを使ったロジスティック回帰分析の具体的な実装コードを、これら2つのライブラリを用いて解説します。

また、分析結果の解釈に欠かせないオッズ比の計算や、精度の可視化(ROC曲線)についても網羅的に紹介します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

ロジスティック回帰分析とは?Pythonで実装するメリット

ロジスティック回帰(Logistic Regression)は、名前に「回帰」と付いていますが、主に分類問題に使われる統計モデルです。

説明変数(要因)から、目的変数(結果)が「0」または「1」になる確率を予測します。

線形回帰との違い

通常の線形回帰が数値を予測するのに対し、ロジスティック回帰は「シグモイド関数」を用いて、出力値を0から1の範囲(確率)に収める点が特徴です。

ある閾値(通常は0.5)を超えれば「1(発生)」、超えなければ「0(未発生)」と分類します。

Pythonで分析を行うメリット

Pythonにはデータ分析に特化したライブラリが豊富に揃っています。

  • scikit-learn: 機械学習モデルの構築、学習、評価が非常に簡単に行えます。
  • statsmodels: 統計学的な検定結果(p値や信頼区間など)を詳細に出力できます。
  • pandas: データの前処理や集計が効率的に行えます。

これらを組み合わせることで、データの加工からモデル構築、結果の解釈までを一気通貫で行うことができます。

分析の準備:ライブラリのインポートとデータの用意

まずは必要なライブラリをインポートし、分析に使用するサンプルデータを準備しましょう。

今回は、scikit-learnに標準で同梱されている「乳がんの診断データセット(Breast Cancer Wisconsin dataset)」を使用します。

これは、腫瘍の特徴から良性・悪性を分類する二値分類の定番データセットです。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 日本語フォントの設定(可視化用。環境に合わせて変更してください)
# plt.rcParams['font.family'] = 'MS Gothic' 

# データの読み込み
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target, name='target')

# データの確認(先頭5行)
print(X.head())
print(y.head())

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

# データの標準化(ロジスティック回帰では重要)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

このソースコードでは、まず sklearn.datasets からデータを読み込み、扱いやすい pandas のDataFrame形式に変換しています。

その後、モデルの性能を正しく評価するために train_test_split で学習用とテスト用にデータを分割しています。

重要なポイントは「標準化」です。

ロジスティック回帰はデータのスケール(単位や大きさ)の影響を受けるため、StandardScaler を使って平均0、分散1に揃える処理を行っています。
これにより、モデルの収束が早くなり、係数の比較もしやすくなります。

【scikit-learn】ロジスティック回帰の実装と予測

まずは、機械学習で最も一般的なライブラリである scikit-learn を使った実装方法です。
モデルの構築から予測までが非常にシンプルに記述できます。

モデルの学習と予測

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# ロジスティック回帰モデルのインスタンス化
# Cは正則化の強さを指定するパラメータ(小さいほど正則化が強い)
model = LogisticRegression(C=1.0, random_state=42)

# モデルの学習
model.fit(X_train_scaled, y_train)

# テストデータに対する予測
y_pred = model.predict(X_test_scaled)

# 正解率の表示
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

# 詳細な評価レポート
print("\nClassification Report:\n")
print(classification_report(y_test, y_pred))

実行結果の例

Accuracy: 0.9766

Classification Report:
              precision    recall  f1-score   support
           0       0.98      0.95      0.97        64
           1       0.97      0.99      0.98       107
    accuracy                           0.98       171
   macro avg       0.98      0.97      0.97       171
weighted avg       0.98      0.98      0.98       171

LogisticRegression クラスを使ってモデルを作成し、fit メソッドで学習、predict メソッドで予測を行っています。

引数の C は逆正則化パラメータで、モデルの過学習を防ぐために調整します。

出力されたレポートを見ることで、正解率(Accuracy)だけでなく、適合率(Precision)や再現率(Recall)といった指標も確認できます。

【statsmodels】p値や統計量を確認する実装

「どの変数が統計的に有意に効いているのか(p値)」を確認したい場合は、statsmodels ライブラリが適しています。

scikit-learnよりも詳細な統計レポートを出力できます。

statsmodelsによるロジスティック回帰の実行

import statsmodels.api as sm

# statsmodelsでは定数項(切片)を明示的に追加する必要がある
X_train_const = sm.add_constant(X_train_scaled)

# ロジスティック回帰モデル(Logit)の構築と学習
# statsmodelsは (目的変数, 説明変数) の順で渡す点に注意
logit_model = sm.Logit(y_train, X_train_const)
result = logit_model.fit()

# 結果のサマリーを表示
print(result.summary())

実行結果の例(一部抜粋)

Optimization terminated successfully.
         Current function value: 0.056...
         Iterations 12
                           Logit Regression Results                           
==============================================================================
Dep. Variable:                 target   No. Observations:                  398
Model:                          Logit   Df Residuals:                      367
Method:                           MLE   Df Model:                           30
...
=================================================================================
                    coef    std err          z      P>|z|      [0.025      0.975]
---------------------------------------------------------------------------------
const             0.3541      0.543      0.652      0.514      -0.710       1.418
x1                0.5234      1.234      0.424      0.672      -1.895       2.942
...

sm.add_constant を使って説明変数に「定数項(全ての値が1の列)」を追加しています。

これは切片を計算するために必須の処理です。

sm.Logit でモデルを定義し、fit() で学習させます。
summary() メソッドを呼ぶことで、各変数の係数(coef)、標準誤差、z値、そしてp値(P>|z|)を含む詳細な表が出力されます。

p値が0.05未満であれば、その変数は統計的に有意であると判断できます。

ロジスティック回帰の結果を解釈する:オッズ比

ロジスティック回帰の結果をビジネスで説明する際、係数(coef)そのものよりも「オッズ比」の方が直感的に理解しやすい場合があります。

オッズ比の計算と意味

オッズ比は、ある事象が起こる確率と起こらない確率の比率です。

ロジスティック回帰の係数は対数オッズ(log odds)を表しているため、これを指数関数(exponential)で変換することでオッズ比を求められます。

# scikit-learnモデルの係数を取得
coefficients = model.coef_[0]

# 係数とオッズ比をDataFrameにまとめる
coef_df = pd.DataFrame({
    'Feature': data.feature_names,
    'Coefficient': coefficients,
    'Odds_Ratio': np.exp(coefficients) # 係数を指数変換してオッズ比を算出
})

# オッズ比が高い順にソートして表示
print(coef_df.sort_values(by='Odds_Ratio', ascending=False).head())

このコードでは、np.exp() を使って係数をオッズ比に変換しています。

オッズ比が「1」より大きければ、その変数の値が増加すると、目的変数が「1」になる確率が高まることを意味します。

逆に「1」より小さければ、確率は低くなります。

例えば、オッズ比が2.5の変数は、値が1単位増えると、結果が発生するオッズが2.5倍になることを示唆します。

分析精度の可視化:ROC曲線とAUC

モデルの性能を視覚的に評価するために、ROC曲線を描画してみましょう。また、その曲線下の面積であるAUC(Area Under the Curve)も計算します。

ROC曲線の描画コード

from sklearn.metrics import roc_curve, roc_auc_score

# テストデータに対する予測確率を取得(クラス1になる確率)
y_pred_proba = model.predict_proba(X_test_scaled)[:, 1]

# FPR(偽陽性率)、TPR(真陽性率)、閾値を算出
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)

# AUCスコアを計算
auc_score = roc_auc_score(y_test, y_pred_proba)

# グラフの描画
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'ROC Curve (AUC = {auc_score:.4f})')
plt.plot([0, 1], [0, 1], 'k--', label='Random Guess') # ランダムな予測の線
plt.xlabel('False Positive Rate (FPR)')
plt.ylabel('True Positive Rate (TPR)')
plt.title('ROC Curve for Logistic Regression')
plt.legend()
plt.grid()
plt.show()

predict_proba メソッドを使って、各データがクラス1(陽性)に分類される「確率」を取得します。

roc_curve 関数でグラフ描画に必要なデータを取得し、matplotlib でプロットします。

AUCは 0.5 から 1.0 の値をとり、1.0に近いほど優れたモデルであることを表します。

ランダムな予測(対角線)よりも左上に膨らんでいるカーブが良いモデルの証拠です。

Pythonのスキルを活かして年収を上げる方法

以上、Pythonのロジスティック回帰分析の実装手順について解説してきました。

なお、Pythonのスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

Pythonエンジニアの需要は非常に高いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなPythonの案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。