12  単回帰分析

回帰分析(regression analysis)とは、ある変数 \(Y\) を他の変数 \(X_1, X_2, \ldots, X_p\) を用いて予測・説明するための統計的手法である。\(Y\) を目的変数、\(X_1, X_2, \ldots, X_p\) を説明変数と呼ぶ。回帰分析は、経済学、社会学、医学、工学など様々な分野で応用されている。

例えば、以下のような例がある。

説明変数 \(X\) 目的変数 \(Y\)
気温 アイスクリームの売上
広告費 商品の売上
勉強時間 試験の点数
面積、築年数 住宅価格

\(X = (X_1, X_2, \ldots, X_p)\) とすると、説明変数 \(X\) と目的変数 \(Y\) の関係は以下のように表される。

\[ Y = f(X) + \epsilon \]

ここで、\(f\) は説明変数 \(X\) と目的変数 \(Y\) の関係を表す関数、\(\epsilon\) は誤差項である。

12.1 単回帰分析

単回帰分析(simple regression analysis)は、1つの説明変数 \(X\) を用いて目的変数 \(Y\) を予測・説明する手法である。単回帰分析では、\(X\)\(Y\) の関係を線形モデルで表す。数学的には、以下のように表される。

\[ Y = \beta_0 + \beta_1 X + \epsilon \]

12.1.1 パラメータの推定

\(n\) 組の観測データ

\[ \mathcal{D} = \{(x_1, y_1), (x_2, y_2), \ldots, (x_n, y_n)\} \]

が与えられたとき、データからパラメータ \(\beta_0\)\(\beta_1\) を推定する。推定されたパラメータをそれぞれ \(\hat{\beta}_0\)\(\hat{\beta}_1\) と表す。これらのパラメータを用いて、\(x_i\) に対する予測値 \(\hat{y}_i\)

\[ \hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x \]

と計算される。\(x_i\) に対する予測値 \(\hat{y}_i\) と実際の観測値 \(y_i\) の差を残差(residual)と呼び、以下のように定義される。

\[ e_i = y_i - \hat{y}_i \]

残差平方和(residual sum of squares, RSS)は残差の二乗の和であり、以下のように定義される。

\[ \text{RSS} = \sum_{i=1}^{n} e_i^2 = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \]

これを展開すると、

\[ \text{RSS} = (y_1 - \hat{\beta}_0 - \hat{\beta}_1 x_1)^2 + (y_2 - \hat{\beta}_0 - \hat{\beta}_1 x_2)^2 + \ldots + (y_n - \hat{\beta}_0 - \hat{\beta} x_n)^2 \]

となる。RSS を最小化する \(\hat{\beta}_0\)\(\hat{\beta}_1\) を求める方法を最小二乗法(least squares method)と呼ぶ。

計算より、最小二乗法により求められる \(\hat{\beta}_0\)\(\hat{\beta}_1\) は以下のように表される。

\[ \hat{\beta}_1 = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^{n}(x_i - \bar{x})^2} \]

\[ \hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x} \]

ここで、\(\bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i\), \(\bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_i\) をそれぞれ \(x\) および \(y\) の平均とする。

12.1.2 実装

架空のデータセット \(\mathcal{D}\) を用いて、勉強時間と試験の点数の関係を分析する。

\[ \mathcal{D} = \{(1, 35), (2, 45), (3, 50), (4, 55), (5, 60), (6, 65), (7, 70), (8, 75), (9, 85)\} \]

勉強時間を説明変数 \(X\)、試験の点数を目的変数 \(Y\) とする。次のコードは、データの可視化を行う。

import numpy as np
import matplotlib.pyplot as plt

# 1. Sample Data (Hours studied vs Test Score)
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
y = np.array([35, 45, 50, 55, 60, 65, 70, 75, 85])

# 2. Visualize the Data
plt.scatter(x, y)
plt.show()

与えられた \(\mathcal{D}\) から \(\hat{\beta}_0\)\(\hat{\beta}_1\) を計算する関数を以下に示す。

import numpy as np

def simple_linear_regression(x, y):
    n = len(x)
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    
    # Calculate beta_1
    numerator = np.sum((x - x_mean) * (y - y_mean))
    denominator = np.sum((x - x_mean) ** 2)
    beta_1 = numerator / denominator
    
    # Calculate beta_0
    beta_0 = y_mean - beta_1 * x_mean
    
    return beta_0, beta_1

最後に、上記の関数を用いて \(\hat{\beta}_0\)\(\hat{\beta}_1\) を計算してみる。

# Calculate coefficients
beta_0, beta_1 = simple_linear_regression(x, y)
print(f"Intercept (β0): {beta_0}")
print(f"Slope (β1): {beta_1}")
Intercept (β0): 31.666666666666664
Slope (β1): 5.666666666666667

これで,与えられた勉強時間 \(x\) に対する試験の点数の予測値 \(\hat{y}\) を次のように計算できる。

\[ \hat{y} \approx 31.6667 + 5.6667 x \]

例えば、勉強時間が 4 時間のとき、試験の点数の予測値は

\[ \hat{y} \approx 31.6667 + 5.6667 \times 4 \approx 54.3335 \]

となる。この予測値は、実際の観測値 \(y = 55\) に近いことがわかる。

最後に、回帰直線をデータとともにプロットする。

# Plot the regression line
plt.scatter(x, y, color="blue", label="Data points")
plt.plot(x, beta_0 + beta_1 * x, color="red", linewidth=2, label="Regression line")
plt.xlabel("X (Hours studied)")
plt.ylabel("y (Test Score)")
plt.title("Simple Linear Regression")
plt.legend()
plt.show()

Notescikit-learn を用いた単回帰分析の例

Python では、scikit-learn ライブラリを用いて回帰分析を簡単に実装できる。以下に、単回帰分析の例を示す。

次に、線形回帰モデルを作成し、\(\hat{\beta}_0\)\(\hat{\beta}_1\) を計算する。データからパラメータを推定することを学習(learning)、フィッティング(fitting)、トレーニング(training)と呼ぶ。

LinearRegression() からモデルを作成し、fit() にデータ Xy を与えて、\hat{\beta}_0\hat{\beta}_1 を計算する。

from sklearn.linear_model import LinearRegression

# 1. Sample Data (Hours studied vs Test Score)
X = np.array([[1], [2], [3], [4], [5], [6], [7], [8], [9]])
y = np.array([35, 45, 50, 55, 60, 65, 70, 75, 85])

# 2. Create and Fit the Model
model = LinearRegression()
model.fit(X, y)

# 3. Print the coefficients
print(f"Intercept (β0): {model.intercept_}")
print(f"Slope (β1): {model.coef_[0]}")
Intercept (β0): 31.666666666666664
Slope (β1): 5.666666666666667

12.1.3 糖尿病データセットの例

load_diabetes 関数を用いて糖尿病データセットを読み込み、BMIを説明変数、糖尿病の進行度を目的変数として単回帰分析を行う。ここでは,BMIが標準化されていることに注意 1

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_diabetes

# 糖尿病データセットの読み込み
diabetes = load_diabetes(as_frame=True)

# BMI を説明変数、糖尿病の進行度を目的変数とする
X = diabetes.data[["bmi"]]
y = diabetes.target

# 線形回帰モデルの作成と学習
model = LinearRegression()
model.fit(X, y)

# 回帰直線の描画
plt.scatter(X, y, color="blue", label="Data points")
plt.plot(X, model.predict(X), color="red", linewidth=2, label="Regression line")
plt.xlabel("X (BMI)")
plt.ylabel("y (Diabetes Progression)")
plt.title("Simple Linear Regression")
plt.legend()
plt.show()

# 回帰係数の表示
print(f"Intercept (β0): {model.intercept_}")
print(f"Slope (β1): {model.coef_[0]}")

Intercept (β0): 152.13348416289617
Slope (β1): 949.4352603840388
Note回帰分析と因果関係

回帰分析は、変数間の関係性をモデル化する手法であり、必ずしも因果関係を示すものではない。例えば、アイスクリームの売上と水難事故の発生件数には正の相関があるが、これは両者が夏季に増加するという共通の要因によるものであり、アイスクリームの売上が水難事故を引き起こすわけではない。このように、回帰分析の結果を解釈する際には、因果関係と相関関係を区別することが重要である。

12.1.4 練習問題

カリフォルニア州の住宅価格データセットを用いて、収入を説明変数、住宅価格を目的変数として単回帰分析を行い、回帰直線を描画せよ。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing

# カリフォルニア州の住宅価格データセットの読み込み
housing = fetch_california_housing(as_frame=True)

# 収入を説明変数、住宅価格を目的変数とする
X = housing.data[["MedInc"]]  # 所得を説明変数とする
y = housing.target  # 住宅価格を目的変数とする

# 線形回帰モデルの作成と学習
model = LinearRegression()
model.fit(X, y)

# ここにコードを書く

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