다운로드
작성자: admin 작성일시: 2017-10-17 22:34:25 조회수: 3217 다운로드: 169
카테고리: 머신 러닝 태그목록:

스케일링과 변수 변환

회귀분석에 사용되는 데이터는 그 자체로 사용하기 보다는 스케일링이나 함수 변환 등의 전처리 과정을 거치는 경우가 많다. 전처리 과정은 공분산 행렬의 조건을 향상시키거나 데이터 간의 관계를 선형 모형에 맞게 바꾸기 위해 사용된다.

조건수

조건수(conditional number)는 공분산 행렬 $X^TX$의 가장 큰 고유치와 가장 작은 고유치의 비율을 뜻한다.

$$ \text{condition number} = \dfrac{\lambda_{\text{max}}}{\lambda_{\text{min}}} $$

조건수가 크면 역행렬을 계산할 때 오차가 미치는 영향이 커진다. 여기에서는 다음 연립방정식을 예로 들어 설명을 하겠다.

$$ Ax = b $$

조건수가 작은 경우

행렬 $A$가 단위 행렬이면 조건수는 가장 작은 경우로 조건수의 값이 1이다.

$$ \text{cond}(I) = 1 $$
In [1]:
A = np.eye(4)

이 행렬 $A$와 곱해져서 상수 벡터 $b$가 되는 벡터 $x$를 역행렬 $A^{-1}$을 사용하여 계산할 수 있다. 이 예에서는 상수 벡터 $b$가 1-벡터이다.

In [2]:
b = np.ones(4)
sp.linalg.solve(A, b)
Out:
array([1., 1., 1., 1.])

만약 상수 벡터에 약간의 오차가 있었다면 연립방정식의 해에도 동일한 수준의 오차가 발행한다.

In [3]:
sp.linalg.solve(A + 0.0001 * np.eye(4), b)
Out:
array([0.99990001, 0.99990001, 0.99990001, 0.99990001])

조건수가 큰 경우

다음과 같은 행렬을 생각하자. 이 행렬은 4차 힐버트 행렬로 조건수가 15000이 넘는다. 이렇게 연립방정식을 이루는 행렬의 조건수가 커지면 상수항 오차가 작은 경우에도 해의 오차가 커지게 된다.

In [4]:
A = sp.linalg.hilbert(4)
A
Out:
array([[1.        , 0.5       , 0.33333333, 0.25      ],
       [0.5       , 0.33333333, 0.25      , 0.2       ],
       [0.33333333, 0.25      , 0.2       , 0.16666667],
       [0.25      , 0.2       , 0.16666667, 0.14285714]])
In [5]:
np.linalg.cond(A)
Out:
15513.738738929038

이 행렬과 곱해져서 상수 벡터가 되는 벡터를 역행렬을 사용하여 찾으면 다음과 같다.

In [6]:
sp.linalg.solve(A, b)
Out:
array([  -4.,   60., -180.,  140.])

조건수가 크면 약간의 오차만 있어도 해가 전혀 다른 값을 가진다. 따라서 조건수가 크면 회귀분석을 사용한 예측값도 오차가 커지게 된다.

In [7]:
sp.linalg.solve(A + 0.0001 * np.eye(4), b)
Out:
array([ -0.58897672,  21.1225671 , -85.75912499,  78.45650825])

회귀분석과 조건수

회귀분석에서 조건수가 커지는 경우는 크게 두 가지가 있다.

  1. 변수들의 단위 차이로 인해 숫자의 스케일이 크게 달라지는 경우. 이 경우에는 스케일링(scaling)으로 해결한다.
  2. 다중 공선성 즉, 상관관계가 큰 독립 변수들이 있는 경우, 이 경우에는 변수 선택이나 PCA를 사용한 차원 축소 등으로 해결한다.

스케일링

보스턴 집값 데이터의 경우 회귀분석을 하면 조건수가 15,000 정도로 크게 나오는데 이는 각 독립 변수들이 0.1 단위부터 수백 단위까지 제각각의 크기를 가지고 있기 때문이다.

In [8]:
from sklearn.datasets import load_boston
boston = load_boston()
dfX = pd.DataFrame(boston.data, columns=boston.feature_names)
dfX.std()
Out:
CRIM         8.601545
ZN          23.322453
INDUS        6.860353
CHAS         0.253994
NOX          0.115878
RM           0.702617
AGE         28.148861
DIS          2.105710
RAD          8.707259
TAX        168.537116
PTRATIO      2.164946
B           91.294864
LSTAT        7.141062
dtype: float64
In [9]:
dfy = pd.DataFrame(boston.target, columns=["MEDV"])
df = pd.concat([dfX, dfy], axis=1)

model1 = sm.OLS.from_formula("MEDV ~ " + "+".join(boston.feature_names), data=df)
result1 = model1.fit()
print(result1.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   MEDV   R-squared:                       0.741
Model:                            OLS   Adj. R-squared:                  0.734
Method:                 Least Squares   F-statistic:                     108.1
Date:                Mon, 05 Nov 2018   Prob (F-statistic):          6.72e-135
Time:                        23:03:26   Log-Likelihood:                -1498.8
No. Observations:                 506   AIC:                             3026.
Df Residuals:                     492   BIC:                             3085.
Df Model:                          13                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept     36.4595      5.103      7.144      0.000      26.432      46.487
CRIM          -0.1080      0.033     -3.287      0.001      -0.173      -0.043
ZN             0.0464      0.014      3.382      0.001       0.019       0.073
INDUS          0.0206      0.061      0.334      0.738      -0.100       0.141
CHAS           2.6867      0.862      3.118      0.002       0.994       4.380
NOX          -17.7666      3.820     -4.651      0.000     -25.272     -10.262
RM             3.8099      0.418      9.116      0.000       2.989       4.631
AGE            0.0007      0.013      0.052      0.958      -0.025       0.027
DIS           -1.4756      0.199     -7.398      0.000      -1.867      -1.084
RAD            0.3060      0.066      4.613      0.000       0.176       0.436
TAX           -0.0123      0.004     -3.280      0.001      -0.020      -0.005
PTRATIO       -0.9527      0.131     -7.283      0.000      -1.210      -0.696
B              0.0093      0.003      3.467      0.001       0.004       0.015
LSTAT         -0.5248      0.051    -10.347      0.000      -0.624      -0.425
==============================================================================
Omnibus:                      178.041   Durbin-Watson:                   1.078
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              783.126
Skew:                           1.521   Prob(JB):                    8.84e-171
Kurtosis:                       8.281   Cond. No.                     1.51e+04
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.51e+04. This might indicate that there are
strong multicollinearity or other numerical problems.

이렇게 조건수가 크면 모수 추정 오차가 증폭될 가능성이 커진다. 이 효과를 확실하게 보기 위하여 일부러 다음처럼 조건수를 더 크게 만들어 보았다. 이 상태로 선형 회귀분석을 하면 성능이 급격하게 떨어지는 것을 볼 수 있다.

In [10]:
dfX2 = dfX.copy()
dfX2["TAX"] *= 1e13
df2 = pd.concat([dfX2, dfy], axis=1)

model2 = sm.OLS.from_formula("MEDV ~ " + "+".join(boston.feature_names), data=df2)
result2 = model2.fit()
print(result2.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   MEDV   R-squared:                       0.333
Model:                            OLS   Adj. R-squared:                  0.329
Method:                 Least Squares   F-statistic:                     83.39
Date:                Mon, 05 Nov 2018   Prob (F-statistic):           8.62e-44
Time:                        23:03:26   Log-Likelihood:                -1737.9
No. Observations:                 506   AIC:                             3484.
Df Residuals:                     502   BIC:                             3501.
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept     -0.0038      0.000     -8.543      0.000      -0.005      -0.003
CRIM          -0.1567      0.046     -3.376      0.001      -0.248      -0.066
ZN             0.1273      0.016      7.752      0.000       0.095       0.160
INDUS         -0.1971      0.019    -10.433      0.000      -0.234      -0.160
CHAS           0.0034      0.000     12.430      0.000       0.003       0.004
NOX           -0.0023      0.000     -9.285      0.000      -0.003      -0.002
RM             0.0267      0.002     14.132      0.000       0.023       0.030
AGE            0.1410      0.017      8.443      0.000       0.108       0.174
DIS           -0.0286      0.004     -7.531      0.000      -0.036      -0.021
RAD            0.1094      0.018      6.163      0.000       0.075       0.144
TAX         1.077e-15   2.66e-16      4.051      0.000    5.55e-16     1.6e-15
PTRATIO       -0.1124      0.011    -10.390      0.000      -0.134      -0.091
B              0.0516      0.003     19.916      0.000       0.046       0.057
LSTAT         -0.6569      0.056    -11.790      0.000      -0.766      -0.547
==============================================================================
Omnibus:                       39.447   Durbin-Watson:                   0.863
Prob(Omnibus):                  0.000   Jarque-Bera (JB):               46.611
Skew:                           0.704   Prob(JB):                     7.56e-11
Kurtosis:                       3.479   Cond. No.                     1.19e+17
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.19e+17. This might indicate that there are
strong multicollinearity or other numerical problems.

StatsModels에서는 모형지정 문자열에서 scale 명령을 사용하여 스케일링을 할 수 있다. 이 방식으로 스케일을 하면 스케일링에 사용된 평균과 표준편차를 저장하였다가 나중에 predict 명령을 사용할 때도 같은 스케일을 사용하기 때문에 편리하다. 더미 변수인 CHAS는 스케일을 하지 않는다는 점에 주의한다.

In [11]:
model3 = sm.OLS.from_formula(
    "MEDV ~ "
    "scale(CRIM) + scale(ZN) + scale(INDUS) + scale(NOX) + scale(RM) + scale(AGE) + "
    "scale(DIS) + scale(RAD) + scale(TAX) + scale(PTRATIO) + scale(B) + scale(LSTAT) + CHAS",
    data=df2)
result3 = model3.fit()
print(result3.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   MEDV   R-squared:                       0.741
Model:                            OLS   Adj. R-squared:                  0.734
Method:                 Least Squares   F-statistic:                     108.1
Date:                Mon, 05 Nov 2018   Prob (F-statistic):          6.72e-135
Time:                        23:03:26   Log-Likelihood:                -1498.8
No. Observations:                 506   AIC:                             3026.
Df Residuals:                     492   BIC:                             3085.
Df Model:                          13                                         
Covariance Type:            nonrobust                                         
==================================================================================
                     coef    std err          t      P>|t|      [0.025      0.975]
----------------------------------------------------------------------------------
Intercept         22.3470      0.219    101.943      0.000      21.916      22.778
scale(CRIM)       -0.9281      0.282     -3.287      0.001      -1.483      -0.373
scale(ZN)          1.0816      0.320      3.382      0.001       0.453       1.710
scale(INDUS)       0.1409      0.421      0.334      0.738      -0.687       0.969
scale(NOX)        -2.0567      0.442     -4.651      0.000      -2.926      -1.188
scale(RM)          2.6742      0.293      9.116      0.000       2.098       3.251
scale(AGE)         0.0195      0.371      0.052      0.958      -0.710       0.749
scale(DIS)        -3.1040      0.420     -7.398      0.000      -3.928      -2.280
scale(RAD)         2.6622      0.577      4.613      0.000       1.528       3.796
scale(TAX)        -2.0768      0.633     -3.280      0.001      -3.321      -0.833
scale(PTRATIO)    -2.0606      0.283     -7.283      0.000      -2.617      -1.505
scale(B)           0.8493      0.245      3.467      0.001       0.368       1.331
scale(LSTAT)      -3.7436      0.362    -10.347      0.000      -4.454      -3.033
CHAS               2.6867      0.862      3.118      0.002       0.994       4.380
==============================================================================
Omnibus:                      178.041   Durbin-Watson:                   1.078
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              783.126
Skew:                           1.521   Prob(JB):                    8.84e-171
Kurtosis:                       8.281   Cond. No.                         10.6
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

변수 변환

다음과 같은 경우에는 로그 함수 혹은 제곱근 함수 등을 사용하여 변환된 변수를 사용하면 회귀 성능이 향상될 수도 있다.

  • 독립 변수나 종속 변수가 심하게 한쪽으로 치우친 분포를 보이는 경우
  • 독립 변수와 종속 변수간의 관계가 곱셈 혹은 나눗셉으로 연결된 경우
  • 종속 변수와 예측치가 비선형 관계를 보이는 경우

원래 선형회귀모형의 가정에는 독립 변수나 종속 변수가 반드시 대칭 분포를 보여야 한다는 가정은 없지만 정규 분포에 가까운 분포를 보일 수록 선형회귀모형의 성능이 좋아지는 경우가 많다.

보스턴 집값 데이터에서는 가격, DIS, PTRATIO, LSTAT 등이 비대칭 분포를 이루거나 가격과 반비례 관계를 가지므로 이 변수들을 로그로 변환한 후에 선형회귀분석을 하면 성능을 향상시킬 수 있다.

In [12]:
model4 = sm.OLS.from_formula("np.log(MEDV) ~ "
                             "scale(CRIM) + scale(I(CRIM ** 2)) + "
                             "scale(ZN) + scale(I(ZN ** 2)) + "
                             "scale(INDUS) + "
                             "scale(NOX) + scale(RM) + scale(AGE) + "
                             "scale(np.log(DIS)) + scale(RAD) + scale(TAX) + "
                             "scale(np.log(PTRATIO)) + scale(B) + scale(np.log(LSTAT)) + CHAS",
                             data=df)
result4 = model4.fit()
print(result4.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:           np.log(MEDV)   R-squared:                       0.817
Model:                            OLS   Adj. R-squared:                  0.812
Method:                 Least Squares   F-statistic:                     146.2
Date:                Mon, 05 Nov 2018   Prob (F-statistic):          6.88e-170
Time:                        23:03:26   Log-Likelihood:                 165.33
No. Observations:                 506   AIC:                            -298.7
Df Residuals:                     490   BIC:                            -231.0
Df Model:                          15                                         
Covariance Type:            nonrobust                                         
==========================================================================================
                             coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------------
Intercept                  3.0291      0.008    369.651      0.000       3.013       3.045
scale(CRIM)               -0.2628      0.031     -8.553      0.000      -0.323      -0.202
scale(I(CRIM ** 2))        0.1278      0.024      5.315      0.000       0.081       0.175
scale(ZN)                 -0.0382      0.031     -1.230      0.219      -0.099       0.023
scale(I(ZN ** 2))          0.0359      0.028      1.299      0.195      -0.018       0.090
scale(INDUS)               0.0002      0.016      0.012      0.991      -0.031       0.032
scale(NOX)                -0.1128      0.017     -6.502      0.000      -0.147      -0.079
scale(RM)                  0.0377      0.012      3.254      0.001       0.015       0.060
scale(AGE)                 0.0088      0.014      0.612      0.541      -0.020       0.037
scale(np.log(DIS))        -0.1269      0.018     -6.910      0.000      -0.163      -0.091
scale(RAD)                 0.1842      0.024      7.673      0.000       0.137       0.231
scale(TAX)                -0.1111      0.024     -4.687      0.000      -0.158      -0.065
scale(np.log(PTRATIO))    -0.0827      0.011     -7.595      0.000      -0.104      -0.061
scale(B)                   0.0274      0.009      2.950      0.003       0.009       0.046
scale(np.log(LSTAT))      -0.2230      0.014    -15.403      0.000      -0.251      -0.195
CHAS                       0.0789      0.032      2.444      0.015       0.015       0.142
==============================================================================
Omnibus:                       38.517   Durbin-Watson:                   1.190
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              167.793
Skew:                           0.027   Prob(JB):                     3.67e-37
Kurtosis:                       5.821   Cond. No.                         13.7
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

질문/덧글

질문 있습니다. krox*** 2018년 8월 13일 11:08 오전

항상 감사합니다. 잘 보고 배우고 있습니다.
질문이 있습니다.

model3 = sm.OLS.from_formula("np.log(MEDV) ~ "
"scale(CRIM) + scale(I(CRIM ** 2)) + "
"scale(ZN) + scale(I(ZN ** 2)) + "
"scale(INDUS) + "
"scale(NOX) + scale(RM) + scale(AGE) + "
"scale(np.log(DIS)) + scale(RAD) + scale(TAX) + "
"scale(np.log(PTRATIO)) + scale(B) + scale(np.log(LSTAT)) + CHAS",
data=df)
여기에서

1. I(CRIM ** 2), I(ZN**2) 의 I()는 어떤 함수인가요?
2. CRIM, ZN 을 제곱하는 이유가 있나요?? 제곱을 해야하는 경우와 log를 씌워줘야 하는 경우의 차이를 알고 싶습니다.
3. CRIM이나 ZN의 경우는 "scale(CRIM) + scale(I(CRIM ** 2)) " 처럼 두 개의 feature를 사용하는데, 이렇게 하는 이유가 궁금합니다.
3. 지수화 또는 로그화를 안해주는 feature들은 어떤 기준으로 scale만 해주는 건가요?