분류 알고리즘 선택
- 모든 경우에 뛰어난 성능을 낼 수 있는 분류 모델은 없다. 실제로 최소한 몇 개의 학습 알고리즘 성능을 비교하고 해당 문제에 최선인 모델을 선택하는 것이 항상 권장된다.
- 머신 러닝 알고리즘을 훈련하기 위한 다섯 가지 주요 단계는 다음과 같다.
- 특성을 선택하고 훈련 샘플을 모은다.
- 성능 지표를 선택한다.
- 분류 모델과 최적화 알고리즘을 선택한다.
- 모델의 성능을 평가한다.
- 알고리즘을 튜닝한다.
사이킷런 첫걸음: 퍼셉트론 훈련
- 2장에서 했던 것을 쉬운 인터페이스로 분류 알고리즘을 최적화하여 구현한 사이킷런 API를 사용해 보겠다.
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
print('클래스 레이블:', np.unique(y))
--
클래스 레이블: [0 1 2]
- np.unique(y) 함수는 iris.target에 저장된 세 개의 고유한 클래스 레이블을 반환한다.
- 결과는 0 1 2가 나오는데 이는 붓꽃 클래스 이름인 Iris-setosa, Iris-versicolor, Iris-virginica의 정수 형태
- 사이킷런의 많은 함수와 클래스 메서드는 문자열 형태의 클래스 레이블을 다룰 수 있지만, 정수 레이블을 권장한다.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)
print('y의 레이블 카운트:', np.bincount(y))
print('y_train의 레이블 카운트:', np.bincount(y_train))
print('y_test의 레이블 카운트:', np.bincount(y_test))
---
y의 레이블 카운트: [50 50 50]
y_train의 레이블 카운트: [35 35 35]
y_test의 레이블 카운트: [15 15 15]
- 훈련된 모델 성능을 평가하기 위해 데이터셋을 훈련 세트와 테스트 세트로 분할 한다. 사이킷런 model_selection 모듈의 train_test_split 함수를 이용하면 X와 y 배열을 나눌 수 있다.
- 30%는 테스트 데이터, 70%는 훈련 데이터가 된다.
- 데이터를 분할 하기 전에 데이터셋을 섞는 것이 좋으므로 유사 난수 생성기에 random_state 매개변수로 고정된 랜덤시드(random_state=1)을 전달한다.
- 마지막으로 stratify=y를 통해 계층화(stratification) 기능을 사용하는데, 여기서 계층화는 train_test_split 함수가 훈련 세트와 테스트 세트의 클래스 레이블 비율을 입력 데이터셋과 동일하게 만든다는 의미이다.
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
- 앞장의 경사 하강법 예제에서 보았던 것처럼 머신러닝 알고리즘과 최적화 알고리즘은 성능을 위해 특성 스케일 조정이 필요하다. 여기서는 사이킷런의 preprocessing 모듈의 StandardScaler 클래스를 사용해서 특성을 표준화 했다.
- 위 코드에서 StandardScaler의 fit 메서드는 훈련 세트의 각 특성 차원마다 $\mu$(샘플 평균)와 $\sigma$(표준 편차)를 계산한다.
- transform 메서드를 실행하면 계산된 $\mu$와 $\sigma$를 사용하여 훈련세트를 표준화 한다.
- 훈련 세트와 테스트 샘플이 서로 같은 비율로 이동되도록 동일한 $\mu$와 $\sigma$를 사용하여 테스트 세트를 표준화 한다.
from sklearn.linear_model import Perceptron
ppn = Perceptron(max_iter=40, eta0=0.1, tol=1e-3, random_state=1)
ppn.fit(X_train_std, y_train)
y_pred = ppn.predict(X_test_std)
print('잘못 분류된 샘플 개수: %d' % (y_test != y_pred).sum())
---
잘못 분류된 샘플 개수: 14
- 훈련 데이터를 표준화한 후 퍼셉트론 모델을 훈련한다. 사이킷런의 알고리즘은 대부분 기본적으로 OvR(One-versus-Rest) 방식을 사용하여 다중 분류(multiclass classification)를 지원한다.
- 사이킷런의 인터페이스는 2장에서 구현한 퍼셉트론과 미슷하다. linear_model 모듈에서 Perceptron 클래스를 로드하여 새로운 객체를 생성한 후 fit 메서드를 사용하여 모델을 훈련한다.
- eta0은 학슙릴이고, max_iter는 훈련 세트를 반복할 에포크 횟수를 말한다.
- 2장에서 했던 것처럼 적절한 학습률을 찾으려면 어느 정도 실험이 필요하다.
- 학습률이 너무 크면 알고리즘은 전역 최솟값을 지나치고, 너무 작으면 학습 속도가 느리기 때문에 대규모 데이터셋에서 수렴하기까지 많은 에포크가 필요하다.
- 사이킷런 라이브러리는 metrics 모듈 아래에 다양한 성능 지표를 구현해 놓았는데, 예는 아래와 같다.
from sklearn.metrics import accuracy_score
print('정확도: %.2f' % accuracy_score(y_test, y_pred))
print('정확도: %.2f' % ppn.score(X_test_std, y_test))
---
정확도: 0.69
정확도: 0.69