[혼자 공부하는 머신러닝+딥러닝] 책의 내용을 정리한 글입니다.
개념
훈련한 모델을 버리지 않고 새로운 데이터에 대해서만 조금씩 더 훈련할 수는 없을까?
→ 이런 식의 훈련방식을 점진적 학습 또는 온라인 학습이라고 부른다.
확률적 경사 하강법
: 대표적인 점진적 학습 알고리즘으로, 훈련 세트에서 랜덤하게 하나의 샘플을 골라 손실 함수의 경사를 따라 최적의 모델을 찾는다.
- 무작위로 선택하는 샘플의 개수를 여러 개 사용하는 경우 미니배치 경사 하강법이라고 한다.
- 한 번에 전체 샘플을 사용하는 경우 배치 경사 하강법이라고 한다.
- 확률적 경사 하강법에서 훈련 세트를 한 번 모두 사용하는 과정을 에포크라고 부르며, 일반적으로 수십에서 수백 번의 에포크를 반복한다.
확률적 경사 하강법에서 말하는 손실 함수란 무엇일까?
손실 함수
: 확률적 경사 하강법이 최적화할 대상이며, 어떤 문제에서 머신러닝 알고리즘이 얼마나 엉터리인지를 측정하는 기준이다.
- 얼마나 안 좋은지를 측정하는 값이기에 손실함수의 값이 작을수록 좋다.
- 어떤 값이 최솟값인지는 알지 못한다.
- 손실 함수는 미분 가능해야 한다.
- 연속이어야 하고 미분계수(한 점에서의 접선의 기울기)가 존재해야 한다.
- 참고 - https://zhonya.tistory.com/73
손실 함수의 종류
- 로지스틱 손실 함수
- 이진 분류에서 사용하는 손실 함수로, 이진 크로스엔트로피 손실 함수라고도 부른다.
- 이 손실 함수를 사용하면 로지스틱 회귀 모델이 만들어진다.
- 타깃 = 1일 때 -log(예측확률)
- 예측 확률이 1에서 멀어질수록 손실은 아주 큰 양수가 된다.
- 타깃 = 0일 때 -log(1-예측 확률)
- 예측 확률이 0에서 멀어질 수록 손실은 아주 큰 양수가 된다.
- 크로스엔트로피 손실 함수
- 다중 분류에서 사용하는 손실 함수
- 평균 제곱 오차
- 회귀에서 사용하는 손실 함수
- 타깃에서 예측을 뺀 값을 제곱한 다음 모든 샘플에 평균한 값
코드 작성
확률적 경사 하강법을 사용해 점진적으로 학습하는 로지스틱 회귀 모델을 훈련해 보자.
데이터 준비
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
# 에포크 횟수 10회로 지정
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))
# => 0.773109243697479
# => 0.775
# partial_fit()를 사용해 1 에포크 이어서 훈련 진행 후 점수 확인
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
# => 0.8151260504201681
# => 0.85
에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있기 때문에 가장 적합한 에포크 횟수 찾기
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))
import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
과대적합이 시작되기 직전 횟수인 100이 가장 적절한 반복 횟수로 판단하고 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))
# => 0.957983193277311
# => 0.925
이 장에서 사용된 핵심 패키지와 함수
scikit-learn
- SGDClassfier
- 확률적 경사 하강법을 사용한 분류 모델을 만든다.
- loss - 최적화할 손실 함수를 지정, 기본값은 hinge(서포트 벡터 머신 알고리즘을 위한 손실 함수)
- penalty - 규제의 종류를 지정, 기본값은 L2 규제를 위한 l2이며 규제 강도는 alpha 매개변수에서 지정
- max_iter - 에포크 횟수를 지정, 기본값은 1000
- tol - 반복을 멈출 조건으로 n_iter_no_change 매개변수에서 지정한 에포크 동안 손실이 tol만큼 줄어들지 않으면 알고리즘이 중단, 기본값은 0.001이며 n_iter_no_change 기본값은 5
- SGDRegressor
- 확률적 경사 하강법을 사용한 회귀 모델
- loss - 최적화할 손실 함수를 지정, 기본값은 제곱 오차를 나타내는 squared_loss
'Machine Learning' 카테고리의 다른 글
[혼자 공부하는 머신러닝+딥러닝] 교차 검증과 그리드 서치 (0) | 2023.05.09 |
---|---|
[혼자 공부하는 머신러닝+딥러닝] 결정 트리 (0) | 2023.05.09 |
[혼자 공부하는 머신러닝 + 딥러닝] 로지스틱 회귀 (0) | 2023.04.27 |
[혼자 공부하는 머신러닝 + 딥러닝] 특성 공학과 규제 (0) | 2023.04.21 |
[혼자 공부하는 머신러닝 + 딥러닝] 선형 회귀 (0) | 2023.04.15 |