"""최근 맨 땅에 헤딩하는 식으로 빅데이터를 혼자 공부했었는데,
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 할 때의 다중공선성 문제를 다뤄야하기 때문이다.
- 주성분분석(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 을 파이썬으로 구현해보고
선형회귀의 정확도와 시간복잡도를 비교해보겠다!
'Python > 데이터 분석 기초' 카테고리의 다른 글
Kaggle - [House Prices] 집값 예측 모델링 후기 (0) | 2021.06.06 |
---|---|
[머신러닝을 위한 파이썬] 3. pandas 활용 예제 (0) | 2021.03.18 |
[머신러닝을 위한 파이썬] 2. numpy 활용 예제 (0) | 2021.03.18 |
[머신러닝을 위한 파이썬] 1.행렬 연산 구현해보기 (0) | 2021.03.18 |