확률적 경사 하강법(Stochastic Gradient Descent, SGD)은 기계 학습 및 딥 러닝에서 모델을 학습시키는 데 사용되는 최적화 알고리즘 중 하나다. 이 알고리즘은 손실 함수를 최소화하거나 최대화하는 모델 파라미터의 값을 찾는 데 사용된다. SGD는 다음과 같은 주요 특징을 갖고 있다.
확률적(Stochastic): SGD는 각 학습 단계에서 무작위로 선택한 데이터 포인트(또는 미니배치)를 사용하여 모델 파라미터를 업데이트한다. 이는 데이터의 전체 세트를 사용하는 전통적인 경사 하강법과 대조됩니다. 이로 인해 빠르게 학습이 진행되며, 대규모 데이터 세트에서도 효과적으로 작동한다.
경사 하강법(Gradient Descent): SGD는 손실 함수의 기울기(경사)를 활용하여 모델 파라미터를 조정한다. 경사는 현재 파라미터 설정에서 손실 함수가 어떤 방향으로 더 낮아지는지 나타내는 정보를 제공한다. 파라미터를 이 방향으로 이동시켜 손실을 최소화하는 것이 SGD의 목표이다.
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
fish_target = fish['Species'].to_numpy()
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
fish_input, fish_target, random_state=42)
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
위를 통해 우선 해당 파일에서 판다스 데이터 프레임을 만들어보자
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log_loss', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
loss = 'log_loss'로 지정하여 로지스틱 손실 함수를 지정했다.
max_iter는 수행할 에포크 횟수를 지정한다. 10으로 지정하여 전체 훈련 세트를 10회 반복했다.
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
아직 점수가 낮지만 에포크를 한번 더 실행하니 정확도가 향상되는걸 볼 수 있다. 훈련 횟수는 얼마나 지정하는 것이 좋을까?
import numpy as np
sc = SGDClassifier(loss='log_loss', random_state=42)
train_score = []
test_score = []
classes = np.unique(train_target)
for _ in range(0, 300):
sc.partial_fit(train_scaled, train_target, classes=classes)
train_score.append(sc.score(train_scaled, train_target))
test_score.append(sc.score(test_scaled, test_target))
300번의 에포크 동안 훈련을 반복하여 진행해 보자.
import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
데이터가 작기 때문에 아주 잘 나타나지는 않지만 백번째 에포크 이후 훈련세트와 테스트 세트의 점수가 조금씩 벌어진다. 이 경우 100번째 에포크가 적절한 반복 횟수인걸 알 수 있다.
sc = SGDClassifier(loss='log_loss', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
100회의 에포크로 맞추고 모델을 다시 훈련해 보자. 그리고 최종적으로 점수를 다시 확인하며 훈련 모델을 향상 시킬 수 있었다
sc = SGDClassifier(loss='hinge', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))