머신러닝

[혼자 공부하는 머신러닝+딥러닝] - 다양한 분류 알고리즘

주니빙 2023. 11. 4. 19:33

확률적 경사 하강법

앞서 훈련한 모델을 버리지 않고 새로운 데이터에 대해서만 조금씩 더 훈련하는 방식을 점진적 학습 또는 온라인 학습이라고 부른다.

대표적인 점진적 학습 알고리즘이 확률적 경사 하강법이다.

 

확률적 경사 하강법 (1개씩 꺼내기)

가장 가파른 경사를 따라 원하는 지점에 도달하는 것이 목표이다. 가장 가파른 길을 찾아 내려오지만 조금씩 내려오는 것 또한 중요하다.

훈련 세트에서 랜덤하게 하나의 샘플을 골라 가장 가파른 길을 찾아내므로 확률적이라는 말이 붙는다.

 

확률적 경사 하강법에서 훈련 세트를 한 번 모두 사용하는 과정을 에포크라고 부른다.

 

에포크

에포크는 전체 훈련 데이터 세트를 한 번 학습하는 것을 의미한다. 에포크는 모델이 전체 데이터 세트에 대해 한 번씩 훈련되는 주기를 나타낸다. 에포크가 증가할수록 모델은 더 많은 학습을 진행하게 되며, 이를 통해 모델의 성능이 향상될 수 있다.

 

미니배치 경사 하강법 (여러 개씩 꺼내기)

미니배치 경사 하강법은 확률적 경사 하강법과 배치 경사 하강법의 중간 방식으로, 훈련 데이터를 작은 미니배치로 나누어 모델을 업데이트하는 방법이다. 이 방법은 전체 훈련 데이터를 모두 사용하는 경사 하강법보다 계산 속도가 빠르고, 확률적 경사 하강법보다 안정적인 업데이트를 제공한다.

 

배치 경사 하강법 (몽땅 꺼내기)

배치 경사 하강법은 훈련 데이터 세트의 모든 샘플을 사용하여 모델을 업데이트하는 방식이다. 즉, 모든 샘플의 오차를 계산하고 평균 오차를 이용하여 모델을 업데이트한다. 이 방법은 모든 데이터에 대한 그레이디언트를 계산하기 때문에 안정적인 업데이트를 제공하지만 계산 비용이 매우 높을 수 있다.

 

손실 함수

손실 함수는 모델의 예측 값과 실제 값 사이의 차이를 측정하여 모델의 오차를 계산하는 함수이다. 손실 함수는 모델을 학습시킬 때 사용되며, 오차를 최소화하는 방향으로 모델을 조정한다.

손실 함수의 값이 작을수록 좋다.

 

로지스틱 손실 함수

로지스틱 손실 함수는 분류 모델에서 사용되는 손실 함수로, 주로 이진 분류에 사용된다. 로지스틱 손실 함수는 실제 값과 예측 값 사이의 차이를 측정하여 모델의 오차를 계산한다. 이 함수는 오차를 최소화하는 방향으로 모델을 학습시키는데 사용된다.

 

분류에서 손실은 정답을 못 맞히는 것이다.

예를 들어 도미는 양성 클래스(1), 빙어는 음성 클래스(0)으로 가정한다.

정답(타킷)이 차례로 1,1,0,0인 샘플 4개의 예측 확률이 차례로 0.9,0.3,0.2,0.8이라고 가정한다. 첫 번째 샘플부터 하나씩 손실 함수를 만든다.

첫 번째 샘플의 예측은 0.9이므로 양성 클래스 타깃인 1과 곱한 다음에 음수로 바꾼다. 이 경우 예측이 1에 가까울수록 좋은 모델이다.

세 번째 샘플의 타깃은 음성 클래스라 0이므로 이 값을 예측 확률인 0.2와 그대로 곱하지 않고 타깃을 마치 양성 클래스처럼 1로 만들어 주고 대신 예측값도 양성 클래스에 대한 예측으로 바꾼다. 즉 1-0.2=0.8로 사용하고 1과 곱한 다음에 음수로 바꾼다.

4가지 샘플을 모두 계산해주면 2,4번재 샘플의 손실이 -0.3과 -0.2로 높다. 여기에서 예측 확률에 로그 함수를 적용해주면 최종 손실 값은 양수가 된다.

SGDClassifier

SGDClassifier는 확률적 경사 하강법을 사용하여 선형 분류 모델을 학습하는 알고리즘이다. 이 알고리즘은 큰 데이터셋에 효과적이며, 빠른 학습 속도를 제공한다. SGDClassifier는 다양한 손실 함수를 지원하며, 로지스틱 손실 함수를 사용하여 이진 분류 모델을 구축하는 데 주로 사용된다.

 

fish_csv_data 파일에서 판다스 데이터프레임을 만든다.

import pandas as pd
fish = pd.read_csv('<https://bit.ly/fish_csv_data>')

 

Species 열을 제외한 나머지 5개는 입력 데이터로 사용한다. Species 열은 타킷 데이터이다.

ish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
fish_target = fish['Species'].to_numpy()

 

사이킷런의 train_test_split() 함수를 사용해 이 데이터를 훈련 세트와 테스트 세트로 나눈다.

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)

 

StandardSclaer() 함수란?

StandardScaler() 함수는 사이킷런에서 제공하는 특성 스케일링을 위한 함수이다. 이 함수를 사용하면 특성 데이터를 평균이 0이고 표준편차가 1인 범위로 변환할 수 있다.

 

훈련 세트와 테스트 세트의 특성을 표준화 전처리한다.

특성값의 스케일을 맞춘 train_scaled와 test_scaled 두 넘파이 배열을 준비해준다.

from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)

여기까지는 이전에 학습해준 것과 동일하다.

 

사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스가 SGDClassifier이다.

from sklearn.linear_model import SGDClassifier

 

SGDClassifier의 객체를 만들 때 2개의 매개변수를 지정한다.

loss는 손실 함수의 종류를 지정한다. 여기에서는 loss=’log_loss’로 지정하여 로지스틱 손실 함수를 지정했다.

max_iter는 수행할 에포크 횟수를 지정한다. 10으로 지정하여 전체 훈련 세트를 10회 반복한다.

그 다음 훈련 세트와 테스트 세트에서 정확도 점수를 출력한다.

출력된 훈련 세트와 테스트 세트의 정확도는 0.77~로 정확도가 낮다. 이는 지정한 반복 횟수 10번이 부족한 것으로 보인다.

 

확률적 경사 하강법은 점진적 학습이 가능하므로 SGDClassifier 객체를 다시 만들지 않고 훈련한 모델 sc를 추가로 더 훈련 가능하다. printial_fit() 메서드를 활용하여 훈련한다.

호출할 때마다 1 에포크씩 이어서 훈련할 수 있다. 에포크를 한 번 더 실행하니 정확도가 향상된 것을 볼 수 있다.

에포크와 과대/과소적합

확률적 경사 하강법을 사용한 모델은 에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있다.

적은 에포크 횟수 동안에 훈련한 모델은 훈련 세트와 테스트 세트에 잘 맞지 않는 과소적합된 모델이 될 것이고, 반대로 많은 에포크 횟수 동안에 훈련한 모델은 훈련 세트에 너무 잘 맞아 테스트 세트에는 오히려 점수가 나쁜 과대적합된 모델일 것이다.

 

조기 종료란?

조기 종료(early stopping)란 모델의 훈련을 조기에 중단하여 과대적합을 방지하는 기법이다. 일반적으로 훈련 세트와 검증 세트의 손실 함수 값이 계속해서 개선되다가 어느 순간부터 검증 세트의 손실 함수 값이 증가하기 시작하면, 이는 모델이 과대적합에 가까워졌다는 신호이다. 조기 종료는 이러한 신호를 감지하여, 검증 세트의 손실 함수 값이 증가하는 시점에서 훈련을 중단시키는 것이다.

import numpy as np

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

데이터를 불러와준 후, 300번의 에포크 동안 훈련을 반복하여 진행하였다.

반복마다 훈련 세트와 테스트 세트의 점수를 계산하여 각각의 리스트에 추가한다.

 

300번의 에포크 동안 기록한 훈련 세트와 테스트 세트의 점수를 그래프로 그려본다.

파랑색 그래프는 훈련 세트 그래프, 주황색 그래프는 테스트 세트 그래프이다.

위의 그래프를 보면 백 번째 에포크 이후에는 훈련세트와 테스트 세트의 점수가 조금씩 벌어지고 있다. 또한 에포크 초기에는 과소적합되어 훈련 세트와 테스트 세트의 점수가 낮다. 따라서 이 모델은 백 번재 에포크가 적절한 반복 횟수임을 알 수 있다.

 

max_iter=100이라고 작성해줌으로써 반복 횟수를 100에 맞추어준다.

련 세트와 테스트 세트에서의 정확도 점수가 모두 높아진 것을 볼 수 있다.

 

추가로 SGDClassifier의 loss 매개변수의 기본값은 ‘hinge’이다. 힌지 손실은 서포트 벡터 머신이라 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수이다. SGDClassifier는 여러 종류의 손실 함수를 loss 매개변수에 지정하여 다양한 머신러닝 알고리즘을 지원한다.