回帰分析において、変数同士の相互作用を調べたい場面があります。例えば、「薬の効果が性別によって異なるか」や「運動の効果が年齢層によって変わるか」といった問題です。 交互作用項は、このような「ある変数の効果が他の変数の値によって変化する」関係を統計的に評価するための手法です。 この記事では、Stataの組み込みデータセット「auto」を使用して、交互作用項の概念を段階的に学習していきます。 ## 誤差項(ε)について 回帰分析の数式に登場する $\varepsilon$(イプシロン)は「誤差項」と呼ばれます。これは以下を表します: - **モデルで説明できない変動**: 回帰式で完全に予測できない部分 - **観測誤差**: 測定の際の小さなエラー - **その他の要因**: モデルに含まれていない他の変数の影響 例えば、車の燃費は重量だけでなく、エンジンの性能、空気抵抗、タイヤの種類など多くの要因に影響されます。誤差項は、これらの「モデルに含めていない要因」による変動を表現しています。 ## 使用するデータ 自動車のデータセットを使用します: ```stata sysuse auto, clear describe mpg weight foreign ``` ``` Variable Storage Display Value name type format label Variable label ------------------------------------------------------------------------------- mpg int %8.0g Mileage (mpg) weight int %8.0gc Weight (lbs.) foreign byte %8.0g origin Car origin ``` - **mpg**: 燃費(マイルパーガロン)- 結果変数 - **weight**: 車の重量(ポンド)- 説明変数1(連続変数) - **foreign**: 車の産地(0=国産、1=外国産)- 説明変数2(カテゴリー変数) ### 単位の参考 アメリカのデータなので単位が日本と異なります: - **1マイル ≈ 1.6km** - **1ガロン ≈ 3.8リットル** - **1ポンド ≈ 0.45kg** 例えば、燃費20mpg(マイルパーガロン)は: 20マイル ÷ 1ガロン = 20 × 1.6km ÷ 3.8L ≈ 8.4km/L 重量3000ポンドは: 3000 × 0.45kg ≈ 1350kg ## モデル1: 単純な線形回帰 まず、車の重量と燃費の関係を調べます。 ### 数式 $mpg = \beta_0 + \beta_1 \times weight + \varepsilon$ ここで: - $\beta_0$: 切片(重量が0の時の燃費) - $\beta_1$: 回帰係数(重量が1ポンド増加した時の燃費の変化) - $\varepsilon$: 誤差項(モデルで説明できない部分) ### Stataコード ```stata regress mpg weight ``` ### 結果 ``` ------------------------------------------------------------------------------ mpg | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- weight | -.0060087 .0005179 -11.60 0.000 -.0070411 -.0049763 _cons | 39.44028 1.614003 24.44 0.000 36.22283 42.65774 ------------------------------------------------------------------------------ ``` ### 結果の解釈 この結果をβパラメータと対応させると: - $\beta_0 = 39.44$(_cons の値) - $\beta_1 = -0.0060$(weight の値) これらの値を数式に代入すると: $mpg = 39.44 + (-0.0060) \times weight$ $mpg = 39.44 - 0.0060 \times weight$ **解釈**: 車の重量が1ポンド増加すると、燃費は約0.006マイル/ガロン減少します。 ### 視覚化 ```stata twoway (scatter mpg weight, mcolor(navy) msize(medium)) /// (lfit mpg weight, lcolor(red) lwidth(medium)), /// title("モデル1: 単純な線形回帰") /// subtitle("mpg = α + β₁×weight + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "観測値") label(2 "回帰直線") position(6) cols(2)) graph export "interaction_model1.png", replace ``` ![[interaction_model1 4.png]] この図では、すべての車が同じ回帰直線上にあると仮定しています。 ## モデル2: ダミー変数を追加(平行線) 次に、車の産地によって燃費の基準値(切片)が異なるかを調べます。 ### 数式 $mpg = \beta_0 + \beta_1 \times weight + \beta_2 \times foreign + \varepsilon$ ここで: - $\beta_0$: 切片(国産車で重量が0の時の燃費) - $\beta_1$: 重量の効果(重量が1ポンド増加した時の燃費の変化) - $\beta_2$: 外国産車と国産車の燃費の差(重量が同じ場合) - $\varepsilon$: 誤差項(モデルで説明できない部分) ### Stataコード ```stata regress mpg weight foreign ``` ### 結果 ``` ------------------------------------------------------------------------------ mpg | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- weight | -.0065879 .0006371 -10.34 0.000 -.0078583 -.0053175 foreign | -1.650029 1.075994 -1.53 0.130 -3.7955 .4954422 _cons | 41.6797 2.165547 19.25 0.000 37.36172 45.99768 ------------------------------------------------------------------------------ ``` ### 結果の解釈 この結果をβパラメータと対応させると: - $\beta_0 = 41.68$(_cons の値) - $\beta_1 = -0.0066$(weight の値) - $\beta_2 = -1.65$(foreign の値) これらの値を数式に代入すると: $mpg = 41.68 + (-0.0066) \times weight + (-1.65) \times foreign$ $mpg = 41.68 - 0.0066 \times weight - 1.65 \times foreign$ **解釈**: - **weight の係数**: 重量が1ポンド増加すると燃費は0.0066マイル/ガロン減少 - **foreign の係数**: 外国産車は国産車より燃費が1.65マイル/ガロン低い(統計的に有意ではない、p=0.130) ### 各グループの回帰式 この結果から、各グループの回帰式は: **国産車(foreign = 0)**: $mpg = 41.68 - 0.0066 \times weight$ **外国産車(foreign = 1)**: $mpg = (41.68 - 1.65) - 0.0066 \times weight = 40.03 - 0.0066 \times weight$ ### 視覚化 ```stata * 回帰分析を実行 regress mpg weight foreign * 係数を保存 local b_weight = _b[weight] local b_foreign = _b[foreign] local b_cons = _b[_cons] * 平行線を描画 twoway (scatter mpg weight if foreign==0, mcolor(blue) msize(medium)) /// (scatter mpg weight if foreign==1, mcolor(red) msize(medium)) /// (function y = `b_cons' + `b_weight'*x, range(1760 4840) lcolor(blue) lwidth(medium)) /// (function y = (`b_cons' + `b_foreign') + `b_weight'*x, range(1760 4840) lcolor(red) lwidth(medium)), /// title("モデル2: ダミー変数を追加(平行線)") /// subtitle("mpg = α + β₁×weight + β₂×foreign + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "国産車 観測値") label(2 "外国産車 観測値") /// label(3 "国産車 回帰直線") label(4 "外国産車 回帰直線") /// position(6) cols(2)) graph export "interaction_model2.png", replace ``` ![[interaction_model2 1.png]] この図では、2つの直線は**平行**です。つまり、重量の燃費への影響(傾き)は国産車と外国産車で同じと仮定されています。 ## モデル3: 交互作用項を追加(異なる傾き) 最後に、重量の燃費への影響が車の産地によって異なるかを調べます。これが交互作用項です。 ### 数式 $mpg = \beta_0 + \beta_1 \times weight + \beta_2 \times foreign + \beta_3 \times (weight \times foreign) + \varepsilon$ ここで: - $\beta_0$: 切片(国産車で重量が0の時の燃費) - $\beta_1$: 国産車における重量の効果(重量が1ポンド増加した時の燃費の変化) - $\beta_2$: 外国産車と国産車の燃費の差(重量が0の時) - $\beta_3$: 交互作用項の係数(外国産車における重量の効果の違い) - $\varepsilon$: 誤差項(モデルで説明できない部分) ### Stataコード ```stata * 交互作用項の生成方法1: 手動で作成 gen weight_foreign = weight * foreign regress mpg weight foreign weight_foreign * 交互作用項の生成方法2: Stataの記法を使用(推奨) regress mpg c.weight##i.foreign ``` ### 結果 ``` ------------------------------------------------------------------------------ mpg | Coefficient Std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- weight | -.0059751 .0006622 -9.02 0.000 -.0072958 -.0046544 | foreign | Foreign | 9.271333 4.500409 2.06 0.043 .2955505 18.24711 | foreign#| c.weight | Foreign | -.0044509 .0017846 -2.49 0.015 -.0080101 -.0008916 | _cons | 39.64696 2.243364 17.67 0.000 35.17272 44.12121 ------------------------------------------------------------------------------ ``` ### 結果の解釈 この結果をβパラメータと対応させると: - $\beta_0 = 39.65$(_cons の値) - $\beta_1 = -0.0060$(weight の値) - $\beta_2 = 9.27$(1.foreign の値) - $\beta_3 = -0.0045$(c.weight#1.foreign の値) これらの値を数式に代入すると: $mpg = 39.65 + (-0.0060) \times weight + 9.27 \times foreign + (-0.0045) \times (weight \times foreign)$ $mpg = 39.65 - 0.0060 \times weight + 9.27 \times foreign - 0.0045 \times (weight \times foreign)$ **解釈**: - **weight の係数(-0.0060)**: 国産車における重量の効果 - **foreign の係数(9.27)**: 重量0の時の外国産車と国産車の燃費差 - **交互作用項の係数(-0.0045)**: 外国産車における重量効果の追加的な変化 ### 各グループの回帰式 **国産車(foreign = 0)**: $mpg = 39.65 - 0.0060 \times weight$ **外国産車(foreign = 1)**: $mpg = (39.65 + 9.27) + (-0.0060 - 0.0045) \times weight$ $mpg = 48.92 - 0.0104 \times weight$ ### 交互作用の意味 交互作用項が統計的に有意(p=0.015)なので、重量の燃費への影響は車の産地によって異なります: - **国産車**: 重量1ポンド増加で燃費0.0060マイル/ガロン減少 - **外国産車**: 重量1ポンド増加で燃費0.0104マイル/ガロン減少 外国産車の方が重量の増加による燃費悪化が大きいことがわかります。 ### 視覚化 ```stata * まず回帰分析を実行 regress mpg c.weight##i.foreign twoway (scatter mpg weight if foreign==0, mcolor(blue) msize(medium)) /// (scatter mpg weight if foreign==1, mcolor(red) msize(medium)) /// (function y = _b[_cons] + _b[weight]*x, range(1760 4840) lcolor(blue) lwidth(medium)) /// (function y = (_b[_cons] + _b[1.foreign]) + (_b[weight] + _b[c.weight#1.foreign])*x, /// range(1760 4840) lcolor(red) lwidth(medium)), /// title("モデル3: 交互作用項を追加(異なる傾き)") /// subtitle("mpg = α + β₁×weight + β₂×foreign + β₃×(weight×foreign) + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "国産車 観測値") label(2 "外国産車 観測値") /// label(3 "国産車 回帰直線") label(4 "外国産車 回帰直線") /// position(6) cols(2)) graph export "interaction_model3.png", replace ``` ![[interaction_model3 1.png]] この図では、2つの直線は**異なる傾き**を持っています。これが交互作用の視覚的な表現です。 ## 3つのモデルの比較 | モデル | R² | 解釈 | |--------|----|----| | モデル1 | 0.6515 | 重量のみで燃費の65%を説明 | | モデル2 | 0.6627 | 重量と産地で燃費の66%を説明(平行線) | | モデル3 | 0.6902 | 重量と産地の交互作用で燃費の69%を説明(異なる傾き) | 交互作用項を含むモデル3が最も説明力が高く、実際のデータをよく表現していることがわかります。 ## 交互作用項使用時の注意点 ### 1. 主効果の解釈が変わる 交互作用項がある場合、主効果(weightやforeign)の係数の意味が変わります: - **weight の係数**: 外国産車でない場合(foreign=0)における重量の効果 - **foreign の係数**: 重量が0の場合における産地の効果 ### 2. 係数の統計的有意性 交互作用項が有意でない場合は、モデル2(平行線)の方が適切な可能性があります。 ### 3. 各グループでの重量の効果 交互作用項がある場合、重量の効果は車の産地によって異なります。 **β₁は何を表すか**: - β₁ = -0.0060 は「国産車における」重量の効果のみ - 外国産車の重量効果を知りたい場合、β₁だけでは不十分 **各グループでの重量の効果を計算**: **国産車(foreign = 0)**: - 重量1ポンド増加 → 燃費変化 = $\beta_1 = -0.0060$ マイル/ガロン **外国産車(foreign = 1)**: - 重量1ポンド増加 → 燃費変化 = $\beta_1 + \beta_3 = -0.0060 + (-0.0045) = -0.0105$ マイル/ガロン **まとめ**: - 国産車: 重量1ポンド増加で燃費0.0060マイル/ガロン悪化 - 外国産車: 重量1ポンド増加で燃費0.0105マイル/ガロン悪化 外国産車の方が重量増加による燃費悪化が大きいことがわかります。 交互作用項があると、回帰表の係数をそのまま解釈するだけでは各グループの効果が分からないため、このような計算が必要になります。 ## 完全動作コード ```stata * ==================================== * Stata - 交互作用項を理解しよう:完全版 * ==================================== * データの読み込みと確認 sysuse auto, clear cd ~/Downloads describe mpg weight foreign summarize mpg weight foreign * モデル1: 単純な線形回帰 regress mpg weight * モデル1の図 twoway (scatter mpg weight, mcolor(navy) msize(medium)) /// (lfit mpg weight, lcolor(red) lwidth(medium)), /// title("モデル1: 単純な線形回帰") /// subtitle("mpg = α + β₁×weight + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "観測値") label(2 "回帰直線") position(6) cols(2)) graph export "interaction_model1.png", replace * モデル2: ダミー変数を追加 regress mpg weight foreign * モデル2の図(平行線) regress mpg weight foreign local b_weight = _b[weight] local b_foreign = _b[foreign] local b_cons = _b[_cons] twoway (scatter mpg weight if foreign==0, mcolor(blue) msize(medium)) /// (scatter mpg weight if foreign==1, mcolor(red) msize(medium)) /// (function y = `b_cons' + `b_weight'*x, range(1760 4840) lcolor(blue) lwidth(medium)) /// (function y = (`b_cons' + `b_foreign') + `b_weight'*x, range(1760 4840) lcolor(red) lwidth(medium)), /// title("モデル2: ダミー変数を追加(平行線)") /// subtitle("mpg = α + β₁×weight + β₂×foreign + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "国産車 観測値") label(2 "外国産車 観測値") /// label(3 "国産車 回帰直線") label(4 "外国産車 回帰直線") /// position(6) cols(2)) graph export "interaction_model2.png", replace * モデル3: 交互作用項を追加 regress mpg c.weight##i.foreign * 各グループの回帰式を表示 di "国産車(foreign=0)での回帰式:" di "mpg = " _b[_cons] " + " _b[weight] " * weight" di "外国産車(foreign=1)での回帰式:" di "mpg = " (_b[_cons] + _b[1.foreign]) " + " (_b[weight] + _b[c.weight#1.foreign]) " * weight" * モデル3の図 twoway (scatter mpg weight if foreign==0, mcolor(blue) msize(medium)) /// (scatter mpg weight if foreign==1, mcolor(red) msize(medium)) /// (function y = _b[_cons] + _b[weight]*x, range(1760 4840) lcolor(blue) lwidth(medium)) /// (function y = (_b[_cons] + _b[1.foreign]) + (_b[weight] + _b[c.weight#1.foreign])*x, /// range(1760 4840) lcolor(red) lwidth(medium)), /// title("モデル3: 交互作用項を追加(異なる傾き)") /// subtitle("mpg = α + β₁×weight + β₂×foreign + β₃×(weight×foreign) + ε") /// xlabel(, grid) ylabel(, grid) /// xtitle("Weight (lbs.)") ytitle("Mileage (mpg)") /// legend(label(1 "国産車 観測値") label(2 "外国産車 観測値") /// label(3 "国産車 回帰直線") label(4 "外国産車 回帰直線") /// position(6) cols(2)) graph export "interaction_model3.png", replace display "解析完了: 交互作用項の理解" ``` この記事で学習した内容を実際の研究に応用する際は、交互作用が理論的に意味を持つかどうかを慎重に検討することが重要です。