1 of 71

機械学習演習

第3章:ロジスティック回帰

2 of 71

はじめに

この章では、二値分類の基本的かつ重要なアルゴリズムである「ロジスティック回帰」を学びます。医療分野では、その解釈のしやすさから広く使われている手法です。

学習目標

  • ロジスティック回帰の原理を理解する
  • モデルの係数とオッズ比を解釈できる
  • 正則化の概念を理解する
  • 予測確率を臨床判断に活用する方法を学ぶ

はじめに

3 of 71

3.1 ロジスティック回帰とは

4 of 71

しかし、「死亡するか否か」のような二値(0 or 1)を予測する場合、線形回帰では問題があります:

  • 予測値が0未満や1を超える可能性がある
  • 確率として解釈できない

ロジスティック回帰は、この問題を解決します。

3.1.1 線形回帰との違い

線形回帰は連続値(例:血圧値、入院日数)を予測します。

 

5 of 71

3.1.2 シグモイド関数

ロジスティック回帰は、シグモイド関数(ロジスティック関数)を使って、

出力を0〜1の範囲(確率)に変換します。

この関数は:

  • 入力が大きいほど1に近づく
  • 入力が小さいほど0に近づく
  • 出力は常に0〜1の範囲

 

6 of 71

3.1.3 シグモイド関数の可視化

7 of 71

3.1.3 シグモイド関数の可視化

シグモイド関数により、任意の入力値が0〜1の確率に変換されます

8 of 71

3.1.4 オッズとロジット

例:死亡確率が0.25(25%)の場合

  • オッズ = 0.25 / 0.75 = 0.333(「3回に1回死亡」)

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

ロジスティック回帰は、このロジットが特徴量の線形結合になるモデルです。

 

 

ロジット(Logit)は、オッズの自然対数です。

9 of 71

3.2 環境準備とデータの読み込み

10 of 71

3.2 環境準備とデータの読み込み

ここで'heart_failure_clinical_records_dataset.csv'をアップロードしてください

フォルダアイコンをクリックして枠の中にドラッグ&ドロップするとアップロードできます

11 of 71

3.2 環境準備とデータの読み込み

12 of 71

3.3 ロジスティック回帰の実装

13 of 71

3.3.1 基本的なモデルの構築

model = LogisticRegression(random_state=42)

: sklearn.linear_modelからLogisticRegressionクラスをインスタンス化し、ロジスティック回帰モデルを作成します。random_state=42を設定することで、モデルの内部的な乱数生成が固定され、何度実行しても同じ結果が得られるようになります。

14 of 71

3.3.1 基本的なモデルの構築

model.fit(X_train_scaled, y_train)

: 作成したモデルを訓練データに適合させています(学習)。X_train_scaledは標準化された特徴量データ、y_trainは訓練データの目的変数(ここでは死亡イベントの有無)です。このfitメソッドにより、モデルはデータから最適な係数(重み)を学習します。

print(…)

: モデルの学習が完了したことを示すメッセージと、モデルが学習に使用した特徴量の一覧を表示しています。これにより、どの変数がモデルの予測に貢献しているかを確認できます。

15 of 71

3.3.2 予測の実行

解説

  • model.predict(): クラスラベル(0 or 1)を予測
  • model.predict_proba(): 各クラスの確率を予測
    • [:, 0]: クラス0(生存)の確率
    • [:, 1]: クラス1(死亡)の確率

デフォルトでは、死亡確率が0.5以上なら

「死亡」と予測します。

最初の10人を例に予測結果を出力します

8番目の患者(インデックスが7)は実際の値は1(死亡)ですが、予測値は0(生存)となっています。これは、モデルがこの患者の死亡確率を0.134と予測し、デフォルトの閾値0.5を下回ったため、「生存」と誤って予測したことを意味します。

16 of 71

3.3.3 モデルの評価(基本)

accuracy = accuracy_score(y_test, y_pred)

: sklearn.metricsライブラリのaccuracy_score関数を使用して、モデルの正解率を計算しています。この関数は、実際の正解ラベル(y_test)とモデルが予測したラベル(y_pred)を比較し、両者が一致したサンプルの割合を返します。

print(f"正解率(Accuracy): {accuracy:.3f}"): 計算された正解率を小数点以下3桁まで表示しています。

17 of 71

3.3.3 モデルの評価(基本)

print(f"→ テストデータの{accuracy*100:.1f}%を正しく予測できました”)

: 正解率をパーセンテージ形式で、より分かりやすく表示しています。例えば、正解率が0.817であれば、「テストデータの81.7%を正しく予測できました」と出力されます。

この正解率は、モデルがテストデータにおいてどれくらいの割合で正しい予測を行ったかを示す基本的な評価指標です。

18 of 71

3.3.3 モデルの評価(基本)

19 of 71

3.3.3 モデルの評価(基本)

cm = confusion_matrix(y_test, y_pred)

: sklearn.metricsライブラリのconfusion_

matrix関数を使って、実際の正解ラベル (y_test)

とモデルの予測ラベル (y_pred) を比較し、

混同行列を計算しています。これにより、モデルが

各クラスをどれだけ正確に予測し、どのような間違い

をしたかを把握できます。

sns.heatmap(...): 計算された混同行列 cm を

Seabornライブラリのheatmap関数を使ってヒート

マップとして表示しています。annot=Trueで各セル

の数値が表示され、fmt=‘d'で整数として

フォーマットされます。cmap=‘Blues'は色の濃淡

で数値の大小を表現し、xticklabelsとyticklabels

で軸のラベルを分かりやすく設定しています。

20 of 71

3.3.3 モデルの評価(基本)

tn, fp, fn, tp = cm.ravel()

: cm.ravel()は混同行列をフラットな一次元配列

に変換し、それをtn (真陰性), fp (偽陽性),

fn (偽陰性), tp (真陽性) の各変数に割り当てて

います。これにより、それぞれの要素を個別に参照

できるようになります。

print(…)による解釈

: それぞれの要素について、説明を出力しています。

21 of 71

3.3.3 モデルの評価(基本)

sklearn.metricsライブラリの

classification_report関数を使用して、

モデルの予測結果に関する詳細な

評価指標を表示します。

classification_reportは、適合率(Precision)、再現率(Recall、または感度)、F1スコア、

および各クラスのサポート(サンプル数)を、クラスごとにまとめて出力します。

  • y_test: 実際の正解ラベルです。
  • y_pred: モデルが予測したクラスラベルです。
  • target_names=['Survived', 'Died']: 出力されるレポートで、クラス0を’Survived'(生存)、クラス1を'Died'(死亡)として表示するように指定しています。これにより、結果がより直感的に理解できます。

22 of 71

3.3.3 モデルの評価(基本)

評価指標の解説

指標

計算式

意味

医療での解釈

Precision(適合率)

TP / (TP + FP)

陽性予測の正確さ

死亡予測のうち実際に死亡した割合

Recall(感度)

TP / (TP + FN)

陽性の検出率

実際の死亡患者のうち予測できた割合

F1-score

2 × (Precision × Recall) / (Precision + Recall)

PrecisionとRecallの調和平均

バランスの取れた指標

Support

-

各クラスのサンプル数

-

23 of 71

3.4 係数の解釈

24 of 71

3.4.1 係数の確認

ロジスティック回帰の大きな利点は、係数を解釈できることです。

訓練されたロジスティック回帰モデルから学習された係数と切片を取得し、表示します。

これにより、各特徴量が目的変数にどの程度影響を与えるかを解釈することができます。

25 of 71

3.4.1 係数の確認

  1. 係数の取得とDataFrame化:
    • model.coef_[0]から各特徴量の係数(重み)を取得し、X_train.columnsと組み合わせてpandas.DataFrameを作成しています。
    • sort_values('Coefficient', key=abs, ascending=False)によって、係数の絶対値が大きい順に並べ替えています。絶対値が大きいほど、その特徴量がモデルの予測に与える影響が大きいことを示します。

26 of 71

3.4.1 係数の確認

  1. 切片の表示:
    • model.intercept_[0]から切片の値をf-stringを使って小数点以下4桁で表示しています。切片は、すべて特徴量が0だった場合の対数オッズ(ロジット)を表します。
  2. 各特徴量の係数の表示:
    • 作成したcoefficients DataFrameをto_string(index=False)を使って整形して表示しています。これにより、「Feature」と「Coefficient」の列がインデックスなしで綺麗に表示されます。

27 of 71

3.4.1 係数の確認

この出力を見ることで、どの特徴量が死亡リスクの上昇に寄与しているか(正の係数)、または低下に寄与しているか(負の係数)、そしてその影響の大きさを把握できます。

28 of 71

3.4.1 係数の確認

ロジスティック回帰モデルで学習された各特徴量の係数を可視化します。

  1. plt.figure(figsize=(10, 6)): グラフのサイズを設定しています。
  2. colors = [...]: 係数の値に基づいて棒グラフの色を決定しています。係数が正(0より大きい)の場合は'coral'(赤系)に、負(0より小さい)の場合は'steelblue'(青系)に設定しています。
  3. plt.barh(coefficients['Feature'], coefficients['Coefficient'], color=colors): 横棒グラフを作成しています。y軸には特徴量の名前、x軸には対応する係数の値をプロットし、2で定義した色を使用しています。

29 of 71

3.4.1 係数の確認

ロジスティック回帰モデルで学習された各特徴量の係数を可視化します。

  1. plt.xlabel(...), plt.title(...): x軸のラベルとグラフのタイトルを設定しています。
  2. plt.axvline(x=0, ...): 係数0の位置に垂直な線を引き、どの特徴量が正の影響を持ち、どの特徴量が負の影響を持つかを視覚的に分かりやすくしています。
  3. plt.tight_layout()plt.show(): グラフのレイアウトを調整し、表示しています。

30 of 71

3.4.1 係数の確認

【係数の解釈】

正の係数(赤): その特徴量の値が増加すると、目的変数(死亡リスク)が上昇する傾向があることを示します。�負の係数(青): その特徴量の値が増加すると、目的変数(死亡リスク)が低下する傾向があることを示します。

31 of 71

3.4.2 オッズ比の計算

オッズ比(Odds Ratio)は、係数の指数関数で計算され、臨床的に解釈しやすい指標です。

1.対数オッズの式(ロジット):

2.オッズ比の式:(両辺を指数関数𝑒で変換)両辺を指数関数𝑒で変換することで、オッズは特徴量の線型結合の指数関数で表されます。

(オッズ比の導出)

 

 

 

32 of 71

3.4.2 オッズ比の計算

オッズ比(Odds Ratio)は、係数の指数関数で計算され、臨床的に解釈しやすい指標です。

 

3.オッズ比の計算:オッズ比は、他の特徴量(𝑥𝑗、ただし𝑗≠𝑘)を固定したまま、注目する特徴量𝑥𝑘が𝑥𝑘+1へ1単位増加したときのオッズの比として定義されます。

これを計算すると、分子と分母が打ち消し合い、対応する係数𝛽𝑘の指数関数だけが残ります。

従ってオッズ比はその特徴量の係数𝛽の指数関数となります。

(オッズ比の導出)

 

 

common :共通項

33 of 71

3.4.2 オッズ比の計算

ロジスティック回帰モデルの各特徴量に対する「オッズ比(Odds Ratio)」を計算します。

  1. odds_ratios = pd.DataFrame(...): オッズ比を格納するためのDataFrameを作成しています。
    • 'Feature': X_train.columns: 各特徴量の名前を列として追加します。
    • 'Coefficient': model.coef_[0]: モデルが学習した各特徴量の係数を列として追加します。
    • 'Odds Ratio': np.exp(model.coef_[0]): 係数(model.coef_[0])の指数関数(np.exp())を計算することでオッズ比を求めています。ロジスティック回帰において、オッズ比は係数の指数関数として定義されます。
  2. .sort_values('Odds Ratio', ascending=False): 計算されたオッズ比を降順(値が大きい順)に並べ替えています。これにより、影響度の高い特徴量を上位から確認できます。

34 of 71

3.4.2 オッズ比の計算

オッズ比

解釈

1.0

リスクに影響なし

> 1.0

リスク上昇(例:1.5 = 50%リスク増加)

< 1.0

リスク低下(例:0.8 = 20%リスク減少)

注意: 標準化されたデータでの係数なので、「標準偏差1単位の増加あたり」の解釈になります。

オッズ比の解釈

35 of 71

3.4.2 オッズ比の計算

特定の各特徴量(time, serum_creatinine, ejection_fraction)が「元のスケールで標準偏差1単位分増加した場合に、死亡リスクのオッズがどのように変化するか」を計算します。

  1. for feature in [...]: 各特徴量に対して以下の処理を繰り返します。
  2. std = X_train[feature].std(): 訓練データ (X_train) におけるその特徴量の標準偏差 (std) を計算します。
  3. coef = coefficients[coefficients['Feature'] == feature][‘Coefficient'].values[0]: 前のセルで計算されたcoefficients DataFrameから、現在注目している特徴量に対応する係数を取得します。

36 of 71

3.4.2 オッズ比の計算

特定の各特徴量(time, serum_creatinine, ejection_fraction)が「元のスケールで標準偏差1単位分増加した場合に、死亡リスクのオッズがどのように変化するか」を計算します。

  1. odds_ratio = np.exp(coef): 取得した係数(coef)を指数関数(np.exp())で変換し、オッズ比を計算します。このオッズ比は、標準化された特徴量が1単位増加した場合のオッズの変化率を示しますが、これは元のスケールで標準偏差1単位分増加した場合のオッズ比と解釈できます。
  2. print(...): 各特徴量について、計算された標準偏差、オッズ比、そしてそのオッズ比を具体的なパーセンテージで解釈した結果を表示します。

37 of 71

3.4.2 オッズ比の計算

標準化されたデータで学習したモデルの係数を、

より直感的に理解しやすい

「元のデータのスケール」

での変化として解釈することができます。

38 of 71

3.5 正則化(Regularization)

39 of 71

3.5.1 正則化とは

手法

ペナルティ

特徴

L1正則化(Lasso)

係数の絶対値の和

一部の係数を0にする(特徴量選択)

L2正則化(Ridge)

係数の二乗の和

係数を小さくする(デフォルト)

Elastic Net

L1とL2の組み合わせ

両方の利点

scikit-learnでは、Cパラメータで正則化の強さを制御します。

  • Cが小さい: 強い正則化(係数が小さくなる)
  • Cが大きい: 弱い正則化(係数が大きくなりやすい)

3.5.2 正則化の強さ(Cパラメータ)

正則化は、モデルの複雑さにペナルティを課すことで、過学習を防ぐテクニックです。

主な正則化手法

40 of 71

3.5.1 正則化とは

3.5.2 正則化の強さ(Cパラメータ)

41 of 71

3.5.1 正則化とは

3.5.2 正則化の強さ(Cパラメータ)

42 of 71

3.5.1 正則化とは

3.5.2 正則化の強さ(Cパラメータ)

左側のグラフは、訓練データとテストデータそれぞれの正解率がCパラメータに応じてどう変化したかを示しています。

右側のグラフは、モデルの係数の絶対値の最大値がCパラメータに応じてどう変化したかを示しています。この「最大絶対係数」は、モデルの複雑さの代理変数として見ることができます。

43 of 71

3.5.3 L1正則化による特徴量選択

44 of 71

3.6 予測確率の活用

45 of 71

3.6.1 予測確率の分布

46 of 71

3.6.1 予測確率の分布

47 of 71

3.6.2 閾値の調整

デフォルトの閾値は0.5ですが、臨床的な目的に応じて調整できます。

  • 閾値を下げる: 感度(Recall)が上がる → 見逃しを減らす
  • 閾値を上げる: 適合率(Precision)が上がる → 誤報を減らす

48 of 71

3.6.2 閾値の調整

49 of 71

3.6.2 閾値の調整

50 of 71

3.6.2 閾値の調整

51 of 71

3.6.3 ROC曲線とAUC

52 of 71

3.6.3 ROC曲線とAUC

53 of 71

3.7 クラス不均衡への対処

54 of 71

3.7.1 class_weightパラメータの使用

55 of 71

3.7.1 class_weightパラメータの使用

56 of 71

3.7.1 class_weightパラメータの使用

57 of 71

3.7.1 class_weightパラメータの使用

58 of 71

3.8 個別患者の予測解釈

59 of 71

3.8.1 特定の患者の予測を解釈する

60 of 71

3.8.1 特定の患者の予測を解釈する

61 of 71

3.8.1 特定の患者の予測を解釈する

62 of 71

3.8.1 特定の患者の予測を解釈する

63 of 71

3.8.1 特定の患者の予測を解釈する

64 of 71

3.8.1 特定の患者の予測を解釈する

65 of 71

3.9 まとめ

概念

説明

ロジスティック回帰

二値分類のための線形モデル

シグモイド関数

出力を0〜1の確率に変換

係数

各特徴量の影響の大きさと方向

オッズ比

リスクの増減を解釈しやすい形で表現

正則化

過学習を防ぐためのペナルティ

閾値

予測確率からクラスを決定する境界

ROC曲線・AUC

モデルの判別能力を評価

class_weight

クラス不均衡に対処

ロジスティック回帰の利点

  • 係数が解釈しやすい(医療分野で重要)
  • 計算が高速
  • 過学習しにくい
  • 確率を出力できる

ロジスティック回帰の限界

  • 線形の関係しか捉えられない
  • 特徴量間の交互作用を自動的に学習しない
  • 複雑なパターンの学習には不向き

66 of 71

演習問題

問題1:基本的な実装

L2正則化の強さを変えて(C=0.01)モデルを学習し、

テストデータでの正解率とAUCを計算してください。

問題2:閾値の最適化

感度(Recall)が0.8以上になる最大の閾値を見つけてください。

その閾値での適合率(Precision)も計算してください。

67 of 71

演習問題

問題3:係数の解釈

元のスケール(標準化前)で、以下の質問に答えてください。

  1. 駆出率(ejection_fraction)が10%上昇すると、オッズ比はどのように変化しますか?
  2. この変化は臨床的にどのように解釈できますか?

問題4:考察

心不全患者の死亡予測において、ロジスティック回帰モデルを臨床で使用する場合、

以下について考察してください。

  1. モデルの出力(予測確率)をどのように臨床判断に活用できるか
  2. 閾値はどのような基準で設定すべきか

68 of 71

解答例

問題1の解答

69 of 71

解答例

問題2の解答

70 of 71

解答例

問題3の解答

71 of 71

解答例

問題4の解答

1. 予測確率の臨床活用

  • リスク層別化: 予測確率に基づいて患者を低リスク・中リスク・高リスクに分類し、それぞれに適切な介入(フォローアップ頻度、治療強度など)を行う
  • 患者への説明: 「あなたの死亡リスクは約30%です」のように、具体的な数値でリスクを伝えることで、治療の必要性を理解してもらいやすくなる
  • 意思決定支援: 予測確率と各特徴量の寄与度を示すことで、どの因子に介入すべきかの判断材料になる

2. 閾値の設定基準

  • 臨床的コスト: 見逃し(偽陰性)と誤報(偽陽性)のコストを考慮する。死亡予測では見逃しのコストが高いため、低めの閾値が適切
  • 医療資源: 誤報が多すぎると追加検査や入院が増え、医療資源を圧迫する。現実的な対応可能範囲を考慮
  • 患者集団: 高リスク患者が多い病棟では閾値を上げ、一般外来では下げるなど、状況に応じた調整
  • 目標指標: 感度80%以上を目標にするなど、具体的な目標を設定して閾値を決定