[Machine Learning] 선형 회귀

선형 회귀(Linear Regression)란?

선형 회귀는 머신러닝에서 가장 단순하기도 하면서 대표적인 알고리즘으로,
종속 변수 y와 한 개 이상의 독립 변수 X와의 선형 상관 관계를 모델링하는 회귀분석 기법입니다.

좀 더 쉽게 말하면 주어진 데이터로부터
x와 y의 관계를 가장 잘 나타내는 직선을 그리는 것을 말합니다.

선형회귀는 프로그램에게 답을 알려 주면서 학습을 시키기 때문에 지도 학습 알고리즘에 속합니다.

그럼 선형 회귀에 대해 알아보기 전에 먼저 선형 회귀 용어부터 살펴보겠습니다.

선형 회귀 용어

  • 학습 데이터: 프로그램을 학습시키기 위해 사용하는 데이터
  • 목표 변수: 맞추려고 하는 값 (target variable, output variable이라고도 합니다.)
  • 입력 변수: 맞추는 데 사용하는 값 (input variable, feature라고도 합니다.)

보통 데이터를 표현할 때,
학습 데이터의 개수를 m,
i번 데이터의 x를 x(i),
i번 데이터의 y를 y(i)이라고 표현합니다.

가설 함수

선형 회귀에서 우리가 해야 하는 것은 데이터가 있을 때 최적선을 찾는 것입니다.
우리는 최적선을 찾아내기 위해 다양한 함수를 시도해봐야 할텐데,
이렇게 시도해보는 함수들을 가설 함수(hypothesis function)라고 합니다.

우리가 아는 일반적인 직선의 형태는
\(y = ax + b\)인데 선형 회귀에서는 일반적으로 사용하는 문자들이 따로 있습니다.
\(h(x) = \theta_0 + \theta_{1}x\) 의 형식으로 보통 작성하는데요,
지금은 이해의 편의를 위해서 입력 변수가 하나인 경우를 가정했지만,
실제로는 입력 변수가 여러 개인 경우가 더 많습니다.
그럴 경우에 아래와 같이
\(f = ax + by + cz + \dots\)의 형태로 쓰면 문자가 너무 많아서 보기에 좋지 않습니다.
따라서, 아래와 같이
\(h(x) = \theta_0 + \theta_{1}x_{1} + \theta_{2}x_{2} + \dots\)의 형태로 쓰는 게 좋습니다.

그리고 선형 회귀의 목적은 가장 적절한 \(\theta\)를 찾는 것입니다.
이걸 제대로 표현하기 위해서는 \(h\) 밑에 \(\theta\)를 작게 써서
가설 함수 \(h\)가 \(\theta\)에 의해 결정된다고 나타낼 수 있습니다.
\(h_{\theta}(x) = \theta_0 + \theta_{1}x_{1} + \theta_{2}x_{2} + \dots\)

평균 제곱 오차 (MSE)

선형 회귀를 위해서 여러 가설 함수를 시도해봐야 하는데,
어떤 가설 함수가 더 나은지 판단할 수 있는 기준이 있어야겠죠.

선형 회귀에서 가설 함수를 평가하는데 가장 많이 쓰이는 방법은
평균 제곱 오차, Mean Squared Error 입니다.
앞 글자만 따서 MSE라고도 합니다.

평균 제곱 오차라는 건 이 데이터들과 가설 함수가
평균적으로 얼마나 떨어져 있는지 나타냅니다.

가설 함수의 함숫값 - 실제 데이터 값을 오차 라고 합니다.
이걸 그냥 합해서 평균을 내기에는
오차가 양수일수도 음수일 수도 있으니 서로 상쇄되면서 올바른 오차 평균을 구하지 못하게 됩니다.

따라서, 이 오차 값들을 모두 제곱하고 제곱한 값들을 더한 후
데이터 개수만큼 나눠주면 MSE가 됩니다.
이 MSE 값이 크다면 그 가설 함수는 MSE 값이 더 작은 가설 함수보다 안좋은 가설 함수입니다.

오차 값들을 제곱하는 이유가 하나 더 있는데,
더 큰 오차에 대해서는 더 큰 페널티를 주기 위해서 제곱을 하는 것입니다.

수식으로 표현하면 아래와 같습니다.

\[\displaystyle MSE = \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}) - y^{(i)})^2\]

손실 함수

손실 함수는 가설 함수의 성능을 평가하는 함수입니다.
손실 함수의 아웃풋이 작을 수록 손실이 작기 때문에 가설 함수가 데이터에 더 잘 맞고,
아웃풋이 클 수록 손실이 크기 때문에 가설 함수가 데이터에 잘 안 맞는다는 것입니다.

손실 함수는 보통 J라는 문자를 쓰고,
선형 회귀의 경우에는 MSE가 손실 함수의 아웃풋입니다.

\[\displaystyle J(\theta) = \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}) - y^{(i)})^2\]

경사 하강법 (Gradient Descent)

가설 함수를 최적선이 되게끔 개선하려면
가설 함수를 평가하는 기준이 있어야 하는데, 그 기준이 되는 게 손실 함수입니다.

손실 함수는 인풋이 \(\theta\)입니다.
\(\theta\)에 따라 손실 함수의 아웃풋이 달라진다는 것입니다.

손실 함수의 아웃풋을 최소화하기 위해서 사용하는 방식 중 하나가
경사 하강법 (Gradient Descent)입니다.

아웃풋을 최소화하기 위해 손실 함수의 극소값을 향해 가야하는데요,
기울기가 음수인 지점에서는 \(\theta\)를 늘리는 방향으로,
기울기가 양수인 지점에서는 \(\theta\)를 줄이는 방향으로 \(\theta\)를 이동시키면 됩니다.

얼마나 이동시킬지는 현재 위치의 경사진 정도에 비례해서 움직이면 됩니다.
이런식으로 계산 후 개선을 반복하는 것이 경사 하강법입니다.

조금씩 극소점을 향해 내려가기 때문에 경사 하강법이라는 이름이 붙은 겁니다.

이걸 수식으로 표현하면 아래와 같습니다.

\[\displaystyle \theta \leftarrow \theta - \alpha\frac{\partial}{\partial\theta}J(\theta)\]

여기서 \(\alpha\)는 학습률(learning rate)로,
한 번에 얼마나 \(\theta\)를 업데이트할지를 나타내는 지표입니다.

이 값은 개발자가 직접 정해줘야 하는 값으로,
너무 크면 연산시간은 짧겠지만
발산하게 되거나 최저점을 넘어서 다른 지점에 도달하게 될 수도 있고,
너무 작으면 연산 시간이 길어지고,
global minimum이 아닌 local minimum을 최저점으로 인식하게 될 수 있는 문제가 있습니다.

따라서 이 learning rate 값에는 정답이 없고, 손실 함수의 값을 보며 개선해 나가야 합니다.

여태 다뤘던 경사 하강법을 시각화해보겠습니다.
먼저 cost가 줄어드는 모습을 그래프로 확인해보겠습니다.

가설 함수가 변하는 모습을 애니메이션으로 확인해보겠습니다.

모델 평가하기

가설 함수는 세상에 일어나는 상황을 수학적으로 표현한다는 의미에서 모델 이라고 부릅니다.
모델을 학습시키고 나면 이 모델이 얼마나 좋은지 평가를 해야합니다.

이 때 많이 쓰는 게 평균 제곱근 오차(root mean square error, RMSE)입니다.
그냥 위에서 다뤘던 MSE에 루트를 씌운 건데요,
목표 변수의 단위가 오차 제곱을 하면 단위2이 되므로 다시 단위를 돌려주기 위해서입니다.

그런데 학습을 시킬 때 사용했던 학습 데이터에 대해서 RMSE를 구해보면,
이미 모델이 학습 데이터를 기준으로 학습했으므로 RMSE가 낮게 나오는 것은 당연합니다.

따라서, 보통은 모델을 학습 시키기 위한 데이터와 모델을 평가하기 위한 데이터를 분리합니다.
모델을 학습 시키기 위해 쓰는 데이터 셋을 training set 이라고 하고,
모델을 평가하기 위해 쓰는 데이터 셋을 test set 이라고 합니다.

이렇게 데이터를 나누면 학습에 쓰인 데이터와 평가에 쓰인 데이터가 다르므로
좀 더 신빙성 있게 모델을 평가할 수 있게 됩니다.

scikit-learn을 이용한 간단한 선형회귀

Updated:

Leave a comment