비용 함수가 최소가 되는 회귀 계수를 어떻게 구할 수 있을까?
경사 하강법은 비용 함수인 RSS를 최소화하는 방법을 직관적으로 제공하는 뛰어난 방식이다. 점진적인 계산을 반복하여 회귀 계수의 값을 업데이트하고 오류 값이 최소가 되는 회귀 계수를 찾는다.
아래와 같이 비용 함수가 포물선 형태의 2차 함수라면, 경사 하강법은 최초의 회귀 계수 (w) 값에서부터 미분을 적용한 뒤, 이 미분 값 (기울기 값) 이 계속 감소하는 방향으로 회귀 계수를 업데이트 한다.
마침내 더 이상 미분 값이 감소하지 않는 지점을 비용 함수가 최소인 지점으로 간주하고, 그때의 회귀 계수를 반환한다.
RSS 수식
RSS(w0, w1) = np.sum(np.square(y - y_pred)) / N
RSS w0, w1으로 편미분한 결과
w1_update = -(2 / N) * learning_rate * (np.dot(X.T, diff))
w0_update = -(2 / N) * learning_rate * (np.dot(w0_factors.T, diff))
경사 하강법의 일반적인 프로세스
w1 = w1 - w1_update
w0 = w0 - w0_update
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
## 간단한 회귀 식인 y = 4 * x + 6 을 근사하기 위한 100개의 데이터셋 생성
X = 2 * np.random.rand(100, 1)
y = 6 + 4 * X + np.random.randn(100,1)
## X, y 데이터셋 산점도로 시각화
plt.scatter(X, y)
## w0, w1을 받아 w0_update, w1_update 반환
def get_weight_updates(w1, w0, X, y, learning_rate=0.01):
N = len(y)
## w0_update, w1_update를 먼저 w1, w0와 동일한 크기를 가진 0으로 초기화
w1_update = np.zeros_like(w1)
w0_update = np.zeros_like(w0)
## 예측 배열을 계산하고 예측과 실제 값의 차이를 계산
y_pred = np.dot(X, w1.T) + w0
diff = y - y_pred
## w0_update를 dot 행렬 연산으로 구하기 위해 모두 1 값을 가진 행렬 생성
w0_factors = np.ones((N, 1))
## w0_update, w1_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 w0_update, w1_update
## get_weight_updates를 경사 하강 방식으로 반복하여 w1, w0을 업데이트하는 방식
def gradient_descent_steps(X, y, iters=10000):
## w0, w1을 0으로 초기화
w0 = np.zeros((1, 1))
w1 = np.zeros((1, 1))
## iters 만큼 반복적으로 get_weights_updates를 호출하여 w1, w0 업데이트
for ind in range(iters):
w0_update, w1_update = get_weight_updates(w1, w0, X, y, 0.01)
w1 = w1 - w1_update
w0 = w0 - w0_update
return w1, w0
def get_cost(y, y_pred):
N = len(y)
cost = np.sum(np.square(y - y_pred)) / N
return cost
w1, w0 = gradient_descent_steps(X, y, 1000)
y_pred = w1[0, 0] * X + w0
get_cost(y, y_pred)
plt.scatter(X, y)
plt.plot(X, y_pred)
일반적으로 경사 하강법은 모든 데이터에 대해 반복적으로 비용 함수 최소화를 위한 업데이트를 한다. 따라서 수행 시간이 매우 오래 걸린다는 단점이 있다.
때문에 실전에서는 대부분 확률적 경사 하강법 (Stochastic Gradient Descent) 를 이용한다. 이는 일부 데이터만 이용하여 회귀 계수를 업데이트하기 때문에 빠른 속도를 보장한다.
특히, 미니 배치 확률적 경사 하강법은 전체 데이터셋 중 랜덤하게 배치 사이즈만큼 데이터를 추출하고, 이를 기반으로 회귀 계수를 업데이트한다.
파이썬 머신러닝 완벽 가이드 교재