Python/데이터 분석 기초

Multiple Linear Regression 정리 + 느낌

동현 유 2021. 3. 29. 21:02

"""최근 맨 땅에 헤딩하는 식으로 빅데이터를 혼자 공부했었는데,
Feature Engineering 할 때,

왜 해당 피쳐를 선택해야하는지, 어떤 건 없애야하는지, 어떤 피처는 만들어서 사용해도 되는지 등에 대한 논리적 근거가 궁금했다.

다른 사람들이 수행한 EDA를 열심히 뜯어봐도 수학적 근거까지는 명시하지 않았기 때문이다.

대충 싸이킷런으로 예측과 분류의 정확도를 올리는 법을 익힌 후에, '아~ 그냥 이게 전부인가..?'라는 생각에 딥러닝에 도전했다,, 

텐서플로우를 통해 잠시 공부하다가, 싸이킷런처럼 fit() 하고 결과가 나와버리는 것을 보고,,, 너무,,, 답답했다.

속 알맹이에 뭐가 들어있는지도 모르고 쓰는게 너무 찝찝해서, 모델들을 수학적으로 더 공부해야할 필요성을 느꼈다.

수학적인 부분들을 공부하면서 코딩과는 다르게 겉으로 보이는 결과물이 나오지 않아서 조바심이 들기도 한다.

그래도,, 지금 나에게 꼭 필요한 부분이라고 생각이 들어서 공부해보았다.

먼저 기본적인 선형회귀부터 복습했는데, 빅데이터의 시각이 더해지면서 알게 된 것이 꽤 많았다."""

 - Feature를 신뢰할 수 있는가?    =>>>  다중공선성 / t-value 
 - 다중공선성의 기하학적 의미
 - Float 행렬 계산 시의 최적화 필요성   =>>>  행렬분해(QR decomposition / LU decomposition)
 - 행렬분해 알고리즘 : 그람슈미트, 하우스홀더, 기븐스회전, 가우스소거 등등
 - 행렬 계산을 위한 탄탄한 선형대수학 지식....
  선형대수학을 따로 더 깊게 공부하면서 파이썬으로 구현하는 공부를 해볼까.. 하는 생각도 든다.

 

 

1. 선형회귀 정의

선형회귀는 여러 데이터가 있을 때, 그 값을 잘 예측할 수 있는 하나의 선을 그린다고 생각하면 쉽다.

 

하나의 선을 그렸을 때 개별 데이터와의 오차가 발생하게 되는데,

 

이 오차를 최소화하는 선을 찾으면 된다.

 

오차를 계산할 때 음수도 있기 때문에 

 

보통은 오차 제곱의 평균(RMS)을 이용한다. (다른 것도 많이 사용한다.)

 

이를 수식으로 나타낸 것을 \(Cost Function\)이라고 한다.

 

즉 (오차 제곱의 평균을 최소화) = (\(Cost Function\)을 최소화) 이다.

 

Cost Function을 수식으로 표현하면 $$Cost Funtion = mean(\hat{y} - y)^{2}$$

\(\hat{y}\)는 예측한 값이다.

 

개별 데이터에서 빨간 선으로 직선에 내렸을때의 y값과 같다. 

 

따라서 오차를 최소화하는 것이 선형회귀의 핵심이다.

 

이 말은 \(Cost Function\) 을 최소화 한다는 말과 같다.

 

 


2. 최적해 계산

 

아래의 행렬로 이루어진 식이 있다고 하자.

  • \(y\) : 종속변수, 즉 관측한 결과값
  • \(beta\) : 구하고자 할 계수
  • \(X\) : k개의 선형독립적인 피처를 갖는 행렬 / 주어진 조건 / 데이터들
  • \(\epsilon\) : y에 대한 예측치 \(\hat{y}=X\beta\) 와 \(y\) 의 차이

위의 행렬로 이루어진 식을 아래와 같이 간편하게 나타낼 수 있다.

 

$$y = X\beta + \epsilon$$

$$e = y - X\hat{\beta}$$

 

Cost Function인 오차 제곱의 평균(RMS) 가 최소가 되어야한다.

행렬식의 편의를 위해 오차 제곱의 합(RSS)으로 최소가 되는 \(\hat{\beta}\)을 찾아보자

 

$$RSS = e^{T}e$$

 

 

$$e^{T}e = (y - X\hat{\beta})^{T}(y - X\hat{\beta})$$

$$ = y^{T}y - 2\hat{\beta}^{T}X^{T}y + \hat{\beta}^{T}X^{T}X\hat{\beta}$$ 

 

스칼라의 역치는 그대로 동일하다는 점을 이용한 후 미분해보자

\((i.e > y^{T}X\hat{\beta} = (y^{T}X\hat{\beta})^{T} = \hat{\beta}^{T}X^{T}y)\)

 

$$\frac{\partial{e^{T}e}}{\partial{\hat{\beta}}} = -2X^{T}y + 2X^{T}X\hat{\beta} = 0$$

 

위의 식을 만족하는 \(\beta\)가 최솟값을 갖는다.

한 번 더 위의 식을 미분한 2계도 함수는 \(2X^{T}X\) 이다.

\(X\)가 선형독립의 \(col\)들로 이루어졌다는 가정에 의해

\(2X^{T}X\)는 양의 정부호 행렬이다.

따라서 이계도함수가 항상 양수이고, 일계도함수가 0인 곳이 최솟값을 갖는다고 할 수 있다.

위의 가정이 굉장히 중요한데, Feature Select 할 때의 다중공선성 문제를 다뤄야하기 때문이다.

 - 다중공선성의 기하학적 의미1

 - 다중공선성의 기하학적 의미2

 - 다중공선성과 VIF

 - 다중공선성을 무시해도 될때?

 - 주성분분석(PCA), 차원축소, Feature Selection

 - p-value

 - 따로 다중공선선에 대해 정리해봐야겠다...

 

위의 식을 정리하면 아래와 같은 'normal equations'을 얻는다.

$$(X^{T}X)\hat{\beta} = X^{T}y$$

역행렬이 존재한다는 가정하에 

$$\hat{\beta} = (X^{T}X)^{-1}X^{T}y$$


3. 행렬 연산 최적화

위 식은 '수학적'으로는 문제가 없지만 컴퓨터 공학적으로는 매우 좋지 않은 방법이다.

기본적으로 float 형 자료를 연산할 때는 오차가 발생한다.

역함수를 구하는 추가적인 연산으로 연산량이 많아지고, 그에 따른 오차가 증폭된다.

normal equation을 풀 때에는 LU decomposition을 이용해야한다.

(numpy.linalg.solve() 함수는 내부적으로 LU 분해를 사용한다고 함)

 

LU decompostion 을 이용하면, 삼각행렬을 이용하여 중간해를 매우 간편하게 구할 수 있다.

상대적으로 계산량이 많이 적으므로 발생 오차도 적다.

따라서 행렬 계산시에는 행렬을 최적화하는 것이 필수적인데,

$$(X^{T}X)\hat{\beta} = X^{T}y$$

위 식을 최적화해보자!

 

곧 바로 LU decomposition을 통해 구한다고 하면,

좌변을 \((X^{T}X)\hat{\beta} = A\hat{\beta}\), 우변을 \(X^{T}y = B\)으로 하여 

$$A\hat{\beta} = B$$

를 풀면 된다.

하지만 \(X^{T}X\)의 행렬곱을 수행하지 않아도 되는 추가적인 최적화 방법이 있다.

바로 \(X\)를 QR decomposition 하는 것이다.

이 때 Q 는 모든 basis가 orthogonal 한 행렬이고, R 은 상삼각행렬이다.

orthogonal matrix는 \(Q^{T}Q = I\) 가 성립한다.

(모든 \(col\)이 수직이라는 정의에 의해 성립)

 

따라서 \(X = QR\)로 분해하여 위의 normal equation을 최적화해보면

$$(X^{T}X)\hat{\beta} = X^{T}y$$

$$(QR)^{T}(QR)\hat{\beta} = (QR)^{T}y$$

$$R^{T}Q^{T}QR\hat{\beta} = R^{T}Q^{T}y$$

$$R^{T}R\hat{\beta} = R^{T}Q^{T}y$$

$$R\hat{\beta} = Q^{T}y$$

위 식을 얻는다. 

 

\(R\)이 상삼각행렬이기 때문에 계산을 최소화하여 \(\hat{\beta}\)를 구할 수 있다.

 

 

QR decomposition 방법에는 여러가지가 있는데 

 

①그람슈미트 ②하우스홀더변환 ③기븐스회전변환

 

3가지를 살펴보았다.

그람슈미트 방법은 오차 증폭이 크게 되는 방법이라 선호하지는 않고

하우스홀더변환과 기븐스회전변환을 쓰는 모양이다.

 

다음에는 LU decomposition 과 QR decomposition 을 파이썬으로 구현해보고

 

선형회귀의 정확도와 시간복잡도를 비교해보겠다!