MATLABを用いた群間差の検出(ANOVA)



# 1. はじめに

この記事では、これまで統計に馴染みのなかった方にもわかりやすく、MATLABでの実装例を示しながらANOVA（分散分析）について丁寧に解説していきます。各セクションを通じて、ANOVAの概要・位置づけ・実践例・手法の仕組み・解釈方法を身につけられることを目指します。

ANOVA（Analysis of Variance：分散分析）は、複数の母集団（またはサンプル群）の平均値の差が偶然だけでは説明できないほど大きいかどうかをF検定を用いて判断する手法です。母集団とは、調査や研究の対象となる全体の集団を指します。例えば、ある薬の効果を調べる場合、その薬を使用するすべての人々が母集団となります。実際の調査では、母集団から一部を抽出して「標本」とし、分析を行います。

具体的には、ANOVAはグループ間のばらつき（Between-group variance）とグループ内のばらつき（Within-group variance）を比較し、前者が後者よりも十分に大きい場合に「少なくとも一つのグループ平均が他のグループ平均と有意に異なる」と判断します。

# 2. いつ使うか

分散分析は2群を比較するt検定の拡張版であり、グループが3つ以上ある場合に使います。グループが2つだけであればt検定で十分ですが、3つ以上のグループを比較すると、多重比較によって第一種の誤り率が上昇します。

例えば、3つの独立したt検定を有意水準α = 0.05で行った場合、各検定で誤って帰無仮説を棄却しない確率は0.95です。これらがすべて正しく帰無仮説を棄却しない確率は0.95³ ≈ 0.857です。したがって、少なくとも1つの検定で誤って帰無仮説を棄却する確率は1 - 0.857 ≈ 0.143、つまり約14.3%となり、第一種の誤りのリスクが累積して増加します。

ANOVAを使うことで、まず全体としてグループ間に差があるかを検証し、有意が認められた場合に事後検定（TukeyのHSD検定など）へと進むことができます。

# 3. 分散分析の種類

### 3.1. 一元配置分散分析（One-way ANOVA）

要因が1つで、複数の水準（グループ）がある場合に一元配置分散分析（One-way ANOVA）を用います。例えば、3種類の肥料（A、B、C）で栽培したプラントの収量を比較する場合などです。

### 3.2. 二元配置分散分析（Two-way ANOVA）

要因が2つ以上あり、交互作用効果を同時に検証したい場合は二元配置分散分析（Two-way ANOVA）を使います。例えば、「肥料の種類」と「栽培場所」の2つの要因がプラントの収量に与える影響を同時に調べたい場合などです。

# 4. 一元分散分析の方法

## 4.1. 仮定の確認

以下の仮定をデータが満たしているかを確認します。この仮定が満たされない場合は、ウェルチのANOVAや非パラメトリック検定（例えばKruskal-Wallis検定）などの代替手法を検討する必要があります。

- 独立性
    - 各データ（観測値）が他のデータに影響を与えず、互いに独立していることを指します。
- 正規性
    - 各グループのデータが「正規分布」に従っていることを指します。
- 等分散性
    - 各グループのデータのばらつき（分散）が同程度であることを指します。

## 4.2. グループ間変動の算出

- **グループ間変動（Between-group variance）**

グループ間変動とは各グループの平均値と全体平均とのズレの二乗和のことを指します。

$$
\text{SSB} = \sum_{i=1}^{k} N_i (\bar{X}_i - \bar{X})^2
$$

- $k$：グループの数
- $N_i$：グループ ii のサンプルサイズ
- $\bar{X}_i$：グループ ii の平均値
- $\bar{X}$：全体の平均値（全データの総平均）

## 4.3. グループ内変動の算出

- **グループ内変動（Within-group variance）**

グループ内変動とは各グループ内で観測値とそのグループ平均とのズレの二乗和のことを指します。

$$
\text{SSW} = \sum_{i=1}^{k} \sum_{j=1}^{n_i} (X_{ij} - \bar{X}_i)^2
$$

- $X_{ij}$：グループ i の j 番目の観測値


:::note info

**総変動（Total Sum of Squares: SST）** 

総変動とは各観測値と総平均の差の二乗和のことを指します。これはデータ全体のばらつきの総量を示します。

$$
 SST = \sum_{i=1}^{90} (X_i - \bar{X})^2
$$

SSTは以下の式を満たします。

$$
SST = SSB + SSW
$$

:::

## 4.4. 平均平方の算出

- **グループ間自由度**

$$
df_B = k - 1
$$

kはグループ数を表します


:::note info
グループ平均は総平均 $\bar{X}$を基準に差分を取ると

$$
\sum_{i=1}^{k} N_i (\bar{X}_i-\bar{X}) = 0
$$

という 1 本の線形制約を必ず満たします。重み付きの差分ベクトルは次元 *k* ですが、制約で 1 次元削られ自由度は **k − 1** です。

:::

- **グループ内自由度**

$$
 df_W = N - k
$$

N は全データ数、kはグループ数を表します

:::note info

グループ $i$ には $n_i$ 点ありますが、その平均 $\bar{X}_i$を計算すると「合計偏差=0」の制約がかかり自由に動けるのは $n_i − 1 $点になります。

$$
\sum_{j=1}^{n_i} (X_{ij} - \bar{X}_i) = 0
$$

それを全グループを足し合わせることで自由度はN-kとなります

$$
\sum_{i=1}^{k} (n_i - 1) = \left(\sum_{i=1}^{k} n_i\right) - k = N - k
$$

:::

- **平均平方（Mean Squares）**

変動を自由度で割る理由は、その値を「平均平方（Mean Square）」という「独立成分ひとつあたりの標準的なばらつき」に直すためです。

$$
\text{MS}_{\text{between}} = \frac{\text{SSB}}{df_B}
$$

$$
\text{MS}_{\text{within}} = \frac{\text{SSW}}{df_W}
$$

## 4.5. F値の計算と仮説の棄却

F 値は「グループ平均どうしのバラつきが、各グループ内部のバラつきの何倍あるか」を測る比率です。もしすべての母平均が本当に同じなら、両者は同じ大きさになるはずなので F≈1 に近づきます。

これらの比率（F値）を計算し、あらかじめ設定した有意水準（通常は5％）を超えれば「グループ間の差が偶然ではない」と判定します。

```math

\text{F} = \frac{\text{MS}_{\text{between}}}{\text{MS}_{\text{within}}}

```

# 5. 一元配置分散分析の具体例

ここでは、初心者向けの具体例として、「3種類の薬剤（Drug A, Drug B, Drug C）が血圧に与える影響」を調べる架空データを用いて、一元配置分散分析（One-way ANOVA）の流れを示します。ここでは仮定の確認については省略します。

## 5.1. データについて

以下の表は、各薬剤グループにランダムに30人ずつ（合計90人）を割り当て、1か月後の収縮期血圧（mmHg）を計測したことを想定したデータを利用します。

用いた具体的なデータは以下のとおりです。

<details><summary>【クリックで展開】患者データ（全90件）</summary>

|   Patient ID | Drug Group   |   Blood Pressure |
|-------------:|:-------------|-----------------:|
|            1 | A            |              137 |
|            2 | A            |              130 |
|            3 | A            |              130 |
|            4 | A            |              129 |
|            5 | A            |              135 |
|            6 | A            |              125 |
|            7 | A            |              137 |
|            8 | A            |              130 |
|            9 | A            |              133 |
|           10 | A            |              131 |
|           11 | A            |              136 |
|           12 | A            |              126 |
|           13 | A            |              131 |
|           14 | A            |              131 |
|           15 | A            |              135 |
|           16 | A            |              129 |
|           17 | A            |              131 |
|           18 | A            |              129 |
|           19 | A            |              132 |
|           20 | A            |              134 |
|           21 | A            |              129 |
|           22 | A            |              135 |
|           23 | A            |              135 |
|           24 | A            |              134 |
|           25 | A            |              135 |
|           26 | A            |              130 |
|           27 | A            |              132 |
|           28 | A            |              129 |
|           29 | A            |              131 |
|           30 | A            |              134 |
|           31 | B            |              131 |
|           32 | B            |              132 |
|           33 | B            |              131 |
|           34 | B            |              130 |
|           35 | B            |              131 |
|           36 | B            |              133 |
|           37 | B            |              130 |
|           38 | B            |              134 |
|           39 | B            |              138 |
|           40 | B            |              135 |
|           41 | B            |              132 |
|           42 | B            |              130 |
|           43 | B            |              131 |
|           44 | B            |              138 |
|           45 | B            |              133 |
|           46 | B            |              131 |
|           47 | B            |              134 |
|           48 | B            |              139 |
|           49 | B            |              133 |
|           50 | B            |              135 |
|           51 | B            |              134 |
|           52 | B            |              132 |
|           53 | B            |              130 |
|           54 | B            |              132 |
|           55 | B            |              132 |
|           56 | B            |              135 |
|           57 | B            |              136 |
|           58 | B            |              136 |
|           59 | B            |              134 |
|           60 | B            |              136 |
|           61 | C            |              129 |
|           62 | C            |              135 |
|           63 | C            |              133 |
|           64 | C            |              130 |
|           65 | C            |              132 |
|           66 | C            |              131 |
|           67 | C            |              134 |
|           68 | C            |              136 |
|           69 | C            |              138 |
|           70 | C            |              127 |
|           71 | C            |              127 |
|           72 | C            |              129 |
|           73 | C            |              131 |
|           74 | C            |              134 |
|           75 | C            |              132 |
|           76 | C            |              125 |
|           77 | C            |              130 |
|           78 | C            |              133 |
|           79 | C            |              132 |
|           80 | C            |              133 |
|           81 | C            |              130 |
|           82 | C            |              130 |
|           83 | C            |              132 |
|           84 | C            |              132 |
|           85 | C            |              132 |
|           86 | C            |              131 |
|           87 | C            |              129 |
|           88 | C            |              132 |
|           89 | C            |              131 |
|           90 | C            |              134 |

</details>



以下のようなデータとなっています。

| Patient ID | Drug Group | Blood Pressure |
| --- | --- | --- |
| 1 | A | 137 |
| 2 | A | 130 |
| 3 | A | 130 |
| ... | ... | ... |
| 30 | A | 134 |
| 31 | B | 131 |
| 32 | B | 132 |
| 33 | B | 131 |
| ... | ... | ... |
| 60 | B | 136 |
| 61 | C | 129 |
| 62 | C | 135 |
| 63 | C | 133 |
| ... | ... | ... |
| 90 | C | 134 |

（省略していますが、実際の数値は各グループに30人分の血圧データが記録されています）

## コード

先に今回用いたMATLABコードを以下に示します。

このMATLABコードは、血圧データに対して一元配置分散分析（ANOVA）を行い、薬剤グループ間で血圧に有意な差があるかを評価するものです。まずCSVからデータを読み込み、「Blood Pressure」列の平均（総平均および各グループ平均）を算出します。その後、`anova1` 関数でF検定を行い、p値を表示します。検定が有意な場合、`multcompare` 関数を使ってTukey-Kramer法・Bonferroni補正・FisherのLSD法といった複数の事後検定を適用し、どのグループ間に統計的な差があるかを詳細に比較します。

```rust
% テーブル読み込み（列名そのまま保持）
T = readtable('血圧.csv', ...
              'PreserveVariableNames', true, ...
              'VariableNamingRule', 'preserve');

% 「血圧」列を数値ベクトルに変換
bp = table2array(T(:, "Blood Pressure"));                    

% グループ列をcategoricalに変換
grp = categorical(T.("Drug Group"));  

% 一元配置分散分析の実行
[p, tbl, stats] = anova1(bp, grp, 'off');
disp(tbl);
fprintf('p-value = %.20f\n', p);

% overall mean
overallMean = mean(bp);
fprintf('Overall Mean = %.3f\n', overallMean);

% group means (option A: recent MATLAB)
g = groupsummary(T, "Drug Group", "mean", "Blood Pressure");
disp(g);

% 事後検定（Tukey HSD）
figure;
[c, m, h] = multcompare(stats, 'CType', 'tukey-kramer');

% Bonferroniによる検定
[c, m, h] = multcompare(stats, 'CType', 'bonferroni');

% FisherのLSD（ANOVA有意後に使用）
[c, m, h] = multcompare(stats, 'CType', 'lsd');

```

## 仮説設定

- 帰無仮説 $H_0$：3つの薬剤グループ（A, B, C）の平均血圧はすべて等しい。
- 対立仮説 $H_1$：少なくとも1つの薬剤グループの平均血圧が他と異なる。

有意水準を0.05としました

## 手順

1. **総平均$\bar{X}$** の計算
    - 全体90人の血圧を合計し、90で割って総平均を求めます
    - $\bar{X} = 132.1 mmHg$
2. **各グループ平均 $\bar{X}_A, \bar{X}_B, \bar{X}_C$** の計算
    - 薬剤Aグループの30人分の血圧を合計し、30で割る。同様に、Bグループ、Cグループそれぞれの平均を求めます
    - $\bar{X}_A = 131.8 mmHg$
    - $\bar{X}_B = 133.3 mmHg$
    - $\bar{X}_C = 131.5 mmHg$
3. **グループ間変動（Between-group Sum of Squares: SSB）** の計算
    - 各グループ平均と総平均の差の二乗に、グループのサンプル数を掛けたものを合計します
        
        $$
         SSB = 30 (\bar{X}_A - \bar{X})^2 + 30 (\bar{X}_B - \bar{X})^2 + 30 (\bar{X}_C - \bar{X})^2=54.3
        $$
        
    - これは「グループ平均が全体平均からどれだけずれているか」によるばらつきを示します
4. **グループ内変動（Within-group Sum of Squares: SSW）** の計算
    - 各グループ内の観測値とそのグループ平均の差の二乗和を、すべてのグループで合計します
        
        ```math
        SSW = \sum_{i \in A}(X_i - \bar{X}_A)^2 + \sum_{i \in B}(X_i - \bar{X}_B)^2 + \sum_{i \in C}(X_i - \bar{X}_C)^2=675.5
        ```
        
    - これは「同じグループ内でのばらつき」を示します。
5. **自由度の設定と平均平方（Mean Squares: MS）** の計算
    - グループ間の自由度：
    
    $$
    f_{B} = k - 1 = 3 - 1 = 2
    $$
    
    - グループ内の自由度：
    
    $$
    df_{W} = N - k = 90 - 3 = 87
    $$
    
    - グループ間平均平方：
    
    $$
    MSB = \tfrac{SSB}{df_B} =27.1
    $$
    
    - グループ内平均平方：
    
    $$
    MSW = \tfrac{SSW}{df_W} = 7.8
    $$
    
6. **F値の計算**
    
    $$
    F = \frac{MSB}{MSW} =3.5
    $$
    
    - このF値を、自由度 $(df_B, df_W) = (2, 87)$ のF分布を用いてp値を求めます。F分布の上側累積確率は以下のようになリます。つまりp値は0.034となります。
        
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596508/48dfe6e2-0653-4361-8836-c82cbf67c662.png)

        

        
7. **結論の導出**
    - p値が有意水準（0.05）より小さいので、帰無仮説を棄却し、「少なくとも一つの薬剤の平均血圧は他と有意に異なる」と判断します。ただし、「どの薬剤の差か」はANOVAだけでは特定できないため、TukeyのHSD検定などでペアごとの比較を行います。


:::note info
**事後検定（Tukey HSD）の例**
![tukey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596508/1927f1f4-83b3-48ec-a7e6-eff0ae051394.png)


- AとBもしくはAとCの平均の間には有意差がないと判断できます

**事後検定（LSD）の例**
![lsd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596508/5cf1f073-9e99-4ff7-9b5b-58d2ac55ec9d.png)



- AとBの平均の間に有意差があると判断できます


**結論例**

事後検定の結果、FisherのLSD法ではグループAとBの間に有意差が認められましたが、Tukey HSD法ではこの差は有意とはなりませんでした。

:::

# まとめ

本記事では、ANOVA（分散分析）の概念や使い方を、統計に親しみのない方でも理解しやすいよう、基本から丁寧に解説しました。まず、ANOVAは複数のグループ間の平均値の差を評価する統計手法であり、その種類や手順を紹介しました。次に、実際のデータを用いてMATLABでの実行方法を具体例とともに説明し、内部でどのような数式が使われ、結果から何が読み取れるかを示しました。これにより、ANOVAの流れを一通り把握でき、実際に自分のデータにも応用しやすくなるはずです。今後は、二元配置ANOVAや繰り返し測定ANOVAなどを学んでいきます。