08. 확률적 경사 하강법

yellowsubmarine372·2023년 8월 13일
1

머신러닝

목록 보기
8/18

colab link
Stochastic Gradient Descent

1. 확률적 경사 하강법

확률적 경사 하강법은 알고리즘 보다는 최적화하는 "훈련방법"
딱 하나의 샘플을 훈련세트에서 랜덤하게 골라 가장 가파른 길을 찾는 방법이 확률적 경사 하강법(한번에 많이 이동할 경우 오차가 발생할 확률이 크므로 조금씩 경사를 이동)

  • 미니배치 경사하강법
    여러개의 샘플을 사용해 경사하강법을 수행

  • 배치 경사 하강법
    전체 샘플을 사용하는 방법, 가장 안정적인 방법이지만 데이터가 너무 많은 경우 데이터를 전부 처리하는 데 어려움 겪을 수 있음

손실 함수

머신러닝 알고리즘의 평가 척도
기존에 사용한 정확도는 불연속적이므로 손실함수로 쓰일 수 없습니다. 연속적인 손실함수를 만드는 방법은 '로지스틱 회귀'로 가능하다.

  • 로지스틱 손실 함수
    로그함수를 적용해 예측확률이 0에서 멀어져 1에 가까워질 수록 손실은 큰 양수임을 확인 가능

에포크

훈련 세트를 한번 모두 사용하는 과정

2. SGDClassifier

  • 데이터 준비하기
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', 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))

#에포크 한번 더 실행
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))

에포크를 한번 더 실행하니 정확도가 향상됨. 어떤 에포크에서 정확도가 최대인지 확인 필요하다.

3. 에포크와 과대/과소적합


import numpy as np
sc = SGDClassifier(loss='log', 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))

모델을 이어서 훈련할 경우에 fit() 대신 partial_fit() 함수 이용

각 에포크 실행 횟수에 따라 훈련세트와 테스트세트의 정확도 점수를 저장한다. 그리고 차이가 최소가 되는 지점을 아래 그래프를 통해 찾는다.

import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()

sc.partial_fit(train_scaled, train_target, classes=classes)

partial_fit() 메서드만 사용하려면 훈련세트에 있는 전체 클래스의 레이블을 partial_fit() 메서드에 전달해야 함

에포크가 100회일 때 가장 최적화된 경우로 보인다. SGDClassifier의 반복횟수를 100으로 맞추고 모델을 다시 훈련해본다.

sc= SGDClassifier(loss='log', 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))
#result

0.957983193277311
0.925

에포크가 100일때 가장 높은 정확도 점수를 보인다.

SGDClassifer는 일정 에포크동안 성능이 향상되지 않으면 더 훈련하지 않고 자동으로 멈춘다.

profile
for well-being we need nectar and ambrosia

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

이런 유용한 정보를 나눠주셔서 감사합니다.

답글 달기