変数のスケーリングと

回帰係数の解釈

様々な変数をとれるということは様々な定義域をとるということ

 重回帰では様々な変数を解析に組み込めることを紹介したが、それは同時に様々な定義域の変数が解析に含まれうることを意味する。説明変数のオーダーが違えども、問題なく推定は行われるが、その時算出された係数の解釈は注意が必要である。例えば、植物の高さcmに影響を与える要因として、与えた水量、土壌窒素含量、日照量を説明変数に組み込むことを考える。与えた水量はL(リットル)、土壌窒素含量はmg、日射量はJ/m^2で測ったとしよう。すると、まあ、実験設計によるが、水量は0 ~ 数十L、窒素含量は0 ~ 数千mg、日射量は0 ~ 数百万J/m^2くらいのオーダーになるだろう。もし、水量の係数が0.5、日射量の係数が0.01と推定されたら、このとき、水量のほうが影響が強い、と判断できるだろうか。実はそんな簡単には判断できない。係数が、各説明変数が1増加した時に増加する被説明変数の量であるので、水量は1L増加すれば0.5 cm増加し、日射量は1J/m^2増加すれば0.01cm増加することを意味する。見方を変えれば、水量は数十L分の1で0.5程度の影響しかなく、日射量は数百万J/m^2の1で0.01も影響がある、と考えることができる。このように、係数をそのまま解釈するだけでは、その要因の影響力を測ることはできない。


標準化(スケーリング)で変数間の影響量を比較する

 そこで、1単位の影響量を比較できるように、変数を標準化(スケーリング)することがある。方法は様々だが、その中でも最も一般的なものは変数を平均0、標準偏差1に統一する方法である。これは変数から変数の平均を引いたのち、もとの変数の標準偏差で割れば簡単に計算できる。R上では関数一つですぐに計算できる。

では、下記で具体的なデータをもとに解析してみよう。


スケーリングの具体例

 下記のようなデータを解析することを考える。Rではscale関数を用いることで、上記で紹介したスケーリングを実行してくれる。データフレームd内には、元の変数とスケーリングした変数、そしてx1とx2を掛け算し、スケーリングした変数を格納している。これは交互作用項を模したものだが、これの必要性は後述する。


------------------------------------------------------

library(plotn)


x1 <- c(29, 12, 22, 20, 14, 24, 17, 19, 24, 14

        19, 14, 23, 24, 21, 23, 13, 11, 27, 25

        24, 15, 11, 11, 13, 29, 18, 29, 17, 27

        25, 13, 24, 19, 23, 16, 24, 22, 24, 29

        28, 23, 14, 13, 22, 22, 12, 29, 19, 28

        18, 27, 14, 11, 28, 29, 26, 20, 24, 21)


x2 <- c(1923, 2914, 1260, 1654, 2478

        1279, 2764, 1605, 2461, 2094

        1865, 1094, 2597, 2474, 1032

        1105, 1130, 2963, 2090, 2656

        2304, 1638, 1974, 1407, 2190

        1885, 2479, 2521, 1622, 2318

        1259, 1893, 2795, 1773, 2498

        2013, 1536, 1109, 1195, 2869

        2288, 2407, 2754, 1509, 2080

        1239, 1309, 1086, 2344, 2518

        2397, 1561, 1812, 1405, 2684

        2639, 1227, 1951, 1583, 2649)


y <- c(494, 419, 357, 374, 399, 376, 448, 363, 496, 348

       375, 257, 492, 509, 315, 346, 257, 409, 490, 521

       485, 323, 311, 261, 340, 486, 436, 549, 331, 499

       380, 324, 535, 371, 486, 363, 402, 337, 363, 580

       514, 482, 425, 288, 430, 344, 255, 406, 427, 539,

       426, 430, 329, 252, 547, 556, 391, 395, 400, 484)


d <- data.frame(x1 = x1, x2 = x2, y = y, sx1 = scale(x1), sx2 = scale(x2), sx12 = scale(x1*x2), sy = scale(y))


head(d)

##   x1   x2   y        sx1         sx2       sx12         sy

## 1 29 1923 494  1.4535437 -0.07978025  0.8349930  0.9879591

## 2 12 2914 419 -1.4881519  1.62782730 -0.3315744  0.1184469

## 3 22 1260 357  0.2422573 -1.22220589 -0.7380978 -0.6003499

## 4 20 1654 374 -0.1038245 -0.54329834 -0.4374679 -0.4032604

## 5 14 2478 399 -1.1420700  0.87654890 -0.3470546 -0.1134230

## 6 24 1279 376  0.5883391 -1.18946669 -0.5711809 -0.3800735


plotn(d[,1:3]) #図1の描画

plotn(d[,4:7]) #図2の描画

------------------------------------------------------

1 スケーリング前の総当たりプロット

2 スケーリングの総当たりプロット

確認すると、x1(スケーリングしたsx1)とx2(sx2)はともにyと正の相関があることがわかる。偏差の分布は均等なので正規分布を仮定した重回帰を実行すればよいだろう。まず、x1とx2を変数とした解析を行う。交互作用はいったん考慮しないことにする。


------------------------------------------------------

fit1 <- lm(y ~ x1 + x2, data = d)

fit2 <- summary(fit1)


fit2

## 

## Call:

## lm(formula = y ~ x1 + x2, data = d)

## 

## Residuals:

##      Min       1Q   Median       3Q      Max 

## -14.1616  -3.6122   0.1291   2.9072  15.4082 

## 

## Coefficients:

##             Estimate Std. Error t value Pr(>|t|)    

## (Intercept)  3.85506    3.24947   1.186     0.24    

## x1          10.09241    0.11749  85.903   <2e-16 ***

## x2           0.10005    0.00117  85.518   <2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 5.192 on 57 degrees of freedom

## Multiple R-squared:  0.9965, Adjusted R-squared:  0.9964 

## F-statistic:  8114 on 2 and 57 DF,  p-value: < 2.2e-16

------------------------------------------------------


解析の結果、x1の係数の推定値は10程度、x2の推定値は0.1程度となった。ともに有意であるが、さて先の議論でこの係数をそのまま解釈して、x1のほうが影響が強いと判断できないことを述べた。x1は10~30の値、x2は1000~3000の値をとる。図1を見ると横軸の長さがそろっているため、x1が10~30を動く時と、x2が1000~3000を動く時のyの影響の程度は同程度のように見える。まさにこの図の感覚がスケーリングである。実際、今度はスケーリングした変数を説明変数として解析してみよう。


------------------------------------------------------

fit3 <- lm(sy ~ sx1 + sx2, data = d)

fit4 <- summary(fit3)


fit4

## 

## Call:

## lm(formula = sy ~ sx1 + sx2, data = d)

## 

## Residuals:

##       Min        1Q    Median        3Q       Max 

## -0.164183 -0.041878  0.001496  0.033705  0.178635 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -2.152e-16  7.770e-03    0.00        1    

## sx1          6.762e-01  7.871e-03   85.90   <2e-16 ***

## sx2          6.731e-01  7.871e-03   85.52   <2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.06019 on 57 degrees of freedom

## Multiple R-squared:  0.9965, Adjusted R-squared:  0.9964 

## F-statistic:  8114 on 2 and 57 DF,  p-value: < 2.2e-16

------------------------------------------------------


すると今度は、sx1とsx2の係数は0.67程度と推定され、効果の大きさが同程度であることがわかる。このようにスケーリングをすれば、定義域の異なる変数間でも効果の大きさを比較することができる。係数の推定値はスケーリングによって変わったが、t値はスケーリング前と変わらず、それゆえP値も変わらない。つまり、(後述の状況を除けば)x1やx2が有意かどうかは、x1、x2およびyのスケーリングによって影響を受けない。なお、切片だけは説明変数のスケーリングによって有意かどうか変わるので注意である。今回はさらにyもスケーリングしたので、syは平均がぴったり0になり、有意になることはない。つまり、切片に関してはスケーリング後に解釈する意味はないと言えるだろう。

 では、今度は交互作用を入れた時にどうなるかを確認してみよう。交互作用を説明変数に入れたときは注意が必要になる。まずはスケーリング前で解析する。


------------------------------------------------------

fit5 <- lm(y ~ x1 * x2, data = d)

fit6 <- summary(fit5)


fit6

## 

## Call:

## lm(formula = y ~ x1 * x2, data = d)

## 

## Residuals:

##      Min       1Q   Median       3Q      Max 

## -14.0597  -3.7751   0.0214   3.0516  15.3303 

## 

## Coefficients:

##              Estimate Std. Error t value Pr(>|t|)    

## (Intercept) 6.506e+00  8.868e+00   0.734    0.466    

## x1          9.963e+00  4.198e-01  23.731   <2e-16 ***

## x2          9.873e-02  4.272e-03  23.110   <2e-16 ***

## x1:x2       6.408e-05  1.992e-04   0.322    0.749    

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 5.233 on 56 degrees of freedom

## Multiple R-squared:  0.9965, Adjusted R-squared:  0.9963 

## F-statistic:  5325 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


上記のように推定できた。実は交互作用を含めずにデータ生成したので、有意な効果がない状態が真のモデルである。さて、スケーリング後の変数で交互作用を考慮して解析してみよう。


------------------------------------------------------

fit7 <- lm(sy ~ sx1 * sx2, data = d)

fit8 <- summary(fit7)


fit8

## 

## Call:

## lm(formula = sy ~ sx1 * sx2, data = d)

## 

## Residuals:

##       Min        1Q    Median        3Q       Max 

## -0.163002 -0.043766  0.000248  0.035379  0.177732 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -0.0002319  0.0078654  -0.029    0.977    

## sx1          0.6759496  0.0079654  84.860   <2e-16 ***

## sx2          0.6731386  0.0079340  84.842   <2e-16 ***

## sx1:sx2      0.0024915  0.0077443   0.322    0.749    

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.06067 on 56 degrees of freedom

## Multiple R-squared:  0.9965, Adjusted R-squared:  0.9963 

## F-statistic:  5325 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


すると、交互作用を考慮しなかったときと異なり、sx1とsx2のt値が変わっている。つまり、表示上は分からないがP値も変わっている(交互作用だけは変わらない)。このようにスケーリング時の交互作用の扱いが不適切だと、変数の効果の有意か否かが、スケーリングの前後で変わってしまう。これは、交互作用項をスケーリングしなかったことが問題である。そこで、交互作用項に相当するx1×x2をスケーリングした値をsx12としてデータフレームd内に格納している。これをもとのモデル式の代わりに説明変数に加えることにしよう。


------------------------------------------------------

fit9 <- lm(sy ~ sx1 + sx2 + sx12, data = d)

fit10 <- summary(fit9)


fit10

## 

## Call:

## lm(formula = sy ~ sx1 + sx2 + sx12, data = d)

## 

## Residuals:

##       Min        1Q    Median        3Q       Max 

## -0.163002 -0.043766  0.000248  0.035379  0.177732 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -2.165e-16  7.832e-03   0.000    1.000    

## sx1          6.675e-01  2.813e-02  23.731   <2e-16 ***

## sx2          6.643e-01  2.874e-02  23.110   <2e-16 ***

## sx12         1.324e-02  4.117e-02   0.322    0.749    

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.06067 on 56 degrees of freedom

## Multiple R-squared:  0.9965, Adjusted R-squared:  0.9963 

## F-statistic:  5325 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


すると、上記の解析結果はfit6と同じt値のなった。このように交互作用項の考慮時は注意が必要である。上記の現象が偶然ではないことをもう一つのデータセットで確認してみよう。



------------------------------------------------------

x1 <- c(11, 16, 15, 29, 27, 28, 27, 29, 24, 27

        16, 29, 11, 19, 24, 25, 14, 10, 21, 10

        24, 27, 23, 24, 12, 21, 18, 21, 29, 13

        11, 13, 16, 23, 21, 29, 28, 27, 22, 24

        21, 25, 17, 16, 19, 14, 23, 12, 10, 14

        13, 10, 15, 14, 27, 22, 19, 15, 10, 28)

x2 <- c(23670, 19806, 25488, 10129, 14578,

        22931, 27996, 11691, 17701, 27682

        14425, 20454, 11144, 26650, 21536

        13302, 29111, 10644, 12781, 12778

        22916, 21033, 21666, 17664, 23902

        27773, 24032, 16411, 14815, 23414

        17985, 23192, 28104, 14679, 18951

        10575, 20639, 10239, 28167, 15482,

        18474, 28102, 20795, 16267, 18332,

        20950, 26634, 13944, 18407, 22981

        17064, 17753, 12172, 12677, 16901

        23180, 16591, 14173, 22202, 13347)

y <- c(299853, 353397, 414552, 305100, 422427

       676352, 798798, 355171, 458245, 792914

       256978, 623659, 141582, 546435, 555404

       355238, 443693, 126937, 285541, 142941

       578971, 604219, 525018, 455532, 326791,

       620997, 466808, 368823, 447955, 343273,

       218216, 346470, 499396, 355470, 422177,

       319443, 602848, 293874, 658762, 399613,

       409420, 732941, 384127, 277569, 379446,

       317638, 646993, 183893, 220378, 354906

       240408, 203499, 196442, 190683, 479233

       552928, 333692, 240758, 259763, 394668)


d <- data.frame(x1 = x1, x2 = x2, y = y, sx1 = scale(x1), sx2 = scale(x2), sx12 = scale(x1*x2), sy = scale(y))


head(d)

##   x1    x2      y        sx1        sx2       sx12         sy

## 1 11 23670 299853 -1.3719333  0.8312999 -0.7216988 -0.6308081

## 2 16 19806 353397 -0.5834659  0.1256395 -0.3662197 -0.3048940

## 3 15 25488 414552 -0.7411594  1.1633110  0.0452169  0.0673471

## 4 29 10129 305100  1.4665494 -1.6416163 -0.5118362 -0.5988704

## 5 27 14578 422427  1.1511624 -0.8291206  0.1161920  0.1152810

## 6 28 22931 676352  1.3088559  0.6963405  1.6787127  1.6608834


plotn(d[,1:3]) #図3の描画

plotn(d[,4:7]) #図4の描画

------------------------------------------------------

3 スケーリング前の総当たりプロット

4 スケーリング後の総当たりプロット

確認すると、x1とx2はyと正の相関がありそうだ。実はこのデータは交互作用を含むように設定している。しいて言うなら、x1のデータから交互作用がありそうにも見えるが、まあ、これくらいなら交互作用無しで解析しても問題ないくらいだと思う。


------------------------------------------------------

fit1 <- lm(y ~ x1 + x2, data = d)

fit2 <- summary(fit1)


fit2

## 

## Call:

## lm(formula = y ~ x1 + x2, data = d)

## 

## Residuals:

##    Min     1Q Median     3Q    Max 

## -77161 -25191    617  20896  80856 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -3.641e+05  2.215e+04  -16.44   <2e-16 ***

## x1           1.774e+04  7.164e+02   24.77   <2e-16 ***

## x2           2.187e+01  8.297e-01   26.35   <2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 34860 on 57 degrees of freedom

## Multiple R-squared:  0.9565, Adjusted R-squared:  0.955 

## F-statistic: 626.6 on 2 and 57 DF,  p-value: < 2.2e-16

------------------------------------------------------


解析の結果、x1の係数は1.8×10^4、x2の係数は22程度とわかる。これらの効果はスケーリングするとどうなるだろうか。


------------------------------------------------------

fit3 <- lm(sy ~ sx1 + sx2, data = d)

fit4 <- summary(fit3)


fit4

## 

## Call:

## lm(formula = sy ~ sx1 + sx2, data = d)

## 

## Residuals:

##      Min       1Q   Median       3Q      Max 

## -0.46967 -0.15333  0.00376  0.12719  0.49216 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -3.159e-16  2.740e-02    0.00        1    

## sx1          6.849e-01  2.765e-02   24.77   <2e-16 ***

## sx2          7.288e-01  2.765e-02   26.35   <2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.2122 on 57 degrees of freedom

## Multiple R-squared:  0.9565, Adjusted R-squared:  0.955 

## F-statistic: 626.6 on 2 and 57 DF,  p-value: < 2.2e-16

------------------------------------------------------


するとsx1係数は0.68程度、sx2の係数は0.73程度と、なんと係数は逆転してしまった。まあ、これくらいなら同程度の強さ、ということになるだろうが、こういうこともある。t値は変わっていないので、有意かどうかには影響を与えていないことがわかるだろう

 では、今度は交互作用を入れた時にどうなるかを確認してみよう。


------------------------------------------------------

fit5 <- lm(y ~ x1 * x2, data = d)

fit6 <- summary(fit5)


fit6

## 

## Call:

## lm(formula = y ~ x1 * x2, data = d)

## 

## Residuals:

##      Min       1Q   Median       3Q      Max 

## -10235.8  -4073.6   -697.5   4135.9   9682.9 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -3.785e+03  8.071e+03  -0.469 0.640935    

## x1           1.875e+02  3.736e+02   0.502 0.617785    

## x2           1.760e+00  4.283e-01   4.109 0.000131 ***

## x1:x2        9.861e-01  2.008e-02  49.120  < 2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 5297 on 56 degrees of freedom

## Multiple R-squared:  0.999,  Adjusted R-squared:  0.999 

## F-statistic: 1.89e+04 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


上記のように推定できた。交互作用を入れるとx1の効果は有意ではなくなってしまった。交互作用を正しくスケーリングせずに解析すると、


------------------------------------------------------

fit7 <- lm(sy ~ sx1 * sx2, data = d)

fit8 <- summary(fit7)


fit8

## 

## Call:

## lm(formula = sy ~ sx1 * sx2, data = d)

## 

## Residuals:

##       Min        1Q    Median        3Q       Max 

## -0.062304 -0.024796 -0.004245  0.025175  0.058938 

## 

## Coefficients:

##             Estimate Std. Error t value Pr(>|t|)    

## (Intercept) 0.008976   0.004167   2.154   0.0355 *  

## sx1         0.734957   0.004324 169.979   <2e-16 ***

## sx2         0.706160   0.004227 167.054   <2e-16 ***

## sx1:sx2     0.208431   0.004243  49.120   <2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.03224 on 56 degrees of freedom

## Multiple R-squared:  0.999,  Adjusted R-squared:  0.999 

## F-statistic: 1.89e+04 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


このように今度はx1が有意になった。解析結果が変わってしまうことの典型例となっている。正しくスケーリングすると、


------------------------------------------------------

fit9 <- lm(sy ~ sx1 + sx2 + sx12, data = d)

fit10 <- summary(fit9)


fit10

## 

## Call:

## lm(formula = sy ~ sx1 + sx2 + sx12, data = d)

## 

## Residuals:

##       Min        1Q    Median        3Q       Max 

## -0.062304 -0.024796 -0.004245  0.025175  0.058938 

## 

## Coefficients:

##               Estimate Std. Error t value Pr(>|t|)    

## (Intercept) -1.239e-18  4.163e-03   0.000 1.000000    

## sx1          7.237e-03  1.442e-02   0.502 0.617785    

## sx2          5.866e-02  1.428e-02   4.109 0.000131 ***

## sx12         9.545e-01  1.943e-02  49.120  < 2e-16 ***

## ---

## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

## 

## Residual standard error: 0.03224 on 56 degrees of freedom

## Multiple R-squared:  0.999,  Adjusted R-squared:  0.999 

## F-statistic: 1.89e+04 on 3 and 56 DF,  p-value: < 2.2e-16

------------------------------------------------------


すると、上記の解析結果はfit6と同じt値になる

 このようにスケーリングによって異なるオーダーの説明変数でも係数の大きさから影響の大きさを比較が可能となる。また、今回の解析では影響がないが、ベイズ推定をするときはスケーリングによって推定値が収束しやすくなることが知られている。あまりに変数間のオーダーに違いがあると収束しにくくなるらしい。覚えておいて損はないだろう。