In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
np.random.seed(0) #.seed를 사용하면 실행 때 마다 동일한 셋트의 난수가 나타나게 할 수 있다.
X = 2 * np.random.rand(100, 1)
y = 6+4*X + np.random.randn(100, 1)
#X, y 데이터셋을 scatter plot으로 시각화
print(X.shape, y.shape)
plt.scatter(X, y)
Out[1]:
1) Vanilla Gradient Descent(일반 경사 하강법)¶
w0과 w1의 값을 최소화 할 수 있도록 업데이트 수행하는 함수 생성.¶
100개의 데이터 X(1,2,...,100)이 있으므로 예측값은 w0 + X(1)w1 + X(2)w1 +..+ X(100)*w1이며, 이는 입력 배열 X와 w1 배열의 내적으로 풀 수 있다. 즉, 예측 배열 y_pred는 np.dot(X, w1.T) + w0 이다.
그리고 경사하강법 수행 프로세스의 Step2 식에 따라 업데이트를 수행할 수 있는 함수를 만든다.
In [2]:
# w1 과 w0 를 업데이트 할 w1_update, w0_update를 반환.
def get_weight_updates(w1, w0, X, y, learning_rate=0.01):
N = len(y)
# 먼저 w1_update, w0_update를 각각 w1, w0의 shape와 동일한 크기를 가진 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))
# 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
반복적으로 경사 하강법을 이용하여 get_weigth_updates()를 호출하여 w1과 w0를 업데이트 하는 함수 생성¶
In [3]:
def gradient_descent_steps(X, y, iters=10000):
w0 = np.zeros((1, 1)) #초기값
w1 = np.zeros((1, 1)) #초기값
for i 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
예측 오차 비용을 계산을 수행하는 함수 생성 및 경사 하강법 수행¶
In [4]:
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, iters=1000)
print("w1:{0:.3f} w0:{1:.3f}".format(w1[0,0], w0[0,0]))
y_pred = w1[0,0] * X + w0
print('Gradient Descent Total Cost:{0:.4f}'.format(get_cost(y, y_pred)))
실제 정답이 4, 6이었으니.. 잘 찾아간듯하다. 시각화해보면
In [5]:
plt.scatter(X, y)
plt.plot(X,y_pred)
Out[5]:
2) Stochastic Gradient Descent(확률적 경사 하강법)¶
데이터를 Batch size 만큼 쪼개서 데이터를 선택하여 위의 과정을 반복하게 되는 것을 Stochastic Gradient Descent라고 한다.
In [6]:
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만큼 데이터 추출하여 sample_X, sample_y로 저장
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
In [7]:
np.random.permutation(X.shape[0])
Out[7]:
In [8]:
w1, w0 = stochastic_gradient_descent_steps(X, y, iters=1000)
print("w1:",round(w1[0,0],3),"w0:",round(w0[0,0],3))
y_pred = w1[0,0] * X + w0
print('Stochastic Gradient Descent Total Cost:{0:.4f}'.format(get_cost(y, y_pred)))
Reference¶
파이썬 머신러닝 완벽 가이드 - 권철민 저
'Data Science > Machine Learning' 카테고리의 다른 글
Classification 2. 앙상블 학습(Ensemble Learning) - Voting과 Bagging (0) | 2020.10.09 |
---|---|
Classification 1. 결정 트리(Decision Tree) (0) | 2020.10.08 |
Evaluation2. 회귀의 성능 평가 지표(MAE, MSE, RMSE, R제곱) (0) | 2020.09.28 |
Evaluation1 - 분류 모델 성능 지표 (Accuracy, Confusion Matrix, Precision, Recall, F1 score, ROC AUC ) (0) | 2020.09.28 |
Sklearn 익히기 - train/test data set 분리 및 Cross Validation (0) | 2020.09.28 |