들어가며
이진 분류기는 예, 아니요 두개의 클래스만 가지고 분류하는 분류기이다
반면 다중 분류기는 두개 이상의 클래스를 구별할 수 있는 분류기를 의미한다
여러 개의 클래스를 직접 구별할 수 있는 알고리즘도 많지만
일부 알고리즘은 이진 분류만 가능하다
이러한 알고리즘에서 다중 분류를 사용하기 위해서는
이진 분류기를 여러 개 사용해 다중 클래스를 분류하는 방법을 쓴다
다중 분류(multiclass classifier)
이진 분류만 가능한 알고리즘에서 다중 분류를 구현하기 위해서는
이진 분류기를 여러 개 사용해야 한다
이진 분류기를 여러 개 사용하는 방법에도 여러 전략이 있다
OvR (or OvA) 전략
이 전략은 예를 들어 특정 숫자 하나만 구분하는 숫자별 이진 분류기를 0~9까지 10개를 훈련시켜
클래스가 10개인 숫자 분류 시스템을 만들 수 있는 방법이다
1을 찾는다고 했을 때
0 분류기에서는 0이다 0이 아니다 두개로 나뉘어 negative로 판단되어 점수가 낮게나오고
1 분류기라면 1이다 1이 아니다 두개로 나뉘어 positive로 판단되어 높은 점수가 나오게 된다
2~9도 마찬가지로 점수가 낮게 나올 것이다
입력 하나 받았을 때 10개의 분류기를 돌려 각 분류기에서 나온 점수 중 가장 높은 것을 채택하는 방식이다
이를 OvR(One Versus the Rest) 또는 OvA(One versus all) 전략이라고 한다
OvO 전략
또 다른 전략으로는 0과 1 구별, 1과 2 구별, 0과 2 구별처럼 각 숫자의 조합마다 이진 분류기를 훈련시키는 것이 있다
이를 OvO(One versus One) 전략이라고 한다
3을 찾는다고 했을 때
0 vs 1 / 0 vs 2 / ... / 0 vs 9 혹은 1 vs 1 / 1 vs 2 등과 같이 3과 관련이 없는 분류기에서는
투표가 이루어지지 않고
3 vs 0 / 3 vs 1 / ... / 3 vs 9 에서 투표가 이루어지고
3이 최다 득표가 되어 3으로 예측되는 구조이다
숫자를 구분하는 분류기에서는 0~9에서 2개의 쌍을 만들어서 훈련해야 하므로
총 45개의 분류기를 훈련시켜야 한다
예측 시에도 45개의 분류기를 통과하여 가장 많이 양성으로 분류된 클래스를 선택한다
OvO의 장점은 각 분류기의 훈련에 대해 전체 훈련 세트 중 구별할 두 클래스에 해당하는 샘플만 있으면 되므로
데이터 크기에 민감한 알고리즘에서 효율적이다
사이킷런에서 분류 알고리즘을 선택하면 자동으로 OvR 또는 OvO로 선택되어 실행된다
from sklearn.svm import SVC
svm_clf = SVC(random_state=42)
svm_clf.fit(X_train[:2000], y_train[:2000])
서포트 벡터 머신같은 일부 알고리즘은 훈련 세트 크기에 민감하므로
작은 훈련 세트에서 많은 분류기를 훈련시키는 OvO가 선택된다
svm_clf.predict([some_digit])
-> array(['5'], dtype=object)
숫자 5의 이미지가 주어졌을 때 5로 잘 예측한 것을 볼 수 있다
some_digit_scores = svm_clf.decision_function([some_digit])
some_digit_scores.round(2)
-> array([[ 3.79, 0.73, 6.06, 8.3 , -0.29, 9.3 , 1.75, 2.77, 7.21,
4.82]])
decision_function() 메서드를 통해 각 분류기에서 어떤 점수가 나왔는지 확인해볼 수 있다
이 메서드의 기본값은 "ovr"이라서 10개가 나온 것이니 혼동하지 않아야한다
만약 "ovo"로 바꾼다면 45개의 원소가 출력될 것이다
가장 높은 점수는 9.3이고 이는 클래스 5에 해당한다
MNIST 데이터셋의 경우 각 클래스의 인덱스가 클래스 값 자체와 같으므로 5의 인덱스에는 클래스 5이다
from sklearn.multiclass import OneVsRestClassifier
ovr_clf = OneVsRestClassifier(SVC(random_state=42))
ovr_clf.fit(X_train[:2000], y_train[:2000])
만약 OvO나 OvR 전략을 사용하도록 강제하고 싶다면
OneVsOneClassifier / OneVsRestClassifier를 사용하면 된다
ovr_clf.predict([some_digit])
-> array(['5'], dtype='<U1')
마찬가지로 5로 잘 예측된 것을 볼 수 있다
마치며
이번 글에서는 다중 클래스를 분류하는 전략들에 대해 알아보았다
다중 클래스를 이중 클래스를 여러 개 사용해서 분류한다는 발상 자체가 신기했고
OvO 전략이나 OvR 전략을 상황에 맞게 잘 판단해서 써야될 것 같다는 생각이 들었다
어떤 상황에서 OvO 일 때는 틀리지만 OvR일 때는 맞을 수 있고 그 반대일 수도 있다
다음 글에서는 오차행렬에서 파생될 수 있는 다른 개념들에 대해 추가로 알아볼 것이다
'AI > Machine Learning' 카테고리의 다른 글
| [AI] 경사하강법(Gradient Descent) (1) | 2026.03.14 |
|---|---|
| [AI] 오차 행렬을 통한 오류 분석 (1) | 2026.03.02 |
| [AI] ROC곡선 (0) | 2026.03.01 |
| [AI] 정밀도/재현율 트레이드오프 (1) | 2026.02.28 |
| [AI] 오차 행렬(Confusion Matrix)과 정밀도(Precision), 재현율(Recall) (1) | 2026.02.28 |
