14  交差項の使い方

14.1 交差項で何が分かるのか

説明変数Xが応答変数Yに与える影響(直接効果)に対して,別の説明変数Zが与える影響がある場合,XZの交差項X \times Zをモデルに組み入れることで,Xの影響がZの値によってどのように変化するかを分析することができます。

Y = \beta_0 + \beta_1 X + \beta_2 Z + \beta_3 X \times Z + \varepsilon

このX \times Z交差項(interaction term)とよびます。

前章で導入したダミー変数との交差項は,ダミー変数の値によって,切片や傾きがどのように変化するかを分析することができましたが,ここでは量的変数と量的変数の交差項のケースを考えます。

14.2 交差項を入れた回帰分析の注意点

回帰分析で交差項を入れる場合の注意点は次の4つです。

  1. 条件付仮説(たとえば,十分にZが大きいとき,XYに影響を与える,とか)を検証する場合に,交差項を使う。
  2. 交差項を入れるときは,交差項を構成する変数をそれぞれ回帰モデルに入れる。
  3. 交差項を構成する変数の回帰係数はそのまま解釈できない。
  4. 分析結果として,限界効果と標準誤差を示す。

これは,数式で確認すれば分かりやすいです。 回帰モデルが

Y = \beta_0 + \beta_1 X + \beta_2 Z + \beta_3 X \times Z + \varepsilon

であるとき,説明変数Xが応答変数Yに与える影響は,YXで偏微分することで求められます。

\frac{\partial Y}{\partial X} = \beta_1 + \beta_3 Z

この式から,XYに与える影響がZの値によって変化する、ということが分かります。 そのため,\beta_1の値だけでは,Xの影響を正確に評価することができません。また,Zの値によって,Xの影響が変化することを示すためには,Zの値を変化させたときの\beta_1の値を示す必要があります。これを限界効果(marginal effect)とよびます。

14.3 広告宣伝費を事例とした交差項の分析

以下の分析で利用するためのデータを読み込みます。 ここでも,tidyverseパッケージ群のread_csv()関数を使います。

df <- read_csv("data/adv_2023.csv") # データの読み込み
df <- df %>%
  select(-拡販費) %>% # 必要ないデータを除去
  filter(決算月数 == 12) %>% # 決算月数が12のデータを抽出
  filter(広告宣伝費 > 0)  # 広告宣伝費が0のデータを除去
glimpse(df)
Rows: 8,632
Columns: 13
$ 日経会社コード <chr> "0000001", "0000001", "0000003", "0000003", "0000003", …
$ 企業名称       <chr> "極洋", "極洋", "日本水産", "日本水産", "日本水産", "日…
$ 決算期         <chr> "2006/03", "2007/03", "2006/03", "2007/03", "2008/03", …
$ 決算種別       <dbl> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,…
$ 連結基準       <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ 決算月数       <dbl> 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,…
$ 業種           <dbl> 235341, 235341, 235341, 235341, 235341, 235341, 235341,…
$ 資産合計       <dbl> 65049, 66459, 384819, 404173, 396739, 385462, 383924, 4…
$ 売上高         <dbl> 152899, 157088, 539653, 552871, 533970, 505250, 481574,…
$ 販管費         <dbl> 13702, 14455, 95566, 98200, 100394, 98413, 99938, 10490…
$ 広告宣伝費     <dbl> 304, 279, 2699, 2569, 2953, 2568, 2636, 3160, 3009, 288…
$ 研究開発費     <dbl> 193, 188, 3083, 3377, 3718, 3803, 3994, 4499, 4809, 361…
$ 設備投資額     <dbl> 897, 1841, 17186, 16031, 19105, 28872, 21121, 18633, 16…

以下では,応答変数として売上高,説明変数として広告宣伝費と設備投資額を使います。

14.3.1 記述統計と散布図の表示

主要変数3つの記述統計をみます。 ここではsummary()関数を使います。

df3 <- df[, c("売上高", "広告宣伝費", "設備投資額", "資産合計")]
summary(df3)
     売上高           広告宣伝費       設備投資額         資産合計       
 Min.   :      54   Min.   :     1   Min.   :      1   Min.   :      25  
 1st Qu.:   26299   1st Qu.:   250   1st Qu.:    771   1st Qu.:   27312  
 Median :   84923   Median :  1284   Median :   3078   Median :   83040  
 Mean   :  448013   Mean   :  9912   Mean   :  28789   Mean   :  592193  
 3rd Qu.:  277604   3rd Qu.:  6158   3rd Qu.:  12271   3rd Qu.:  278223  
 Max.   :30225681   Max.   :509653   Max.   :4069225   Max.   :51936949  
                                     NA's   :540       NA's   :5         

これでも良いのですが,skimrパッケージとsummarytoolsパッケージを使うと,より見やすい表を作ることが出来ます。

# install.packages("skimr") # first time only
library(skimr)
skim(df3)
Data summary
Name df3
Number of rows 8632
Number of columns 4
_______________________
Column type frequency:
numeric 4
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
売上高 0 1.00 448013.23 1522677.66 54 26298.75 84923.0 277604.00 30225681 ▇▁▁▁▁
広告宣伝費 0 1.00 9911.51 34054.36 1 250.00 1283.5 6158.00 509653 ▇▁▁▁▁
設備投資額 540 0.94 28788.64 156138.90 1 771.25 3078.5 12270.75 4069225 ▇▁▁▁▁
資産合計 5 1.00 592192.73 2348228.18 25 27312.00 83040.0 278223.00 51936949 ▇▁▁▁▁

あるいは,summarytoolsパッケージのdescr()関数を使っても見やすい表を作ることが出来ます。

# install.packages("summarytools") # first time only
library(summarytools)
descr(df3, transpose = TRUE)
Descriptive Statistics  
df3  
N: 8632  

                        Mean      Std.Dev     Min         Q1     Median          Q3           Max
---------------- ----------- ------------ ------- ---------- ---------- ----------- -------------
      広告宣伝費     9911.51     34054.36    1.00     250.00    1283.50     6161.00     509653.00
        資産合計   592192.73   2348228.18   25.00   27302.00   83040.00   278313.00   51936949.00
      設備投資額    28788.64    156138.90    1.00     770.50    3078.50    12280.50    4069225.00
          売上高   448013.23   1522677.66   54.00   26293.50   84923.00   277652.00   30225681.00

Table: Table continues below

 

                         MAD         IQR     CV   Skewness   SE.Skewness   Kurtosis   N.Valid   Pct.Valid
---------------- ----------- ----------- ------ ---------- ------------- ---------- --------- -----------
      広告宣伝費     1818.41     5908.00   3.44       8.29          0.03      86.44   8632.00      100.00
        資産合計   106096.34   250911.00   3.97      10.91          0.03     165.12   8627.00       99.94
      設備投資額     4215.77    11499.50   5.42      15.22          0.03     285.02   8092.00       93.74
          売上高   107098.58   251305.25   3.40       9.52          0.03     127.38   8632.00      100.00

また,summarytoolsパッケージのdfSummary()関数を使うと,データフレームの形で表を作ることが出来ます。

df3 %>%
  dfSummary(
    plain.ascii = FALSE,
    style        = 'grid',
    graph.magnif = 0.85,
    varnumbers = FALSE,
    valid.col    = FALSE) %>%
    print(method = "render")

Data Frame Summary

df3

Dimensions: 8632 x 4
Duplicates: 0
Variable Stats / Values Freqs (% of Valid) Graph Missing
売上高 [numeric]
Mean (sd) : 448013.2 (1522678)
min ≤ med ≤ max:
54 ≤ 84923 ≤ 30225681
IQR (CV) : 251305.2 (3.4)
8492 distinct values 0 (0.0%)
広告宣伝費 [numeric]
Mean (sd) : 9911.5 (34054.4)
min ≤ med ≤ max:
1 ≤ 1283.5 ≤ 509653
IQR (CV) : 5908 (3.4)
4878 distinct values 0 (0.0%)
設備投資額 [numeric]
Mean (sd) : 28788.6 (156138.9)
min ≤ med ≤ max:
1 ≤ 3078.5 ≤ 4069225
IQR (CV) : 11499.5 (5.4)
5751 distinct values 540 (6.3%)
資産合計 [numeric]
Mean (sd) : 592192.7 (2348228)
min ≤ med ≤ max:
25 ≤ 83040 ≤ 51936949
IQR (CV) : 250911 (4)
8480 distinct values 5 (0.1%)

Generated by summarytools 1.0.1 (R version 4.2.2)
2023-09-01

好きな方法を使ってください。

次に,散布図を描きます。

df3 %>%
  ggplot(aes(x = 設備投資額, y = 売上高)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(x = "設備投資額", y = "売上高") + mystyle

設備投資額が多い企業ほど売上高が多いように見えますが,因果関係を明らかにするためにも,広告宣伝費と翌期の売上高の散布図を書いてみます。ついでに両変数を対数変換して,分布を正規分布に近づけておきます。

df3 %>%
  mutate(
    K_設備投資額 = lag(設備投資額) / lag(資産合計),
    K_売上高 = 売上高 / lag(資産合計)
  ) %>%
  ggplot() + aes(x = K_設備投資額, y = K_売上高) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(x = "基準化済み前期設備投資額", y = "基準化済み売上高") + mystyle

次に,この設備投資額と売上高の関係に広告宣伝費がどのような影響を与えているのかを調べるために,回帰モデルに交差項を組み込んでいきます。

14.3.2 交差項を使った重回帰分析

ここでは,次のような仮説を考えてみます。

広告宣伝費が多い企業ほど,設備投資額が多いと,売上高が増加する。

この仮説を検証するために,回帰モデルを次のように設定します。

$$ \begin{aligned} \log \text{売上高} = \beta_0 &+ \beta_1 \log \text{前期設備投資額} + \beta_2 \log \text{広告宣伝費} \\ & + \beta_3 \log \text{前期設備投資額} \times \log \text{広告宣伝費} + \varepsilon \end{aligned}

$$

これをlm()関数を使って回帰分析を行います。 lm()関すで交差項を含む回帰モデルを作るときは,*を使います。 推定結果をmodelsummaryパッケージを使って表示します。

library(modelsummary)
res01 <- lm(log(売上高) ~ log(設備投資額) * log(広告宣伝費), data = df3)
modelsummary(res01,
  stars = c("*" = .10, "**" = .05, "***" = .01),
  gof_omit = "AIC|BIC|logLik",
  )
 (1)
(Intercept) 6.819***
(0.087)
log(設備投資額) 0.397***
(0.012)
log(広告宣伝費) -0.012
(0.013)
log(設備投資額) × log(広告宣伝費) 0.025***
(0.001)
Num.Obs. 8092
R2 0.823
R2 Adj. 0.823
Log.Lik. -9015.976
F 12548.404
RMSE 0.74
* p < 0.1, ** p < 0.05, *** p < 0.01

この結果から,設備投資と売上高の正の関係は,広告宣伝費が大きくなるほど強くなる,ということが分かりました。 この結果の解釈を容易にするために,marginsパッケージを使って限界効果を計算します。

# install.packages("margins") # first time only
library(margins)
margins(res01)
 設備投資額 広告宣伝費
  0.0001487  0.0001997

この限界効果の推定から,広告宣伝費が増加すると,設備投資と売上高の正の関係が強くなることが分かります。

14.3.3 交差項を含む回帰分析結果の解釈と可視化

上の分析結果から,設備投資額と売上高との関係は,広告宣伝費の規模に応じて変化することが分かりました。 しかし,前述した通り設備投資額が売上高に与える影響の強さは,広告宣伝費に応じて決まるため,設備投資額が1円増えたとき,売上高がいくら増えるのかはこの推定結果からは分かりません。

そこで,説明変数を中心化することで,推定結果を解釈可能なものにします。 前章と同様に,中心化するために,各説明変数から標本平均を引きます。 ここでは,scale()関数を使って中心化します。

df3 <- df3 %>%
  mutate(
    log広告宣伝費_c = scale(log(広告宣伝費)),
    log設備投資額_c = scale(log(設備投資額))
  )
res02 <- lm(log(売上高) ~ log設備投資額_c * log広告宣伝費_c, data = df3)
modelsummary(res02,
  stars = c("*" = .10, "**" = .05, "***" = .01),
  gof_omit = "AIC|BIC|logLik",
  )
 (1)
(Intercept) 11.331***
(0.009)
log設備投資額_c 1.251***
(0.011)
log広告宣伝費_c 0.429***
(0.011)
log設備投資額_c × log広告宣伝費_c 0.124***
(0.007)
Num.Obs. 8092
R2 0.823
R2 Adj. 0.823
Log.Lik. -9015.976
F 12548.404
RMSE 0.74
* p < 0.1, ** p < 0.05, *** p < 0.01
df3 <- df3 %>%
  mutate(
    log広告宣伝費 = log(広告宣伝費),
    log設備投資額 = log(設備投資額),
    log広告宣伝費_c = log広告宣伝費 - mean(log広告宣伝費),
    log設備投資額_c = log設備投資額 - mean(log設備投資額)
  )

14.4 まとめ