한번에 모든 데이터를 모델에 학습시키지 않고 조금씩 추가되는 데이터를 모델에 학습시키려면?
-> 매번 새 모델을 학습시키기에는 데이터의 양이 많이 늘어나버리면 문제가 됨.
이때 활용할 수 있는 점진적 학습 알고리즘이 확률적 경사 하강법이다.
확률적 경사 하강법은 원하는 목표에 도달하기 위해 훈련 세트 중 하나를 랜덤하게 골라 활용하고 모든 세트를 이용하였을 때 한 과정을 epoch라고 한다. 이때 훈련 세트를 고르는 방법에 따라 확률적 경사 하강법(1개) / 미니배치 '' (여러개) / 배치 ''(전부) 로 나눌 수 있다.
-> 이런 확률적 경사 하강법을 이용하는 대표적인 경우는 신경망 학습.. 방대한 양의 데이터를 한번에 학습시키기가 어렵기 때문.
'' 손실함수 ''
손실 함수 : 머신러닝 알고리즘의 정확도를 판단하는 기준. 손실함수의 값이 작을수록 좋으며 어떤 값이 손실함수의 최솟값인지는 알지 못한다. 확률적 경사 하강법은 손실 함수를 기준으로 모델을 학습시킨다.
이때 정확도를 테스트 데이터가 맞고 틀림을 기준으로 판별해버리면 확률적 경사 하강법을 통해 조금씩 이상적인 모델에 가까워지기 힘들다.(손실함수에서 받는 값이 양자화되어있으면?) 따라서 손실함수는 미분가능하여야 함.
'' 로지스틱 손실함수 ''

예측 확률을 범위는 로지스틱 회귀 모델의 시그모이드 함수에 따라 0~1사이 값을 가진다. 이때 각 확률에 대한 양성 클래스와 음성 클래스를 기반으로 손실함수를 계산한다.
양성 클래스일 때 손실은 -log(예측 확률)로 계산 / -> 확률이 1에서 멀어질수록 손실은 아주 큰 양수가 됨.
음성 클래스일때 손실은 -log(1-예측 확률)로 계산 / -> 마찬가지로 확률이 0에서 멀어질 수록 손실은 아주 큰 양수가 된다.
이런 방식으로 만들어진 손실 함수를 로지스틱 손실 함수라고 하며 이진 엔트로피 손실 함수라고도 한다.
식으로 나타내면 아래와 같다.

손실 함수에 대해 알아보았지만 실제로 손실함수를 제작할 일은 거의 없다. 하지만 손실 함수의 역할과 동작 원리를 이해하는 것은 매우 중요하다.
'' SGDClassifier ''
SGDClassifier(Stochastic Gradient Descent)는 sklearn에서 제공하는 확률적 경사 하강법 기반의 분류 모델이며 여러 종류의 모델을 학습시킬 수있다.
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
print(fish)

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) #loss는 손실 함수 지정 / max_iter는 epoch 수
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled,train_target))
print(sc.score(test_scaled,test_target))
#경고는 모델이 덜 훈련되었을 수있다는 경고 -> max_iter를 늘려 학습시키면 해결된다.
# 점진적 학습이 가능함
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)
print(classes)
#['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
''' gpt..
partial_fit 메서드와 classes 매개변수
partial_fit 메서드는 부분적인 학습을 수행할 때 사용됩니다. 이는 전체 데이터셋을 한 번에 학습하는 대신,
데이터를 미니 배치(mini-batch) 또는 스트리밍 방식으로 점진적으로 학습할 수 있게 합니다.
partial_fit 메서드는 특히 매우 큰 데이터셋을 다룰 때 유용합니다.
classes 매개변수는 partial_fit 메서드가 처음 호출될 때 모든 클래스 레이블의 목록을 제공하여,
모델이 전체 클래스 집합을 알 수 있도록 합니다.
이는 모델이 나중에 다른 배치를 학습할 때 새로운 클래스가 나타나는 것을 방지하고,
각 클래스에 대해 올바르게 학습할 수 있게 합니다.
'''
for _ in range(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

sc = SGDClassifier(loss = 'hinge', max_iter=100, random_state=42)
sc.fit(train_scaled,train_target)
print(sc.score(train_scaled,train_target))
print(sc.score(test_scaled, test_target))
'''
++ 힌지 손실은 서포트 벡터 머신이라고 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수
''''ML' 카테고리의 다른 글
| ML3 / 다중회귀, 특성공학 (0) | 2024.07.28 |
|---|---|
| 2-1 (0) | 2024.01.29 |
| ML 1-3 (2) | 2024.01.28 |