【機械学習】多重共線性について

今回は機械学習モデルを作成する際、特に重回帰分析などで登場する多重共線性について解説していきたいと思います。機械学習モデル構築するためにはまず、データを収集します。そのデータには多様なデータ、特徴量が含まれています。一見するとすべての特徴量を使用した方が多くのデータからモデルを構築することが出来るため予測性能の良いモデルを作成することが出来ると考えられますが実際はどうなるのでしょうか。実験的側面、理論的側面から解説していきます。
はじめに
今回は機械学習モデルを作成する際、特に重回帰分析などで登場する多重共線性について解説していきたいと思います。機械学習モデル構築するためにはまず、データを収集します。そのデータには多様なデータ、特徴量が含まれています。一見するとすべての特徴量を使用した方が多くのデータからモデルを構築することが出来るため予測性能の良いモデルを作成することが出来ると考えられますが実際はどうなるのでしょうか。実験的側面、理論的側面から解説していきます。
概要
多重共線性とは説明変数間に相関があることで発生する問題のことです。説明変数間に相関があると、回帰係数の推定値が不安定になり信頼性が下がります。これにより間違ったモデルの解釈をしてしまったり、また説明変数の数が多くなるためモデルのが学習データに適合しすぎてしまう過学習の問題が生じます。まずは、回帰係数の推定値の問題から見ていきたいと思います。
重回帰分析とは
回帰係数の推定値について理解するためにまずは重回帰分析についておさらいします。重回帰分析とはある目的変数の値を、複数の説明変数で表現するとともに説明変数と目的変数の関係性を理解する分析手法のことです。
例えば、足の速さを年齢と身長によって説明することが考えられます。この時、回帰式は
$$
足の速さ = a * 年齢 + b * 身長 + c
$$
として表せられます。重回帰分析とはこの時の回帰係数と切片の値を与えられたデータから推定します。重回帰分析を行った結果
$$
足の速さ = -0.1 * 年齢 + 1.3 * 身長 + 0.5
$$
といった結果が得られるとします。この時、回帰係数とは各説明変数の影響度です。この回帰式からは年齢が1増えると-0.1の影響を目的変数、すなわち足の速さに及ぼすと解釈できます。例えば目的変数が店の売り上げであった場合、店の売り上げに貢献している因子は何なのかを分析し、さらに売り上げを上昇させる戦略を立てたり、店の売り上げを妨げているものを除外するような戦略を立てることが出来ます。
多重共線性と偏回帰変数
重回帰分析の概要を掴めました。では偏回帰係数はどの様に求めるのでしょうか。詳細は割愛しますが二乗誤差を最小化するように回帰式を求めます。すなわち求める回帰式が与えられたデータに対して二乗誤差最小という観点から最も当てはまりの良く決定されるということです。。
目的変数と説明変数の関係を以下のように表現します。
$$ y = X\beta + \epsilon $$
- yはn×1の目的変数のベクトル
- Xはn×pの独立変数の行列
- βはp×1の回帰係数のベクトル
- εはn×1の誤差項のベクトル
最小二乗法にしたがって最適化問題を解くと回帰係数の推定値は
$$ \hat{\beta} = (X^T X)^{-1} X^T y $$
として求められ、その推定値の分散は
$$ \text{Var}(\hat{\beta}) = \sigma^2 (X^T X)^{-1} $$
と導出することが出来ます。なおσ^2は誤差項の分散を表しています。ここで説明変数間に多重共線性が存在する場合、行列\(X^T X\)が特異(行列式が0に近く計算が不安定になる)になります。この時その逆行列の値が非常に大きくなっていしまい、推定値の分散が非常に大きくなってしまいます。これにより推定された偏回帰係数の信頼性が下がってしまうのです。
実験
ここまで理論的な側面から偏回帰係数の推定値が不安定になることを示しましたが実際に多重共線性のあるデータを用いて実験を行い確認していきます。今実験では説明変数を2つ用いて多重共線性のある場合、ない場合を実験します。それぞれの結果において推定値の標準誤差に差が出ることを確認し、多重共線性のある場合について実験毎ごとに推定値が大きく変わってしまうことを示します。
まずはデータの作成です。データ数は100で実験し、作成しました。
import numpy as np
import pandas as pd
from numpy.linalg import inv
import statsmodels.api as sm
# データセットの作成
n_samples = 100
多重共線性のある場合のデータ
# 多重共線性のあるデータセットの作成
X1 = np.random.normal(0, 1, n_samples)
X2 = 2 * X1 + np.random.normal(0, 0.1, n_samples) # X1と強い相関
y = 3 + 2 * X1 + np.random.normal(0, 1, n_samples)
# データフレームの作成
data_multicollinearity = pd.DataFrame({'X1': X1, 'X2': X2, 'y': y})
多重共線性のない場合のデータ
# 多重共線性のないデータセットの作成
X1_no_col = np.random.normal(0, 1, n_samples)
X2_no_col = np.random.normal(0, 1, n_samples)
y_no_col = 3 + 2 * X1_no_col + np.random.normal(0, 1, n_samples)
# データフレームの作成
data_no_multicollinearity = pd.DataFrame({'X1': X1_no_col, 'X2': X2_no_col, 'y': y_no_col})
次に重回帰分析を行う関数を定義します。
def perform_regression(data):
X = data[['X1', 'X2']]
y = data['y']
# 定数項を追加
X = sm.add_constant(X)
# OLS回帰の実行
model = sm.OLS(y, X).fit()
# 回帰係数とその標準誤差の取得
params = model.params
bse = model.bse
return params, bse
この関数を用いてそれぞれ実行していきます。
# 多重共線性のあるデータセットでの回帰分析
params_multicollinearity, bse_multicollinearity = perform_regression(data_multicollinearity)
# 結果の表示
print("多重共線性のあるデータセット:")
print("回帰係数の推定値:\n", params_multicollinearity)
print("標準誤差:\n", bse_multicollinearity)
# 多重共線性のないデータセットでの回帰分析
params_no_multicollinearity, bse_no_multicollinearity = perform_regression(data_no_multicollinearity)
print("\n多重共線性のないデータセット:")
print("回帰係数の推定値:\n", params_no_multicollinearity)
print("標準誤差:\n", bse_no_multicollinearity)
結果の出力を確認していきます。まずはそれぞれの回帰係数の標準誤差に関してです。
標準誤差 | 多重共線性のある場合 | 多重共線性のない場合 |
---|---|---|
const | 0.103 | 0.089 |
X1 | 1.983 | 0.101 |
X2 | 0.990 | 0.099 |
上記の結果から多重共線性のある場合、すべての項目において標準誤差が大きくなることが確認できました。
続いて多重共線性のある場合に関して何度かモデルを作成し、実際に偏回帰係数の推定値が大きく動いてしまうことを確認します。
推定値(多重共線性のある場合) | 一回目 | 二回目 | 三回目 |
---|---|---|---|
const | 2.973 | 3.003 | 3.171 |
X1 | -0.264 | 4.187 | 4.207 |
X2 | 1.094 | -1.177 | -1.087 |
このようにモデルを構築するごとに推定値にばらつきが見られ求められた推定値に信頼性がないことが確認できました。
終わりに
今回は多重共線性について理論的な側面と実験的な側面から確認しました。しかしながら各特徴量間にどれほど相関関係があれば適切なモデルが作成できないのか、また多重共線性がある場合どのように対処するべきなのかについて解説していません。これらの事柄については次回のブログで解説したいと思います。