みたいな相談を受けた。
回帰分析は最近ほとんどしないし、そもそもしたとしても交互作用の項は変数が増えるし解釈も面倒になるのでしたことがないのが本音だが、聞かれたので考えた。
結論から言うと、変数は先に標準化して、そして積を取るようである。
iris
を使うわけだが、Sepal.Length
をSepal.Width
, Petal.Length
, Petal.Width
で回帰することを考える。ここで、変数を標準化しない場合、標準化しないデータで得た回帰係数に対して、「目的変数の標準偏差/説明変数の標準偏差」、をかけると標準化した場合のデータで得た回帰係数、つまり標準化偏回帰係数が得られる。
dat <- iris[,-5] dat_scale <- as.data.frame(scale(dat)) lm0 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data=dat) lm1 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data=dat_scale) standard_coef_coef <- apply(dat, 2, sd)/sd(dat$Sepal.Length) # no interaction lm0$coefficients * standard_coef_coef lm1$coefficients
lm0$coefficients * standard_coef_coef (Intercept) Sepal.Width Petal.Length Petal.Width 1.8559975 0.3425789 1.5117505 -0.5122442 lm1$coefficients (Intercept) Sepal.Width Petal.Length Petal.Width -1.176045e-16 3.425789e-01 1.511751e+00 -5.122442e-01
確かに一致する。
次に、Petal.Length
とPetal.Width
が交互作用を持つと仮定した場合を考える。Rのlm
関数で自動的にするならば、入力データを標準化しない場合と、標準化した場合はそれぞれlm2
, lm3
となる。
lm2 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length * Petal.Width, data=dat) lm3 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length * Petal.Width, data=dat_scale)
ここで、Rのformula内で*
を使えば交互作用となるが、これは事前に入力データ内に、積の変数を作っておけばよい。ここで、dat1
は、積の変数を作ってから標準化したもので、dat2
は、標準化した変数を使って積の変数にしたものである。
dat0 <- cbind.data.frame(dat, Petal.Length_Petal.Width=dat$Petal.Length*dat$Petal.Width) dat1 <- as.data.frame(scale(dat0)) dat2 <- cbind.data.frame(dat_scale, Petal.Length_Petal.Width=dat_scale$Petal.Length*dat_scale$Petal.Width)
lm
内のformula をベタに書くと
lm4 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data=dat0) lm5 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data=dat1) lm6 <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data=dat2)
ここで、標準化していない場合のデータで、*
を使って交互作用を書いた場合lm2
と、積の変数を作って回帰した場合lm4
は
lm2 Call: lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length * Petal.Width, data = dat) Coefficients: (Intercept) Sepal.Width Petal.Length Petal.Width 2.24236 0.57835 0.65778 -0.83072 Petal.Length:Petal.Width 0.06164 lm4 Call: lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data = dat0) Coefficients: (Intercept) Sepal.Width Petal.Length Petal.Width 2.24236 0.57835 0.65778 -0.83072 Petal.Length_Petal.Width 0.06164
となり一致する。
一方で、標準化した場合のデータだが、
lm3 Call: lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length * Petal.Width, data = dat_scale) Coefficients: (Intercept) Sepal.Width Petal.Length Petal.Width -0.0958 0.3044 1.5599 -0.5515 Petal.Length:Petal.Width 0.1002 lm5 Call: lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data = dat1) Coefficients: (Intercept) Sepal.Width Petal.Length Petal.Width 1.556e-16 3.044e-01 1.402e+00 -7.647e-01 Petal.Length_Petal.Width 3.508e-01 lm6 Call: lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Petal.Length_Petal.Width, data = dat2) Coefficients: (Intercept) Sepal.Width Petal.Length Petal.Width -0.0958 0.3044 1.5599 -0.5515 Petal.Length_Petal.Width 0.1002
となり、*
記法に一致するのは、標準化した変数を使って積の変数にした場合のlm6
である。
では、標準化しないで交互作用を含む回帰をしたlm2
の係数を、標準化して交互作用を含む回帰をしたものに一致させるかは、単純に「目的変数の標準偏差/説明変数の標準偏差」ではうまくいかなかった。おそらく共分散とかそういうのを使えばなんとかなるのだろうと思ったが数式をいじらずにやっていたので結局答えが出ないまま力尽きてしまった。
たぶん線形代数的に真面目にやるとわかりそうな気がする(やるとは言ってない
mikuhatsune.hatenadiary.com