統計検定2級 水準間平方和、残差平方和

## はじめに
今回は統計検定2級の範囲の水準間平方和、残差平方和に関して学びます。分散分析（ANOVA）を勉強していると出てくる「水準間平方和」と「残差平方和」。 なんだコレって、なったので記事にしています。

## ✅ 「分散分析」って何？

複数のグループの**平均値に差があるかどうか**を調べる統計手法です。

たとえば：

- A社、B社、C社の平均売上に差があるか？
- 3種類の薬の効果に違いがあるか？

---

## 🟦 水準間平方和とは？

### ✔ グループどうしの「平均の差」

> **水準間平方和**は、「グループの平均値が、全体平均からどれくらいズレているか」を表します。

つまり、「グループ間に差があるか？」を数値化するためのものです。

---

### ✔ 具体例でイメージ！

| クラス | 平均点 | 全体平均との差 | 差の2乗 × 人数     |
|--------|--------|------------------|----------------------|
| A      | 60点   | -10点            | 10² × 3 = 300        |
| B      | 80点   | +10点            | 10² × 2 = 200        |

水準間平方和 = 300 + 200 = **500**

---

## ✔ 数式で書くと

$$
\text{水準間平方和} = \sum_{j=1}^{k} n_j (\bar{y}_j - \bar{y})^2
$$

- $k$：グループの数  
- $n_j$：グループ $j$ のデータ数  
- $\bar{y}_j$：グループ $j$ の平均  
- $\bar{y}$：全体の平均

---

### ✔ 名前の意味を分解すると

| 用語         | 意味                                       |
|--------------|--------------------------------------------|
| 水準         | グループ（例：クラスや商品タイプなど）     |
| 間           | グループとグループの“あいだ”               |
| 平方         | 差を2乗する（マイナスを打ち消すため）      |
| 和           | 全部足す                                    |

---

## 🟨 残差平方和とは？

### ✔ 同じグループ内での「ばらつき」

> **残差平方和**は、「各データが、そのグループの平均からどれだけズレているか」を表します。

つまり、「グループ内で点数がバラついているか？」を数値で見ます。

---

### ✔ 「残差」ってなに？

**残差**＝ 実際の値 − グループの平均  
たとえば：

| 学生 | クラス | 点数 | クラス平均 | 残差 |
|------|--------|------|-------------|------|
| A    | 1組    | 70点 | 60点        | +10点 |
| B    | 1組    | 50点 | 60点        | -10点 |

残差平方和は、この**残差の2乗を全部足したもの**です。

---

### ✔ 数式で書くと

$$
\text{残差平方和} = \sum_{j=1}^{k} \sum_{i=1}^{n_j} (y_{ij} - \bar{y}_j)^2
$$

- $y_{ij}$：グループ $j$ の $i$ 番目のデータ  
- $\bar{y}_j$：グループの平均

---

### ✔ 名前の意味を分解すると

| 用語           | 意味                                 |
|----------------|--------------------------------------|
| 残差           | 実際の値と、グループ平均の差        |
| 平方           | 差を2乗する（マイナスを打ち消すため）|
| 和             | 全部足す                             |

---

## 🔁 2つの平方和の違いまとめ

| 用語             | 見ているもの                     |
|------------------|----------------------------------|
| 水準間平方和     | グループどうしの**平均の差**     |
| 残差平方和       | グループ内の**ばらつき（ズレ）** |

---

## 🔧 全体の関係式

分散分析では、全体のバラつき（全体平方和）を次のように分けます：

$$
\text{全体平方和（SST）} = \text{水準間平方和（SSB）} + \text{残差平方和（SSE）}
$$


### ✅ 問題

ある学校で、A組・B組・C組の3クラスについて、テストの点数を以下のように調査しました。

| クラス | 点数                  |
|--------|-----------------------|
| A組    | 60, 65, 70            |
| B組    | 80, 75                |
| C組    | 50, 55, 60            |

このデータをもとに、以下の値を求めなさい。

---

### ❓ 計算するもの

1. 各クラスの平均点、および全体の平均点  
2. **水準間平方和（SSB）**  
3. **残差平方和（SSE）**


## 🧮 解き方と解説：水準間平方和・残差平方和の計算

---

### ✅ ステップ①：各クラスと全体の平均を出す

| クラス | 点数                  | 合計 | 人数 | 平均         |
|--------|-----------------------|------|------|--------------|
| A組    | 60, 65, 70            | 195  | 3    | 65.0         |
| B組    | 80, 75                | 155  | 2    | 77.5         |
| C組    | 50, 55, 60            | 165  | 3    | 55.0         |
| 全体   | 合計 = 195 + 155 + 165 = 515 |      | 合計 = 8人 | 全体平均 = 515 ÷ 8 = 64.375 |

---

### ✅ ステップ②：水準間平方和（SSB）を求める

$$
SSB = \sum_{j=1}^{k} n_j (\bar{y}_j - \bar{y})^2
$$

- A組：$3 \times (65.0 - 64.375)^2 = 3 \times (0.625)^2 = 1.171875$
- B組：$2 \times (77.5 - 64.375)^2 = 2 \times (13.125)^2 = 344.53125$
- C組：$3 \times (55.0 - 64.375)^2 = 3 \times (-9.375)^2 = 263.671875$

**合計：**
$$
SSB = 1.171875 + 344.53125 + 263.671875 = \mathbf{609.375}
$$

---

### ✅ ステップ③：残差平方和（SSE）を求める

$$
SSE = \sum_{j=1}^{k} \sum_{i=1}^{n_j} (y_{ij} - \bar{y}_j)^2
$$

#### 各クラスで計算：

- **A組**（平均65）  
  $(60 - 65)^2 + (65 - 65)^2 + (70 - 65)^2 = 25 + 0 + 25 = 50$

- **B組**（平均77.5）  
  $(80 - 77.5)^2 + (75 - 77.5)^2 = 6.25 + 6.25 = 12.5$

- **C組**（平均55）  
  $(50 - 55)^2 + (55 - 55)^2 + (60 - 55)^2 = 25 + 0 + 25 = 50$

**合計：**
$$
SSE = 50 + 12.5 + 50 = \mathbf{112.5}
$$

---

### ✅ 最終結果まとめ

| 指標             | 値           |
|------------------|--------------|
| 全体平均         | 64.375       |
| 水準間平方和 SSB | **609.375**  |
| 残差平方和 SSE   | **112.5**    |

---

### ✅ 補足：全体平方和も求められる

$$
SST = SSB + SSE = 609.375 + 112.5 = \mathbf{721.875}
$$


```py:
# 📌 日本語フォントインストール（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

# 日本語フォント設定（明示的に使用）
jp_font = FontProperties(fname="/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf")

# データ定義
data = {
    'A': [60, 65, 70],
    'B': [80, 75],
    'C': [50, 55, 60]
}

# 平均・全体平均
class_means = {k: np.mean(v) for k, v in data.items()}
all_scores = [score for scores in data.values() for score in scores]
overall_mean = np.mean(all_scores)
class_sizes = {k: len(v) for k, v in data.items()}

# 平方和計算
ssb = sum(class_sizes[k] * (class_means[k] - overall_mean) ** 2 for k in data)
sse = sum((score - class_means[k]) ** 2 for k, scores in data.items() for score in scores)
sst = ssb + sse

# 結果表示
print("【各クラスの平均】")
for k in data:
    print(f"{k}組の平均: {class_means[k]:.3f} 点")
print(f"\n【全体の平均】: {overall_mean:.3f} 点")
print(f"\n【水準間平方和 (SSB)】: {ssb:.3f}")
print(f"【残差平方和 (SSE)】: {sse:.3f}")
print(f"【全体平方和 (SST)】: {sst:.3f}")

# グラフ描画
fig, ax = plt.subplots(figsize=(10, 6))
colors = {'A': 'skyblue', 'B': 'salmon', 'C': 'lightgreen'}
x_pos = 0
xticks = []
xtick_labels = []

for group, scores in data.items():
    xs = np.arange(x_pos, x_pos + len(scores))
    ys = scores
    ax.scatter(xs, ys, color=colors[group], label=f"{group}組の点数", zorder=3)
    ax.hlines(class_means[group], xmin=xs[0]-0.3, xmax=xs[-1]+0.3,
              color=colors[group], linestyle='--', label=f"{group}組 平均: {class_means[group]:.1f}点")
    x_pos += len(scores) + 1
    xticks.extend(xs)
    xtick_labels.extend([f"{group}{i+1}" for i in range(len(scores))])

# 全体平均線
ax.hlines(overall_mean, xmin=-1, xmax=x_pos-1, color='black',
          linestyle=':', linewidth=2, label=f"全体平均: {overall_mean:.1f}点")

# ラベル設定（すべて fontproperties=jp_font を明示）
ax.set_xticks(xticks)
ax.set_xticklabels(xtick_labels, rotation=45, fontproperties=jp_font)
ax.set_ylabel("点数", fontproperties=jp_font)
ax.set_title("各クラスの点数と平均（分散分析のイメージ）", fontproperties=jp_font)
ax.legend(prop=jp_font)
ax.grid(True)
plt.tight_layout()
plt.show()
```

```shell
【各クラスの平均】
A組の平均: 65.000 点
B組の平均: 77.500 点
C組の平均: 55.000 点

【全体の平均】: 64.375 点

【水準間平方和 (SSB)】: 609.375
【残差平方和 (SSE)】: 112.500
【全体平方和 (SST)】: 721.875
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/722e1016-d956-484f-a23a-f29e9fa158be.png)


:::note info
これで、水準間平方和、残差平方和が理解できました。ただ、この値出てきてなんなの？？🤔って感じですね。
結局ここの値から何か示唆が得られていないので、このままではなんの価値もない値です。なので、次はF検定を学ぼうと思います！！
:::