重回帰分析と多重共線性

code
Published

October 5, 2023

1 はじめに

健康診断データとそれに基づく病気のリスク評価は、医療分野において欠かせない要素です。特に、予防医学や早期診断の観点から、これらのデータがいかに重要であるかは言うまでもありません。今回の記事では、前回糖尿病のデータを用いて、健康診断データと糖尿病スコア(1年後の病状進行の量的な指標)との関係を探ります1

特に多重共線性の概念とその影響について調べます。多重共線性とは、予測変数間に高い相関がある場合に発生し、これが重回帰分析の結果に影響を与える可能性がある現象です。多重共線性があると、モデルの係数の解釈が難しくなり、係数の推定値の分散が大きくなり、結果としてモデルの予測が不安定になる可能性があります。

本記事では、はじめに重回帰モデルを構築します。そして、得られたモデルの係数を解釈し、多重共線性が結果にどう影響しているのかを調査します。

2 準備

Code
# ライブラリのインポート
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
import seaborn as sns
import numpy as np

# データセットの読み込み
diabetes = load_diabetes()
data = pd.DataFrame(diabetes['data'], columns=diabetes['feature_names'])

# targetの標準化
sc = StandardScaler()
data['target'] = sc.fit_transform(diabetes['target'].reshape(-1, 1))

# データセットのサンプル表示
data.head()
age sex bmi bp s1 s2 s3 s4 s5 s6 target
0 0.038076 0.050680 0.061696 0.021872 -0.044223 -0.034821 -0.043401 -0.002592 0.019907 -0.017646 -0.014719
1 -0.001882 -0.044642 -0.051474 -0.026328 -0.008449 -0.019163 0.074412 -0.039493 -0.068332 -0.092204 -1.001659
2 0.085299 0.050680 0.044451 -0.005670 -0.045599 -0.034194 -0.032356 -0.002592 0.002861 -0.025930 -0.144580
3 -0.089063 -0.044642 -0.011595 -0.036656 0.012191 0.024991 -0.036038 0.034309 0.022688 -0.009362 0.699513
4 0.005383 -0.044642 -0.036385 0.021872 0.003935 0.015596 0.008142 -0.002592 -0.031988 -0.046641 -0.222496

s1-s6と医学用語、概要の対応は以下になります。2

Warning

s5に関しては、scikit-learnの公式ページ3においてもpossiblyと説明にあります。 以下の説明は参考程度にしてください。

変数 医学用語 概要
s1 tc (total serum cholesterol) 血中の総コレステロール量
s2 ldl (low-density lipoproteins) 「悪玉コレステロール」とも呼ばれ、高いほど動脈硬化のリスクが高い
s3 hdl (high-density lipoproteins) 「善玉コレステロール」とも呼ばれ、高いほど動脈硬化のリスクを減少
s4 tch (total cholesterol / HDL) 総コレステロールとHDLコレステロールの比率。
s5 ltg (possibly log of serum triglycerides level) 血清中のトリグリセリド(脂質)レベルの対数
s6 glu (blood sugar level) 血中のグルコース(血糖)レベル

3 モデル作成と結果の確認

Code
# モデルの作成と学習
X_train, X_test, y_train, y_test = train_test_split(data.drop('target', axis=1), data['target'], test_size=0.2)
lr = LinearRegression().fit(X_train, y_train)

# 予測と結果の評価
y_pred = lr.predict(X_test)
mae = np.mean(np.abs(y_pred - y_test))

# 結果の表示
mae, lr.coef_, lr.feature_names_in_
(0.5777090835157782,
 array([ -0.04669955,  -2.82587978,   6.62555705,   4.27804588,
        -11.089395  ,   7.44176542,   0.75973975,   1.02145469,
         10.61421819,   0.59526243]),
 array(['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6'],
       dtype=object))

MAEは約46.9

Code
mae = np.mean(np.abs(y_pred - y_test))
mae
0.5777090835157782

4 可視化

係数の大きさや相関を可視化することにより共変性がないか確認します

Code
1plt.bar(x=lr.feature_names_in_, height=lr.coef_)
1
係数の棒グラフを作成
<BarContainer object of 10 artists>

ここでは以下に注目します。 - s3(HDL)、s4(TCH)の係数が小さい

Code
corr = data.corr()
plt.title("相関のヒートマップ")
sns.heatmap(
    corr,
    annot=True
1    )
1
ヒートマップ
<Axes: title={'center': '相関のヒートマップ'}>

以下のことが見て取れます。 - S1(総コレステロール)とS2(LDL)の正の非常に高い相関がある - S3(HDL)とS4(TCH)に負の高い相関がある - target(糖尿病スコア)とs3以外の特徴量には正の相関がある

Code
1sns.pairplot(data)
1
ペアプロット

ペアプロットでも上記の性質が確認できます。 また、各分布はおおよそ正規分布に従っています。

5 考察

ヒートマップから分かるように、HDLと糖尿病スコアには負の中程度の相関があります。それにもかかわらず、重回帰モデルのHDLの係数は小さくなっています。これは、総コレステロールにHDLも含まれていることが原因と考えられます。総コレステロールとHDLのような関係を多重共線性と呼び、これらの変数が存在するとモデルの解釈が難しくなります。モデルに多重共線性があるかどうか調べる方法にVIFを求める手法があります。また、多重共線性のある特徴量のうち片方のみを利用することにより解釈可能な重回帰モデルが作成できます。

6 まとめ

  • 重回帰分析を利用して、健康診断データから糖尿病スコアを予測するモデルを作成
  • 予測に寄与している特徴量を調べるために係数を可視化
  • 多重線形性の存在により、一部の変数が実際の影響よりも低いスコアになっている

Footnotes

  1. https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset↩︎

  2. https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html↩︎

  3. https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset↩︎