import numpy as np
import matplotlib.pyplot as plt
# サンプルデータ(勉強時間と試験の点数)
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
y = np.array([35, 45, 50, 55, 60, 65, 70, 75, 85])
# データの可視化
plt.scatter(x, y)
plt.show()
回帰分析(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 は誤差項である.
単回帰分析(simple regression analysis)は,1つの説明変数 X を用いて目的変数 Y を予測・説明する手法である.単回帰分析では,X と Y の関係を線形モデルで表す.数学的には,以下のように表される.
Y = \beta_0 + \beta_1 X + \epsilon
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}_i = \hat{\beta}_0 + \hat{\beta}_1 x_i
と計算される.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}_1 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 の平均とする.
架空のデータセット \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
# サンプルデータ(勉強時間と試験の点数)
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
y = np.array([35, 45, 50, 55, 60, 65, 70, 75, 85])
# データの可視化
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)
# beta_1 の計算
numerator = np.sum((x - x_mean) * (y - y_mean))
denominator = np.sum((x - x_mean) ** 2)
beta_1 = numerator / denominator
# beta_0 の計算
beta_0 = y_mean - beta_1 * x_mean
return beta_0, beta_1最後に,上記の関数を用いて \hat{\beta}_0 と \hat{\beta}_1 を計算してみる.
# 回帰係数の計算
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 に近いことがわかる.
最後に,回帰直線をデータとともにプロットする.
# 回帰直線の描画
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()
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
カリフォルニア州の住宅価格データセットを用いて,収入を説明変数,住宅価格を目的変数として単回帰分析を行い,回帰直線を描画せよ.
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)
# ここにコードを書くhttps://www4.stat.ncsu.edu/~boos/var.select/diabetes.html↩︎