回帰分析では、ある説明変数が結果に与える影響が、別の変数の値によって変わることがあります。このような「効果の修飾(effect modification)」をモデルに組み込むのが**交互作用項(interaction term)**です。 ここでは、小学生の**身長(cm)**を結果変数、**学年**と**性別**を説明変数とする例で考えます。男子は1年生の時点で女子より身長が高く、さらに学年が上がるにつれて男女差が広がっていきます。つまり、「学年が上がることによる身長の増加量」が性別によって異なります。これが交互作用です。 ## サンプルデータ 以下は架空の小学生データ(各学年・男女1名ずつ、計12名)です。「男」という変数を用意し、男子 = 1、女子 = 0 とコーディングしています。 | ID | 性別 | 男 | 学年 | 身長 (cm) | |----|------|-----|------|-----------| | 1 | 女子 | 0 | 1 | 115 | | 2 | 女子 | 0 | 2 | 120 | | 3 | 女子 | 0 | 3 | 126 | | 4 | 女子 | 0 | 4 | 130 | | 5 | 女子 | 0 | 5 | 135 | | 6 | 女子 | 0 | 6 | 141 | | 7 | 男子 | 1 | 1 | 121 | | 8 | 男子 | 1 | 2 | 129 | | 9 | 男子 | 1 | 3 | 135 | | 10 | 男子 | 1 | 4 | 142 | | 11 | 男子 | 1 | 5 | 148 | | 12 | 男子 | 1 | 6 | 156 | 女子は約 5 cm/年のペースで伸びています。男子は1年生の時点で女子より 6 cm 高く、伸び率も約 7 cm/年と大きいため、学年が上がるほど差が開いていきます。 ## モデルの構築:3段階で理解する ### モデル1:学年のみ(単回帰) $ \text{身長}_i = \beta_0 + \beta_1 \cdot \text{学年}_i + \varepsilon_i $ 最も単純なモデルで、性別を無視しています。学年が1つ上がるごとに身長が $\beta_1$ cm 増えると仮定しており、男女の違いは考慮されません。 ```stata regress height grade ``` ``` ------------------------------------------------------------------------------ height | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- grade | 5.971429 1.027697 5.81 0.000 3.680728 8.262129 _cons | 112.2667 4.002392 28.05 0.000 103.3446 121.1887 ------------------------------------------------------------------------------ ``` ### モデル2:学年+性別(主効果のみ) $ \text{身長}_i = \beta_0 + \beta_1 \cdot \text{学年}_i + \beta_2 \cdot \text{男}_i + \varepsilon_i $ このモデルでは性別による切片の違いを許しています。式を性別ごとに書き下してみます。 **女子(男 = 0)のとき:** $ \text{身長} = \beta_0 + \beta_1 \cdot \text{学年} $ **男子(男 = 1)のとき:** $ \text{身長} = (\beta_0 + \beta_2) + \beta_1 \cdot \text{学年} $ > 2本の回帰直線は**平行**になります。傾き $\beta_1$(学年あたりの身長増加量)は男女共通で、切片だけが $\beta_2$ だけずれます。つまり「男子は女子よりどの学年でも一律に $\beta_2$ cm 高い」という仮定を置いています。 ```stata regress height grade male ``` ``` ------------------------------------------------------------------------------ height | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- grade | 5.971429 .2997619 19.92 0.000 5.293127 6.649731 male | 10.66667 1.023879 10.42 0.000 8.350158 12.98317 _cons | 106.9333 1.274709 83.89 0.000 104.0491 109.8176 ------------------------------------------------------------------------------ ``` しかし現実には、学年が上がるにつれて男女差が広がっていきます。これは「傾き」自体が男女で異なることを意味しており、平行な直線では表現できません。 ![[interaction_model2.png]] ### モデル3:交互作用あり $ \text{身長}_i = \beta_0 + \beta_1 \cdot \text{学年}_i + \beta_2 \cdot \text{男}_i + \beta_3 \cdot (\text{学年}_i \times \text{男}_i) + \varepsilon_i $ ここで $\beta_3 \cdot (\text{学年}_i \times \text{男}_i)$ が**交互作用項**です。学年と性別の積(product)を新たな変数として追加しています。 ```stata regress height c.grade##i.male ``` ``` ------------------------------------------------------------------------------ height | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- grade | 5.114286 .1360147 37.60 0.000 4.800642 5.427929 1.male | 4.666667 .7492396 6.23 0.000 2.938642 6.394691 | male#c.grade | 1 | 1.714286 .1923424 8.91 0.000 1.270585 2.157987 | _cons | 109.9333 .5296879 207.52 0.000 108.7119 111.1548 ------------------------------------------------------------------------------ ``` `c.grade##i.male` は Stata の factor variable 記法で、主効果と交互作用項を同時に投入します。手動で変数を作成する方法もあります。 ```stata gen grade_male = grade * male regress height grade male grade_male ``` ![[interaction_model3.png]] モデル2では2本の直線が平行でしたが、モデル3では**切片も傾きも異なる**2本の直線になっています。 ## 交互作用項の式変形 モデル3を変形し、各係数の意味を明らかにします。 ### 学年でくくる $ \begin{aligned} \text{身長} &= \beta_0 + \beta_1 \cdot \text{学年} + \beta_2 \cdot \text{男} + \beta_3 \cdot \text{男} \cdot \text{学年} \\[6pt] &= \beta_0 + \beta_2 \cdot \text{男} + (\beta_1 + \beta_3 \cdot \text{男}) \cdot \text{学年} \end{aligned} $ この形にすると構造が見やすくなります。 - **切片**:$\beta_0 + \beta_2 \cdot \text{男}$ → 男の値(0か1)によって切片が変わる - **学年の傾き**:$(\beta_1 + \beta_3 \cdot \text{男})$ → 男の値によって傾きが変わる つまり $\beta_3$ は「男 = 1 になったときに傾きがどれだけ変化するか」を直接表しています。 ### 女子(男 = 0)の場合 $ \text{身長} = \beta_0 + \beta_1 \cdot \text{学年} $ ### 男子(男 = 1)の場合 $ \text{身長} = (\beta_0 + \beta_2) + (\beta_1 + \beta_3) \cdot \text{学年} $ ### 並べて比較する | | 切片 | 傾き(学年の係数) | |------------------------|-------------------|---------------------------| | **女子**(男 = 0) | $\beta_0$ | $\beta_1$ | | **男子**(男 = 1) | $\beta_0 + \beta_2$ | $\beta_1 + \beta_3$ | | **差(男子 − 女子)** | $\beta_2$ | $\beta_3$ | 各係数の意味をまとめます。 - $\beta_0 = 109.93$:女子で学年 = 0(仮想的な入学前)のときの期待身長 - $\beta_1 = 5.11$:**女子における**学年が1つ上がるごとの身長の増加量(cm/学年) - $\beta_2 = 4.67$:学年 = 0 における男女の身長差(**切片の差**) - $\beta_3 = 1.71$:学年あたりの身長増加量が、男子では女子と比べてどれだけ大きいか(**傾きの差**) ## 数値例 モデル3の推定結果を当てはめます。 $ \hat{\text{身長}} = 109.93 + 5.11 \cdot \text{学年} + 4.67 \cdot \text{男} + 1.71 \cdot (\text{学年} \times \text{男}) $ **女子の回帰式:** $ \hat{\text{身長}} = 109.93 + 5.11 \cdot \text{学年} $ **男子の回帰式:** $ \hat{\text{身長}} = (109.93 + 4.67) + (5.11 + 1.71) \cdot \text{学年} = 114.60 + 6.83 \cdot \text{学年} $ ### 男女差の変化を確認する | 学年 | 女子の予測身長 | 男子の予測身長 | 差(男子 − 女子) | |------|---------------|---------------|-------------------| | 1 | 115.0 | 121.4 | 6.4 | | 2 | 120.2 | 128.3 | 8.1 | | 3 | 125.3 | 135.1 | 9.8 | | 4 | 130.4 | 141.9 | 11.5 | | 5 | 135.5 | 148.7 | 13.2 | | 6 | 140.6 | 155.6 | 15.0 | - 女子:傾き 5.11 cm/学年 - 男子:傾き 6.83 cm/学年 - 1学年あたりの傾きの差:1.71 cm(= $\beta_3$, p < 0.001) 1年生の時点で約 6 cm の差がありますが、6年生では約 15 cm に広がります。$\beta_2$ が切片の差、$\beta_3$ が傾きの差を捉えています。 ## 交互作用項の検定 交互作用が統計的に意味があるかどうかは、$\beta_3 = 0$ という帰無仮説を検定します。 $ H_0: \beta_3 = 0 \quad \text{(学年あたりの身長増加量は男女で同じ)} $ $ H_1: \beta_3 \neq 0 \quad \text{(学年あたりの身長増加量は男女で異なる)} $ $\beta_3 = 0$ が棄却されなければ、交互作用項を除いたモデル2(平行な直線)で十分ということになります。棄却されれば、身長の伸び方が男女で違うと結論づけられます。今回の結果では p < 0.001 で有意でした。 ## まとめ 1. **交互作用項**は「ある変数の効果が別の変数の水準によって異なる」ことをモデルに取り込む手段です。 2. カテゴリ × 連続の交互作用では、**グループごとに切片と傾きが異なる回帰直線**が得られます。 3. 交互作用項の係数 $\beta_3$ は「傾きの差」を表しており、これが 0 かどうかを検定することで交互作用の有無を判断できます。 4. 交互作用項がある場合、主効果の係数は「もう一方の変数が 0 のときの効果」を意味するため、解釈に注意が必要です。 ## 完全動作コード 以下を do-file に貼り付けてそのまま実行できます。 ```stata * ============================================ * 交互作用項の理解:小学生の身長データ * ============================================ clear all * --- データ入力 --- input id str4 sex male grade height 1 "女子" 0 1 115 2 "女子" 0 2 120 3 "女子" 0 3 126 4 "女子" 0 4 130 5 "女子" 0 5 135 6 "女子" 0 6 141 7 "男子" 1 1 121 8 "男子" 1 2 129 9 "男子" 1 3 135 10 "男子" 1 4 142 11 "男子" 1 5 148 12 "男子" 1 6 156 end list, separator(6) * --- モデル1: 学年のみ --- display _newline(2) "===== モデル1: 学年のみ =====" regress height grade * --- モデル2: 学年 + 性別(主効果のみ) --- display _newline(2) "===== モデル2: 学年 + 性別(平行線) =====" regress height grade male * --- モデル3: 交互作用あり --- display _newline(2) "===== モデル3: 交互作用あり =====" regress height c.grade##i.male * --- 各グループの回帰式を表示 --- display _newline "女子: 身長 = " %6.2f _b[_cons] " + " %6.4f _b[grade] " * 学年" display "男子: 身長 = " %6.2f (_b[_cons] + _b[1.male]) " + " %6.4f (_b[grade] + _b[c.grade#1.male]) " * 学年" * --- グラフ: モデル2(平行線)vs モデル3(異なる傾き) --- * モデル2 quietly regress height grade male predict yhat2 twoway (scatter height grade if male == 0, mcolor(red) msymbol(circle)) /// (scatter height grade if male == 1, mcolor(blue) msymbol(circle)) /// (line yhat2 grade if male == 0, sort lcolor(red) lwidth(medium)) /// (line yhat2 grade if male == 1, sort lcolor(blue) lwidth(medium)), /// legend(order(1 "女子" 2 "男子") position(6) cols(2)) /// xtitle("学年") ytitle("身長 (cm)") /// title("モデル2: 主効果のみ(平行線)") /// xlabel(1(1)6) ylabel(110(5)160, grid) graph export "interaction_model2.png", replace drop yhat2 * モデル3 quietly regress height c.grade##i.male predict yhat3 twoway (scatter height grade if male == 0, mcolor(red) msymbol(circle)) /// (scatter height grade if male == 1, mcolor(blue) msymbol(circle)) /// (line yhat3 grade if male == 0, sort lcolor(red) lwidth(medium)) /// (line yhat3 grade if male == 1, sort lcolor(blue) lwidth(medium)), /// legend(order(1 "女子" 2 "男子") position(6) cols(2)) /// xtitle("学年") ytitle("身長 (cm)") /// title("モデル3: 交互作用あり(異なる傾き)") /// xlabel(1(1)6) ylabel(110(5)160, grid) graph export "interaction_model3.png", replace drop yhat3 ```