본문 바로가기
Python/머신러닝+딥러닝 Ⅰ

확률적경사하강법

by Mr.DonyStark 2024. 3. 22.

□ 확률적경사하강법
새로운 데이터가 추가될 때마다 새로운 모델을 생성/학습해야함
기존의 모델과 모델 세팅등을 최대한 유지하면서 업데이트하는 최적화 방법. 알고리즘 모델은 아님. 즉, 훈련방법 또는 최적화 방법임
 ○ 확률적경사하강법 : 훈련세트를 한번 모두 사용하는 과정
 ○ 미니배치 경사하강법 : 여러개씩 꺼내기
 ○ 배치경사 하강법 : 몽땅꺼내기
□ 에포크 : 훈련세트를 한번 모두 사용하는 과정
손실함수는 0에 가까울수록 아주 큰음수가 되기 때문에 손실을 아주크게만들어 모델에 큰 영향을 끼침

□ 예제

 ○ 데이터 호출

import pandas as pd

fish = pd.read_csv("https://bit.ly/fish_data")
fish.head()

 

 

 ○ 인풋, 타겟데이터 분리

#데이터전처리
fish_input = fish[["Weight","Length1","Length2","Length3","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)


print(f"트레이닝 데이터 전처리 전\n{train_input[:2]}")
print(f"트레이닝 데이터 전처리 후\n{train_scaled[:2]}")
print(f"테스트 데이터 전처리 전\n{test_input[:2]}")
print(f"테스트 데이터 전처리 후\n{test_scaled[:2]}")

 

 ○ 분류 모델 : SDGClassifier. 확률적 경사하강법을 제공하는 대표적인 분료용 모델.

#확률적경사하강법 : 분류
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))

 

※ 손실 최소화를 위해 로지스틱손실함수 사용, 에포크는 10번을 지정했음에도 과소적합이 발생함.

※ 이에 따라 점진적 학습을 위한 partial_fit() 메서드를 사용하여 기존 훈련된 모델에 이어 학습을 재시도함

 

○ 재학습 : partial_fit()

#모델 이어서 훈련 : partial_fit()
sc.partial_fit(train_scaled,train_target)
print(sc.score(train_scaled,train_target))
print(sc.score(test_scaled,test_target))

1에포크를 실행하니 정확도가 향상되었음

 

※ 에포크가 진행될 수록 훈련세트 점수는 꾸준히 증가하지만 테스트세트 점수는 어느 순간 감소하는 성향을 가짐

과대적합이 시작하기전에 훈련을 멈추는 것을 조기종료라고함. 

 그렇다면 최적의 에포크회수는 어떻게 구할까?

import numpy as np

sc = SGDClassifier(loss="log_loss",random_state=42)
train_score = list()
test_score = list()
classes = np.unique(train_target)

#에포크 300번 진행
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번째 이후 훈련세트와 테스트 세트의 점수가 조금씩 벌어진 것을 확인 할 수 있음. (파랑:트레이닝, 주황:테스트)

 

○ 위에서 확인한 최적의 에포크를 바탕으로 재학습 및 정확도 점수 확인

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))

※ 사실 loss 매개변수의 기본값은 hinge 임.

hinge손실은 서포트 벡터머신이라고 부름.

결론 확률적 경사 하강법은 손실 함수라는 산을 정의하고 가장 가파른 경사를 따라 조금씩 내려오는 알고리즘임. 충분히 반복하여 훈련하면 훈련 세트에서 높은 점수를 얻는 모델을 만들 수 있음. 하지만 훈련을 반복할 수 록 모델이 훈련 세트에 점점 더 잘맞게되어 어느순간 과대적합되고 테스트 세트의 정확도 또한 줄어들것을 유의하며 진행해야함.

'Python > 머신러닝+딥러닝 Ⅰ' 카테고리의 다른 글

교차검증  (1) 2024.03.22
Decision Tree(결정트리 알고리즘)  (0) 2024.03.22
Logistic_KNN  (0) 2024.03.22
규제(L1, L2)와 Ridge, Lasso  (0) 2024.03.15
Multiple Regression(다중회귀)  (0) 2024.03.15