[머신러닝 완벽가이드] Chap.5 회귀(1)

Elin·2021년 7월 8일
0
post-thumbnail

5.1 회귀 소개

개념

  • 회귀 분석: 데이터 값이 평균과 같은 일정한 값으로 돌아가려는 경향을 이용한 통계학 기법
  • 통계학의 회귀: 여러 개의 독립변수와 한 개의 종속변수 간의 상관관계를 모델링하는 기법
    • 선형/비선형, 독립변수의 개수(단일/다중), 종속변수의 개수에 따라 여러 유형
  • 머신러닝 회귀 예측의 핵심은 주어진 피처와 결정 값 데이터 기반에서 학습을 통해 최적의 회귀 계수를 찾아내는 것
  • 지도학습의 한 유형

종류

  • 선형 회귀: 실제 값과 예측값의 차이를 최소화하는 직선형 회귀선을 최적화(=회귀 계수를 최적화)
  • 규제에 따라 일반 선형 회귀(규제x), 릿지(L2 규제), 라쏘(L1 규제), 엘라스틱넷(L1+L2 규제)으로 나눌 수 있음
  • 로지스틱 회귀는 분류에 사용되는 선형 모델임(이진 분류, 희소 영역 분류, 텍스트 분류 등에서 뛰어난 성능)

5.2 단순 선형 회귀를 통한 회귀 이해

단순 선형 회귀

단순 선형 회귀: 독립 변수 1개, 종속 변수 1개인 선형 회귀
-> 직선 형태 y = α + β * x
선형회귀

  • 예측값: yhat = a + b * x (a: α의 추정치/ b: β의 추정치)
  • 잔차: 실제 값과 회귀 모델의 차이에 따른 오류 값(오차에 대한 추정치/모집단-오차, 표본집단-잔차)

RSS

  • RSS: 잔차 제곱의 평균(모집단에서는 오차 제곱의 평균)
  • 일반적으로 학습 데이터 건수로 나누어서 정규화된 식으로 표현함
    rss
  • 회귀에서의 비용(Cost)이며, 회귀 변수로 구성되는 RSS를 비용 함수라고 함
  • 머신러닝 회귀 알고리즘: 비용함수(=손실함수)를 지속해서 감소시키고 더이상 감소하지 않는 최소의 오류 값을 구함

5.3 경사하강법(Gradient Descent)

: 점진적으로 반복적인 계산을 통해 파라미터 값을 업데이트하면서 오류 값이 최소가 되는 파라미터를 구하는 방식 (=RSS(비용함수)가 최소가 되는 파라미터 구하는 방식)
ex. RSS(w) = R(w) 가 이차함수인 경우
경사하강법

과정

Step 1: 임의의 값으로 첫 비용함수의 값 계산
Step 2: 편미분 결과값에 학습률(보정계수)를 곱한 것을 마이너스하면서 계산하여 이전 값 업데이트
편미분

Step 3: 비용함수 값이 최소가 될 때 반복을 중지, 최적 파라미터 구함

# 비용함수
def get_cost(y, y_pred):
    N = len(y) 
    cost = np.sum(np.square(y - y_pred))/N  # RSS
    return cost
    
#### 경사하강법 함수

# 업데이트 함수 
def get_weight_updates(w1, w0, X, y, learning_rate=0.01):
    N = len(y)
    
    # 초기값: 각각 w1, w0의 shape와 동일한 크기를 가진 0 값
    w1_update = np.zeros_like(w1)  # np.zeros_like(w1): w1의 크기가 1x5이면, 0으로 채워진 1x5 행렬 생성
    w0_update = np.zeros_like(w0)

    y_pred = np.dot(X, w1.T) + w0  # np.dot(): 내적 계산
    diff = y-y_pred  # 실제, 예측 값의 차이 계산
         
    # w0_update를 dot 행렬 연산으로 구하기 위해 모두 1값을 가진 행렬 생성 
    w0_factors = np.ones((N,1))

    # w1과 w0을 업데이트할 w1_update와 w0_update 계산
    w1_update = -(2/N)*learning_rate*(np.dot(X.T, diff))
    w0_update = -(2/N)*learning_rate*(np.dot(w0_factors.T, diff))    
    
    return w1_update, w0_update

# 경사하강 함수
def gradient_descent_steps(X, y, iters=10000):

    # w0와 w1을 모두 0으로 초기화. 
    w0 = np.zeros((1,1))   # [0] 행렬
    w1 = np.zeros((1,1))
    
    # iters 만큼 반복적으로 get_weight_updates() 호출하여 w1, w0 업데이트
    for ind in range(iters):
        w1_update, w0_update = get_weight_updates(w1, w0, X, y, learning_rate=0.01)
        w1 = w1 - w1_update
        w0 = w0 - w0_update
              
    return w1, w0
    
w1, w0 = gradient_descent_steps(X, y, iters=1000)

확률적 경사 하강법

  • 모든 학습 데이터에 대해 반복적으로 비용함수 최소화를 위한 값을 업데이트하기 때문에 수행 시간이 매우 오래 걸린다는 경사 하강법 단점 보완
  • 일부 데이터만 이용하여 파라미터가 업데이트되는 값을 계산
  • 미니 배치 확률적 경사 하강법: 배치 사이즈 선택 (배치 사이즈=1인 경우가 확률적 경사 하강법)
    • 미니 배치=10 이면, N개의 데이터 모두를 계산하지 않고 10개만 계산한 후 값 업데이트
  • 경사 하강법으로 구한 파라미터 값과 예측 오류 비용이 큰 차이가 없으므로 큰 데이터를 처리할 경우에는 일반적으로 확률적 경사 하강법 이용
def stochastic_gradient_descent_steps(X, y, batch_size=10, iters=1000):
    w0 = np.zeros((1,1))
    w1 = np.zeros((1,1))
    prev_cost = 100000
    iter_index =0
    
    for ind in range(iters):
        np.random.seed(ind)
        
        # 전체 X, y 데이터에서 랜덤하게 batch_size만큼 데이터 추출
        stochastic_random_index = np.random.permutation(X.shape[0])
        sample_X = X[stochastic_random_index[0:batch_size]]
        sample_y = y[stochastic_random_index[0:batch_size]]
        
        # 랜덤하게 batch_size만큼 추출된 데이터로 w1_update, w0_update 계산 후 업데이트
        w1_update, w0_update = get_weight_updates(w1, w0, sample_X, sample_y, learning_rate=0.01)
        w1 = w1 - w1_update
        w0 = w0 - w0_update
    
    return w1, w0

w1, w0 = stochastic_gradient_descent_steps(X, y, iters=1000)

피처가 여러 개인 경우

피처여러개

y_pred = np.dot(Xmat, w.T) + w0

5.4 보스턴 주택 가격 예측

LinearRegression()

: RSS를 최소화해 OSL 추정 방식으로 구현한 클래스

  • 파라미터
    • fit_intercept: 절편 계산 유무(default=True)
    • normalize: 데이터 세트 정규화(default=False, fit_intercept=False인 경우, 이 파라미터 무시)
  • 속성
    • coef_: 회귀 계수의 배열
    • intercept_: intercept 값

다중공선성

: 피처 간의 상관관계가 매우 높은 경우 분산이 매우 커져서 오류에 민감해지는 현상
-> 독립적인 중요한 피처만 남기고 제거 or 규제 / PCA를 통한 차원 축소

회귀 평가 지표

  • MAE: 실제 값과 예측값의 차이의 절댓값의 평균(metrics.mean_absolute_error())
    mae
  • MSE: 실제 값과 예측값의 차이의 제곱의 평균(metrics.mean_squared_error())
    mse
  • RMSE: MSE의 루트값(metrics.r2_score())
    rmse
  • R^2: 실제 값의 분산 대비 예측값의 분산 비율(1에 가까울수록 예측 정확도 높음)
    r2

** scoring 함수에 회귀 평가 지표를 적용할 때는 평가 지표 값에 -1을 곱하여 작은 오류값이 더 큰 숫자로 인식하게 함

@

5.5 다항 회귀와 과(대)적합/과소적합 이해

다항 회귀 이해

다항 회귀: 독립변수의 단항식이 아닌, 다항식으로 표현되는 선형 회귀

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import numpy as np

def polynomial_func(X):
    y = 1 + 2*X[:,0] + 3*X[:,0]**2 + 4*X[:,1]**3   # y=1+2x1+3x1^2+4x2^3
    return y

# Pipeline 객체로 Streamline 하게 Polynomial Feature변환과 Linear Regression을 연결
model = Pipeline([('poly', PolynomialFeatures(degree=3)),
                  ('linear', LinearRegression())])
X = np.arange(4).reshape(2,2)
y = polynomial_func(X)

model = model.fit(X, y)

Polynomial 회귀 계수
[0. 0.18 0.18 0.36 0.54 0.72 0.72 1.08 1.62 2.34]

다항 회귀를 이용한 과소적합 및 과적합 이해

다항 회귀는 직선적 관계가 아닌 복잡한 다항 관계를 모델링할 수 있지만, 차수를 높일수록 학습 데이터에만 맞춘 학습이 이루어져 과적합 문제가 발생할 수 있음
과적합

  • Degree 1: 단순 선형 회귀. 너무 단순해 보임(과소적합). MSE = 0.407
  • Degree 4: 실제 데이터 세트와 유사함. 잡음까지는 예측하지는 못하였지만 코사인 곡선 기반으로 테스트 데이터를 잘 예측함. MSE = 0.043
  • Degree 15: 데이터 세트의 변동 잡음값까지 지나치게 반영하여 과적합 발생. MSE=182815432

편향-분산 트레이드오프

  • 매우 단순한 모델: 고편향성
  • 매우 복잡한 모델: 고분산성

편향분산

  • 저편향/저분산: 실제 결과에 근접 + 예측 변동이 크지 않음
  • 저편향/고분산: 실제 결과에 근접 + 예측 변동이 큼
  • 고편향/저분산: 실제 결과에서 벗어남 + 예측 변동이 크지 않음
  • 고편향/고분산: 실제 결과에서 벗어남 + 예측 변동이 큼

일반적으로 편향과 분산은 트레이드오프 관계에 있음
트레이드오프

: 편향이 높으면 분산이 낮아지고(과소적합), 반대로 분산이 높으면 편향이 낮아짐(과적합)
=> 따라서, 편향과 분산이 서로 트레이드오프를 이루면서 오류 Cost 값이 최대로 낮아지는 모델 구축하는 것이 가장 효율적

profile
Data Analyst | Statistics

0개의 댓글