1. 회귀 분석이란?
- 데이터를 가장 잘 설명하는 모델을 찾아 입력값에 따른 미래 결과값을 예측하는 알고리즘
$$ Y \approx \beta_0 + \beta_1 X $$
- 위 수식에서 적절한 \( \beta_0, \beta_1 \) 값을 찾는 것이 이 알고리즘의 핵심
- 완벽한 예측은 불가능하기에 최대한 잘 근사해야함
2. 단순 선형 회귀
- 데이터를 설명하는 모델을 직선 형태로 가정한 것
- 가장 기초적이나 여전히 많이 사용되는 알고리즘
$$ Y \approx \beta_0 + \beta_1 X $$
- 직선을 구성하는 \( \beta_0 \)(=y절편)과 \( \beta_1 \)(=기울기)을 구하는 것
- 입력값이 1개인 경우에만 적용이 가능함
- 입력값과 결과값의 관계를 알아보는 데 용이함
- 입력값이 결과값에 얼마나 영향을 미치는지 알 수 있음
- 두 변수 간의 관계를 직관적으로 해적하고자 하는 경우 활용
from sklearn.linear_model import LinearRegression
- 기계학습 라이브러리 scikit-learn을 사용하면 Loss 함수를 최솟값으로 만드는 \( \beta_0, \beta_1 \)을 쉽게 구할 수 있음
- LinearRegression 모델의 입력값으로 Pandas의 dataframe의 feature(=x) 데이터와 Series 형태의 label(=y) 데이터를 입력받을 수 있으며, X, Y의 샘플 개수는 같아야 함
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
train_X = pd.DataFrame(X, columns=['X'])
train_Y = pd.Series(Y)
model = LinearRegression() # 모델 초기화
model.fit(train_X, train_Y) # train_X, train_Y 데이터 학습하기
predict_model = model.predict(X) # train_X에 대해 예측하기
# 학습한 결과 시각화하기
plt.scatter(X, Y)
plt.plot([0, 10], [model.intercept_, 10*model.coef_[0] + model.intercept_], c='r')
plt.xlim(0, 10)
plt.ylim(0, 10)
plt.title('Training Result')
plt.savefig('test.png')
Loss 함수
- 실제값과 예측값 차이의 제곱의 합을 Loss 함수로 정의하며, loss 함수의 값이 작을수록 좋은 모델
$$ \frac{1}{N} \sum_{i}^{N}{(y^{(i)} - (\beta_0 + \beta_1 x^{(i)}))^2} $$
- \( i \)번째 데이터 \( (x^{(i)}, y^{(i)}) \)에 대해서
- 입력값은 \( x^{(i)} \)
- 실제값은 \( y^{(i)} \)
- 예측값은 \( \beta_0 x^{(i)} +\beta_1 \)
- Loss 함수의 크기를 작게 하는 \( \beta_0, \beta_1 \) 를 찾는 방법은 다음과 같음
$$ argmin \frac{1}{N} \sum_{i}^{N}{(y^{(i)} - (\beta_0 + \beta_1 x^{(i)}))^2} $$
- 초기값에서 점진적으로 구하는 방식 = 경사 하강법
경사하강법
\( \beta_0, \beta_1 \)값을 Loss 함수 값이 작아지게 계속 업데이트하는 방법
1. \( \beta_0, \beta_1 \)값을 랜덤하게 초기화
2. 현재 \( \beta_0, \beta_1 \) 값으로 Loss값 계산
3. 현재 \( \beta_0, \beta_1 \)값을 어떻게 변화해야 Loss 값을 줄일 수 있는지 알 수 있는 Gradient값 계산
4. Gradient 값을 활용하여 \( \beta_0, \beta_1 \) 값 업데이트
5. Loss 값의 차이가 거의 없어질 때 까지 2~4번 과정을 반복하면
-> Loss 값과 차이가 줄어들면 Gradient 값도 작아짐
3. 다중 선형 회귀
- 여러 개의 입력값(\(X\))으로 결과값(\(Y\))을 예측하고자 하는 경우 사용
- 입력값 \(X\)가 여러 개(2개 이상)인 경우 활용할 수 있는 회귀 알고리즘
- 각 개별 \(X_i\)에 해당하는 최적의 \(\beta_i\)를 찾아야 함
$$ Y \approx \beta_0 + \beta_1X_1 + \beta_2X_2 + \beta_3X_3 + ... + \beta_MX_M $$
- 어떤 입력값이 결과값에 어떠한 영향을 미치는지 알 수 있음
- 여러 개의 입력값 사이 간의 상관 관계가 높을 경우 결과에 대한 신뢰성을 잃을 가능성 있음
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
# X : dataframe, Y : Series
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(train_X, train_Y)
beta_0 = model.intercept_ # y 절편
beta_1 = model.coef_[0] # 1번째 변수에 대한 계수
beta_2 = model.coef_[1] # 2번째 변수에 대한 계수
beta_3 = model.coef_[2] # 3번째 변수에 대한 계수
pred_X = lrmodel.predict(test_X) # test_X에 대해서 예측하기
Loss 함수
- 단순 선형 회귀와 마찬가지로 입력값과 실제값 차이의 제곱의 합으로 정의함
- 마찬가지로 \(\beta_0, \beta_1, \beta_2, ... , \beta_M\)값을 조절하여 Loss 함수의 크기를 작게 함
$$ \frac{1}{N} \sum_{i}^{N}{(y^{(i)} - (\beta_0 + \beta_1 x_1^{(i)} + \beta_2 x_2^{(i)} + ... + \beta_M x_M^{(i)}))^2} $$'
- \(y^{(i)}\) : 실제값
- \( \beta_0 + \beta_1 x_1^{(i)} + \beta_2 x_2^{(i)} + ... + \beta_M x_M^{(i)}\) : 예측값
다중 선형 회귀 모델의 경사 하강법
1) \(\beta_0, \beta_1, \beta_2, ... , \beta_M\)값을 랜덤하게 초기화
2) 현재 \(\beta_0, \beta_1, \beta_2, ... , \beta_M\)값으로 Loss 값 계산
3) 현재 \(\beta_0, \beta_1, \beta_2, ... , \beta_M\)값을 어떻게 변화해야 Loss값을 줄일 수 있는지 알 수 있는 Gradient 값 계산
4) Gradient 값을 활용하여 \(\beta_0, \beta_1, \beta_2, ... , \beta_M\)값 업데이트
5) Loss값의 차이가 거의 없어질 때 까지 2~4번 과정을 반복(Loss값과 차이가 줄어들면 Gradient 값도 작아짐)
4. 회귀 평가 지표
- 어떤 모델이 좋은 모델인지, 목표를 얼마나 잘 달성했는지 정도를 평가해야 함
- 실제 값과 모델이 예측하는 값의 차이에 기반한 평가 방법 사용
- Loss는 모델에서 줄여야하는 값(대상)이며, MSE 등등은 지표
RSS(단순 오차;Residual Sum of Squares)
- 실제값과 예측값의 단순 오차 제곱의 합
- 값이 작을수록 모델의 성능이 높음
- 전체 데이터에 대한 실제값과 예측하는 값의 오차 제곱의 총합
$$ RSS = \sum_{i}^{N}{(y^{(i)} - (\beta_0 + \beta_1 x^{(i)}))^2} $$
- 가장 간단한 평가 방법으로 직관적인 해석이 가능함
- 그러나 오차를 그대로 이용하기 때문에 입력값의 크기에 의존적임
- 절대적인 값과 비교가 불가능함
MSE(Mean Square Error)
- 평균 제곱 오차
$$ MSE = \frac{1}{N}\sum_{i}^{N}{(y^{(i)} - (\beta_0 + \beta_1 x^{(i)}))^2} $$
- RSS에서 데이터 수 만큼 나눈 값
- 작을수록 모델의 성능이 높다고 할 수 있음
- 이상치(Outlier), 즉 데이터들 중 크게 떨어진 값에 민감함
from sklearn.metrics import mean_squared_error
mean_squared_error(y_true, y_pred)
MAE(Mean Absolute Error)
- 평균 절대값 오차
$$ MAE = \frac{1}{N} \sum_{i}^{N}{|y^{(i)} - (\beta_0 + \beta_1 x^{(i)})|} $$
- 실제값과 예측값의 오차의 절대값의 평균
- 작을수록 모델의 성능이 높다고 할 수 있음
- 변동성이 큰 지표와 낮은 지표를 같이 예측할 시 유용
- 가장 간단한 평가 방법들로 직관적인 해석이 가능
- 평균을 그대로 이용해 입력값의 크기에 의존적임
- 절대적인 값과 비교가 불가능함
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_true, y_pred)
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(train_X, train_Y)
# train_X의 예측값 계산
pred_train = model.predict(train_X)
MSE_train = mean_squared_error(train_Y, pred_train)
MAE_train = mean_absolute_error(train_Y, pred_train)
\(R^2\) (결정계수)
- 회귀 모델의 설명력을 표현하는 지표
- 1에 가까울수록 높은 성능의 모델이라고 해석할 수 있음
$$ R^2 = 1 - \frac{RSS}{TSS} $$
- TSS : 데이터 평균값(\(\bar{y}\))과 실제값(\(y^{(i)}\)) 차이의 제곱
$$ TSS =\sum_{i}^{N}{(y^{(i)} - \bar{y})^2} $$
$$ \bar{y} = \frac{1}{N}\sum_{i}^{N}{y^{(i)}} $$
# test_X의 예측값 계산
pred_test = model.predict(test_X)
# test_X의 R2값 계산
r2_score(test_Y, pred_test)
- 오차가 없을수록 1에 가까운 값을 가짐
- 값이 0인 경우, 데이터의 평균값을 출력하는 직선 모델을 의미함
- 음수값이 나온 경우, 평균값 예측보다 성능이 좋지 않음
'데이터 사이언스 > 머신러닝' 카테고리의 다른 글
[NIPA AI 교육/응용] 05. 퍼셉트론 (0) | 2021.09.05 |
---|---|
[NIPA AI 교육/응용] 04. 지도학습 (0) | 2021.08.28 |
[NIPA AI 교육/응용] 02. 자료 형태의 이해 (0) | 2021.08.25 |
[NIPA AI 교육/응용] 01. 자료 형태의 이해 (0) | 2021.08.25 |
[NIPA AI 교육/응용] 00. 인공지능/머신러닝 개론 (0) | 2021.08.24 |