統計検定2級 重回帰分析

## はじめに
今回は統計検定2級の範囲である重回帰分析に関して学んでいこうと思います！！！

## 🔷 重回帰分析（Multiple Linear Regression）とは？

### 💡 定義  
重回帰分析とは、<strong>2つ以上の説明変数(独立変数)</strong>を使って、<strong>1つの目的変数（従属変数）</strong>を予測・説明する回帰モデルです。

---

### 📐 数式の形（2変数の場合）

$$
y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \varepsilon
$$

- $y$：目的変数（例：消費支出）  
- $x_1$：説明変数1（例：定期収入）  
- $x_2$：説明変数2（例：賞与）  
- $\beta_0$：切片（定数項）  
- $\beta_1$, $\beta_2$：各説明変数の係数（効果の大きさ）  
- $\varepsilon$：誤差項（実測値と予測値のずれ）

---

### 🧭 使う場面の例

| 目的変数 | 説明変数 |
|----------|-----------|
| 消費支出 | 定期収入、賞与 |
| 売上     | 広告費、SNS投稿数、サイト訪問者数 |
| 体重     | カロリー摂取量、運動時間、年齢 |

---

### ✅ 単回帰分析との違い

| 比較項目         | 単回帰分析                 | 重回帰分析                   |
|------------------|----------------------------|-------------------------------|
| 説明変数の数     | 1つ                         | 2つ以上                        |
| モデルの構造     | 単純な一次関係             | より複雑な関係も扱える        |
| 注意点           | 少ない                     | 多重共線性に注意が必要        |

---

## 📘 重回帰分析の例題

ある地域で、以下のように「定期収入」「賞与」「消費支出」の3項目を10世帯から調査しました

| 世帯 | 定期収入 ($x_1$) | 賞与 ($x_2$) | 消費支出 ($y$) |
|------|------------------|--------------|----------------|
| 1    | 28.0             | 5.0          | 26.9           |
| 2    | 35.0             | 6.6          | 32.0           |
| 3    | 30.6             | 5.3          | 30.9           |
| 4    | 33.5             | 6.4          | 30.9           |
| 5    | 27.6             | 4.4          | 26.4           |
| 6    | 29.9             | 5.6          | 30.3           |
| 7    | 36.6             | 8.0          | 32.4           |
| 8    | 34.8             | 7.9          | 30.7           |
| 9    | 30.0             | 5.0          | 29.0           |
| 10   | 31.5             | 6.0          | 30.0           |

---

### ❓ 問題

1. このデータに対して、重回帰モデル：

   $$
   y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \varepsilon
   $$

   を最小二乗法で求めなさい

2. 回帰係数 $\beta_1$ の意味を日本語で説明しなさい

3. $x_1 = 32$, $x_2 = 6$ のとき、$y$ の予測値を求めなさい

4. $\beta_2$ の p値が 0.06 であるとき、賞与は消費支出に統計的に有意な影響があるか？


## 🧮 重回帰分析の係数を最小二乗法で求める（数学的アプローチ）

### ✅ 重回帰モデルの一般形

$$
y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \varepsilon
$$

行列形式では：

$$
\mathbf{y} = \mathbf{X} \boldsymbol{\beta} + \boldsymbol{\varepsilon}
$$

- $\mathbf{y}$：目的変数（$n \times 1$ ベクトル）  
- $\mathbf{X}$：説明変数（$n \times p$ 行列、ここでは $p=3$：定数項 + 2変数）  
- $\boldsymbol{\beta}$：係数ベクトル（$p \times 1$）  
- $\boldsymbol{\varepsilon}$：誤差ベクトル

---

### ✅ ステップ1：データ行列を作る

例として、以下のようなデータ（10件）を用います：

| 定期収入 $x_1$ | 賞与 $x_2$ | 消費支出 $y$ |
|----------------|------------|--------------|
| 28.0           | 5.0        | 26.9         |
| 35.0           | 6.6        | 32.0         |
| 30.6           | 5.3        | 30.9         |
| 33.5           | 6.4        | 30.9         |
| 27.6           | 4.4        | 26.4         |
| 29.9           | 5.6        | 30.3         |
| 36.6           | 8.0        | 32.4         |
| 34.8           | 7.9        | 30.7         |
| 30.0           | 5.0        | 29.0         |
| 31.5           | 6.0        | 30.0         |

---

### ✅ ステップ2：最小二乗法の公式を使う

回帰係数ベクトルは次の式で求められます：

$$
\boldsymbol{\hat{\beta}} = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{y}
$$

ここで：

- $\mathbf{X}$ は各データ行に定数項 1 を追加した $10 \times 3$ 行列  
- $\mathbf{y}$ は消費支出のベクトル（$10 \times 1$）

---

### ✅ Pythonで計算するコード（NumPy）

```python
# 📌 Google Colab専用：日本語フォントのインストール
!apt-get -y install fonts-ipafont-gothic > /dev/null

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from mpl_toolkits.mplot3d import Axes3D

# 日本語フォント設定
jp_font = FontProperties(fname="/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf")
plt.rcParams['font.family'] = jp_font.get_name()

# データ
x1 = np.array([28.0, 35.0, 30.6, 33.5, 27.6, 29.9, 36.6, 34.8, 30.0, 31.5])
x2 = np.array([5.0, 6.6, 5.3, 6.4, 4.4, 5.6, 8.0, 7.9, 5.0, 6.0])
y = np.array([26.9, 32.0, 30.9, 30.9, 26.4, 30.3, 32.4, 30.7, 29.0, 30.0])

# デザイン行列
X = np.column_stack((np.ones(len(x1)), x1, x2))

# 最小二乗法で係数を計算
beta = np.linalg.inv(X.T @ X) @ (X.T @ y)

# 予測関数
def predict(x1, x2):
    return beta[0] + beta[1] * x1 + beta[2] * x2

# グリッドを作成して予測面を描画
x1_range = np.linspace(min(x1), max(x1), 20)
x2_range = np.linspace(min(x2), max(x2), 20)
X1_grid, X2_grid = np.meshgrid(x1_range, x2_range)
Y_pred = predict(X1_grid, X2_grid)

# プロット
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(x1, x2, y, color='blue', label='観測データ')
surface = ax.plot_surface(X1_grid, X2_grid, Y_pred, alpha=0.5, color='red', label='回帰面')

# ラベル設定（日本語）
ax.set_xlabel('定期収入（万円）', fontproperties=jp_font)
ax.set_ylabel('賞与（万円）', fontproperties=jp_font)
ax.set_zlabel('消費支出（万円）', fontproperties=jp_font)
ax.set_title('重回帰モデルによる回帰面', fontproperties=jp_font)

# 凡例（日本語ラベル対応）
from matplotlib.lines import Line2D
custom_lines = [
    Line2D([0], [0], marker='o', color='w', label='観測データ',
           markerfacecolor='blue', markersize=10),
    Line2D([0], [0], color='red', lw=4, label='回帰面')
]
ax.legend(handles=custom_lines, prop=jp_font)

plt.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/9f6bb8f8-e713-4f26-892e-9c046b6b0fb0.png)