728x90
반응형
마켓 "물꼬기"는 럭키백 이벤트를 오픈하고 매출이 껑충 뛰었다. 이제 각지에서 수산물을 공급하겠다고 합니다.
영업팀은 이제 Pupbani에게 7개의 생선 중에서 일부를 무작위로 제공해 머신러닝 모델을 학습할 수 있도록 하고 있다.
하지만 수산물을 제공하는 기관이 많아 샘플을 골라내는 일이 너무 힘들다.
어느 생선이 먼저 올지도, 모든 생선이 도착할 때까지 기다릴 수도 없다. 어떻게 해야할까...?
점진적인 학습
- 기존의 훈련 데이터에 새로운 데이터를 추가하여 모델을 새로 훈련한다면?
- 시간이 지남에 따라 데이터의 크기가 엄청 늘어나서 모델 훈련을 위한 서버를 늘려야하기 때문에 사용할 수 없다.
- 이전 데이터를 버리고 훈련 데이터 크기를 일정하게 유지한다면?
- 데이터 셋의 크기가 늘어나지는 않지만 데이터를 버릴 때 다른 데이터에 없는 중요한 데이터를 버린다면 큰일이다.
- 새로운 모델은 예측을 잘 못할 가능성이 있다.
- 앞서 훈련한 모델을 버리지 않고 새로운 데이터에 대해서만 조금씩 훈련하는 방법은 없을까?
- 이런 방식의 방법을 점진적 학습 또는 온라인 학습이라고 한다.
- 이 학습 방법의 대표적인 예는 확률적 경사 하강법(Stochastic Gradient Descent) 알고리즘이 있다.
확률적 경사 하강법
- 확률적 : 무작위하게, 랜덤하게
- 경사 : 기울기
- 하강 : 내려가는 방법
- 경사하강법 모델을 훈련하는 과정
- 실제 산에서 내려오는 것 처럼 가파른 길을 찾아 천천히 조금씩 내려온다.
- 확률적?
- 훈련 세트에서 랜덤하게 하나의 샘플을 고르는 것
- 결론적으로 확률적 경사 하강법은 "훈련 세트에서 랜덤하게 하나의 샘플을 선택하여 가파른 경사를 조금 내려간다."
- 이러한 과정을 반복한다.
- 만약 모든 샘플을 다 사용해도 다 내려오지 못한다면?
- 처음부터 다시 시작한다.
- 훈련 세트에 모든 샘플을 다시 채워 넣는다.
- 다시 랜덤하게 하나의 샘플을 선택하여 이어서 경사를 내려간다.
- 만족할만한 위치에 도달할 때까지 계속 내려간다.
- 훈련 세트를 한 번 모두 사용하는 과정을 에포크(epoch)라고 부른다.
- 일반적인 경사 하강법은 수십, 수백 번 이상 에포크를 수행한다.
- 이렇게 한다면 너무 무책임하게 내려가는 것이 아닐까?
- 잘못 들어선다면 돌아갈 수 없기 때문이다.
- 이러한 문제점을 해소하려고 무작위로 몇 개의 샘플을 선택해서 경사를 내려간다면 어떨까?
- 미니배치 경사 하강법(Minibatch Gradient Descent)
- 여러 개의 샘플을 사용해 경사 하강법을 수행하는 방법
- 미니배치 경사 하강법(Minibatch Gradient Descent)
- 극단적으로 한 번 경사로를 따라 이동하기 위해 전체 샘플을 사용할 수 도 있다.
- 배치 경사 하강법(Batch Gradient Descent)
- 컴퓨터 자원을 너무 많이 사용한다.
- 한 번에 전체 데이터를 모두 읽을 수 없을 수 있다.
- 배치 경사 하강법(Batch Gradient Descent)
- 이러한 확률적 경사 하강법을 반드시 사용하는 알고리즘 - 신경망 알고리즘
손실함수(Loss Function)
- 그런데 어디서 내려가야 하는 걸까?
- 가장 빠른 길을 찾아 내려가려고 하는 이 산은 도대체 무엇일까?
- 이 산을 손실 함수라 부른다.
- 손실함수는 어떤 문제에서 머신러닝 알고리즘이 얼마나 엉터리로 동작하는지 측정하는 기준이다.
- 손실함수의 값은 작을수록 좋다.
- 하지만 어떤 값이 최솟값인지는 알지 못한다.
- 가능한 많이 찾아보고 만족할만한 수준이면 산을 다 내려왔다고 인정해야한다.
- 다행히 우리가 다루는 많은 문제에 필요한 손실 함수는 이미 정의되어 있다.
- 예시1
- 도미와 빙어를 구분하는 문제: 도미는 1, 빙어는 0
- 예측을 4번 중에 2번 성공했다고 가정 - 정확도 0.5
- 정확도를 손실 함수로 사용한다.
- 4개의 샘플만 있다면 5가지의 정확도이기 때문에 그래프를 그렸을 때 듬성듬성 그려진다.
- 어떻게 하면 연속적인 함수를 만들 수 있을까?
- 로지스틱 회귀 모델에서 확률을 출력할 때 예측은 0 or 1이지만 0~1 사이의 어떤 값도 될 수 있다.
- 연속적이다.
- 로지스틱 회귀 모델에서 확률을 출력할 때 예측은 0 or 1이지만 0~1 사이의 어떤 값도 될 수 있다.
로지스틱 손실 함수
- 예시2
- 샘플 4개의 예측 화률 값과 타겟 값 을 가정한다.
- 예측 확률 값 : 0.9, 0.3, 0.2, 0.8
- 타겟 값 : 1, 1, 0, 0
- 손실 함수 = (양성 클래스 예측 확률 ) x (-1)
- -1 ~ 0 사이의 실수 값이 된다.
- 음성 클래스들은 "1-음성 클래스 예측"으로 사용한다.
- 샘플 4개의 예측 화률 값과 타겟 값 을 가정한다.
- 예측 확률에 로그함수를 적용하면 더 좋다.
- 로그 함수는 이 사이에서 음수가 되므로 최종 손실 값은 양수가 된다.
- 로그 함수는 0에 가까울 수록 아주 큰 음수가 되기 때문에 손실을 아주 크게 만들어 모델에 큰 영향을 미칠 수 있다.
- 양성(타깃 = 1)일 때 손실은 -log(예측 확률)
- 음성(타깃 = 0)일 때 손실은 -log(1-예측 확률)
- 이 손실함수를 로지스틱 손실 함수(Logistic Loss Function) 또는 이진 크로스엔트로피 손실 함수(Binary Cross-Entropy Loss Function)라고 부른다.
- 다중 분류에서도 비슷한 손실 함수를 사용한다.
- 크로스엔트로피 손실 함수(Cross-Entropy Loss Function)를 사용한다.
SGDClassifier
데이터 준비
- pandas를 라이브러리를 통해 데이터를 불러오고 표준화 전처리를 진행한다.
# 데이터 불러오기
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv')
# 특성, 타겟 데이터 분리
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)
모델 학습 및 평가
- 확룰적 경사 하강법을 제공하는 대표적인 분류용 클래스 SGDClassifier을 사용한다.
- sklearn.linear_model 패키지 아래에 있다.
- loss 매개변수 : 손실 함수의 종류
- max_iter 매개변수 : 에포크 횟수 지정
- log로 로지스틱 손실함수를 지정하고 에포크 횟수는 10로 지정하겠다.
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)
print(f'훈련세트 정확도: {sc.score(train_scaled, train_target)*100:.2f}%')
print(f'테스트 세트 정확도: {sc.score(test_scaled, test_target)*100:.2f}%')
- ConvergenceWarning은 모델이 충분히 수렴하지 않았다는 경고로 반복 횟수를 올려주게 되면 사라진다.
점진적 학습
- 확률적 경사하강법은 점진적 학습이 가능하다.
- 모델을 이어서 훈련할 때는 partial_fit() 메서드를 이용한다.
sc.partial_fit(train_scaled, train_target)
print(f'훈련세트 정확도: {sc.score(train_scaled, train_target)*100:.2f}%')
print(f'테스트 세트 정확도: {sc.score(test_scaled, test_target)*100:.2f}%')
- 아직 정확도가 낮지만 한 번더 실행하니 정확도가 올라갔다.
- 무작정 반복할 수 없으니 어떠한 기준이 필요할 것 같다.
에포크와 과대/과소 적합
- 확률적 경사 하강법을 이용한 모델은 에포크 횟수에 따라 과대 또는 과소 적합이 될 수 있다.
- 에포크 횟수가 적은 경우 : 모델이 훈련 세트를 덜 학습한다. - 과소적합 위험
- 에포크 횟수가 많은 경우 : 모델이 훈련 세트를 많이 학습한다. - 과대적합 위험
- 에포크가 진행됨에 따라 훈련 세트의 점수는 꾸준히 증가하지만 테스트 세트는 어느 시점에서 감소하기 시작한다.
- 이 지점이 모델이 과대적합되기 시작하는 곳이다.
- 괴대적합이 시작되기 전에 훈련을 멈추는 것을 조기 종료(Early Stopping)라고한다.
조기종료 지점 찾기
- fit()을 사용하지 않고 partial_fit() 만을 사용하려면 훈련 세트의 있는 전체 클래스의 레이블을 classes 매개변수에 전달해줘야 한다.
- 각 에포크마다 훈련 세트와 테스트 세트의 대한 점수를 기록하기 위해 2개의 리스트를 준비한다.
- 300번의 에포크를 진행하고 기록한 데이터 세트들을 시각화 해보겠다.
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):
# 전체 클래스의 레이블 classses 매개변수에 전달
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으로 맞추고 모델을 다시 훈련해본다.
- tol 매개변수는 매개변수에서 향상될 최소값을 지정한다.
- tol = None --> 자동으로 멈추지 않고 100번 에포크하도록함
sc = SGDClassifier(loss='log', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(f'훈련세트 정확도: {sc.score(train_scaled, train_target)*100:.2f}%')
print(f'테스트 세트 정확도: {sc.score(test_scaled, test_target)*100:.2f}%')
- 훈련 세트와 테스트 세트에서의 정확도도 비교적 높게 나왔다.
SGDClassifier의 loss 매개변수
- loss 매개변수의 기본값은 'hinge'이다.
- hinge는 힌지 손실(hinge loss)로 서포트 벡터 머신(Support Vector Machine)이라 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수 이다.
- 힌지 손실을 사용한 SGDClassifier 모델 훈련
sc = SGDClassifier(loss='hinge', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print("힌지 손실 함수를 사용한 SGDClassifier 모델의 정확도\n")
print(f'훈련세트 정확도: {sc.score(train_scaled, train_target)*100:.2f}%')
print(f'테스트 세트 정확도: {sc.score(test_scaled, test_target)*100:.2f}%')
728x90
반응형
'AI > 기계학습(Machine Learning)' 카테고리의 다른 글
[기계학습/ML]11. 검증 세트 - 교차 검증, 그리드 서치 (0) | 2022.10.24 |
---|---|
[기계학습/ML]10. 트리알고리즘 - 결정트리 (0) | 2022.10.23 |
[기계학습/ML]8. 회귀 알고리즘(3) - 로지스틱 회귀 (0) | 2022.10.23 |
[기계학습/ML]7. 회귀 알고리즘(2) - 다중 회귀, 릿지(Ridge), 라쏘(Lasso) (0) | 2022.10.23 |
[기계학습/ML]6. 회귀 알고리즘(1) - K-최근접 이웃 회귀, 선형회귀 (0) | 2022.10.23 |