사전 일반화
개념

일반화

gabury1고친 사람 github-actions[bot]

일반화는 모델이 학습 때 본 적 없는 데이터에서도 맞는 답을 내는 능력입니다. 머신러닝으로 모델을 만드는 목적이 이것입니다. 학습에 쓴 데이터만 맞히는 모델은 서비스에서 쓸 데가 없습니다.

객체지향 설계에서는 여러 클래스의 공통점을 위로 묶는 일을 같은 이름으로 부릅니다.

쉽고 빠른 이해

일반화는 처음 보는 데이터에서도 잘 맞히는 성질입니다. 지난달 메일로 학습한 스팸 필터가 오늘 들어온 스팸도 가려낸다면 일반화가 된 것입니다.

이 성질을 따로 챙기는 까닭은 학습 점수로는 안 보이기 때문입니다. 모델은 학습에 쓴 메일을 외워서도 높은 점수를 냅니다. 외운 모델은 새 메일 앞에서 틀립니다.

어떻게 확인하나:

  1. 모은 데이터 일부를 학습에 쓰지 않고 떼어 둡니다
  2. 나머지로 모델을 학습시킵니다
  3. 떼어 둔 데이터로 점수를 잽니다. 이 점수로 일반화를 가늠합니다

대가 — 떼어 둔 만큼 학습에 쓸 데이터가 줄어듭니다. 새 데이터의 성격이 학습 데이터와 달라지면 이렇게 잰 점수도 빗나갑니다.

상세

이 절은 운전 연수 이야기로 일반화의 감을 먼저 잡습니다. 그다음은 스팸 필터 하나를 예로 삼아 일반화의 뜻과 전제, 재는 법을 봅니다.

끝으로 일반화를 망치는 것과 돕는 것을 가릅니다. 객체지향 설계에서 쓰는 같은 이름의 뜻도 짚습니다.

연습한 길과 처음 가는 길

같은 동네에서 운전 연수를 받은 두 사람이 있습니다. 한 사람은 그 동네 골목 모양만 외워서 처음 가는 도시에서는 차를 못 뺍니다. 다른 한 사람은 신호와 차선을 읽는 법을 익혀서 처음 가는 길도 달립니다.

앞사람은 연습한 길을 외운 것입니다. 뒷사람은 어느 길에나 통하는 규칙을 익힌 것입니다. 머신러닝에서는 뒷사람 같은 모델을 두고 일반화가 됐다고 말합니다. 앞사람 같은 모델은 데이터를 외웠을 뿐입니다.

모델과 훈련 데이터

머신러닝에서 모델은 입력을 받아 답을 내는 함수입니다. 메일 제목과 본문을 넣으면 「스팸」이나 「정상」을 내는 식입니다. 이 함수 안에는 학습으로 정해지는 숫자가 여럿 들어 있습니다. 이 숫자를 파라미터라고 합니다.

훈련은 정답을 아는 예제를 써서 파라미터를 고치는 일입니다. 학습이라고도 부릅니다. 모델의 답과 정답의 차이가 줄어드는 쪽으로 숫자를 조금씩 옮깁니다. 이때 쓰는 예제 묶음이 훈련 데이터입니다.

모델의 답이 정답에서 벗어난 정도를 오차라고 합니다. 스팸 필터라면 잘못 가른 메일의 비율이 오차입니다. 점수를 맞힌 비율로 잰다면 오차는 1에서 그 점수를 뺀 값입니다. 그래서 오차는 작을수록 좋습니다.

훈련 데이터에서 잰 오차가 훈련 오차입니다. 훈련은 이 훈련 오차를 줄이는 쪽으로 나아갑니다.

일반화의 뜻

모델을 만드는 목적은 훈련 데이터를 맞히는 것이 아닙니다. 훈련 데이터의 정답은 이미 알고 있습니다. 모델이 할 일은 앞으로 들어올, 정답을 모르는 메일을 맞히는 것입니다.

처음 보는 데이터에서도 오차가 작은 성질을 일반화라고 합니다. 학습한 예제 너머로 통하는 규칙을 배웠다는 뜻입니다. 신호와 차선을 읽는 법을 익힌 운전자와 같습니다. 지난달 메일로 학습한 필터가 오늘 온 스팸도 가려낸다면 일반화가 된 모델입니다.

일반화의 반대편에는 외우기가 있습니다. 훈련 데이터의 제목과 정답을 표 하나에 담아 두는 모델을 떠올려 봅니다. 이 모델은 훈련 데이터에서 오차가 0입니다. 그러나 골목 모양만 외운 운전자처럼, 낱말 하나만 바뀐 제목에는 답을 못 냅니다.

같은 곳에서 온 데이터

일반화에는 전제가 하나 있습니다. 새 데이터가 훈련 데이터와 같은 곳에서 온다는 것입니다. 지난달 메일과 이번 달 메일이 비슷한 사람들에게서 비슷한 비율로 온다는 뜻입니다.

이 「같은 곳」을 통계에서는 분포라는 말로 다룹니다. 분포는 데이터가 어떤 값을 얼마나 자주 갖는지를 나타냅니다. 스팸이 전체 메일의 몇 할인지, 「무료」라는 낱말이 스팸에 얼마나 자주 나오는지가 분포에 담깁니다.

이 전제를 다듬은 이름이 독립 동일 분포 가정입니다. 줄여서 IID(independent and identically distributed)라고 씁니다. 이 가정은 두 가지를 담습니다. 모든 예제가 같은 분포에서 뽑혔다는 것과 예제끼리 서로 영향을 주지 않는다는 것입니다.

앞의 조건은 위에서 본 「같은 곳」입니다. 뒤의 조건은 예제 하나를 안다고 다른 예제를 짐작할 수 있어서는 안 된다는 뜻입니다. 같은 사람이 보낸 거의 똑같은 메일 수백 통이 훈련 데이터에 몰려 있다면 이 조건이 깨집니다.

전제가 깨지면 일반화도 무너집니다. 영어 스팸만 보고 배운 필터에 한국어 스팸이 쏟아지는 경우가 그렇습니다. 학습 뒤에 데이터의 분포가 바뀌는 문제를 분포 이동이라고 합니다. 이때는 흔히 새 데이터로 모델을 다시 학습시킵니다.

일반화를 재는 법

새 데이터는 아직 오지 않았으니 일반화를 바로 잴 수는 없습니다. 그래서 가진 데이터 일부를 미리 떼어 두고 새 데이터처럼 다룹니다. 학습에 한 번도 쓰지 않고 마지막 채점에만 쓰는 이 데이터가 테스트 세트입니다.

flowchart TD
    A["모은 데이터"] --> B["훈련 데이터"]
    A --> C["테스트 세트"]
    B --> D["학습"]
    D --> E["모델"]
    E --> F["테스트 오차"]
    C --> F

그림은 모은 데이터가 두 갈래로 나뉘는 모습입니다. 훈련 데이터는 학습에만 들어갑니다. 테스트 세트는 학습이 끝난 모델을 채점하는 데만 씁니다. 테스트 세트에서 잰 오차를 테스트 오차라고 부릅니다.

모델이 새 데이터에서 낼 오차를 일반화 오차라고 합니다. 테스트 오차는 이 일반화 오차를 어림한 값입니다. 어림이 맞으려면 테스트 세트도 새 데이터와 같은 분포에서 와야 합니다.

훈련 오차와 테스트 오차의 차이도 함께 봅니다. 이 차이가 일반화 격차입니다. 스팸 필터의 훈련 오차가 0.01, 테스트 오차가 0.19 라면 격차는 0.18 입니다.

격차가 크면 모델이 훈련 데이터에서만 통하는 것을 배웠다는 신호입니다. 격차가 작아도 두 오차가 모두 크면 쓸 만한 모델이 아닙니다. 그 모델은 훈련 데이터조차 못 맞힙니다.

테스트 세트를 아끼는 까닭

테스트 세트는 한 번만 쓰는 것이 원칙입니다. 모델을 만들 때는 대개 파라미터 수나 학습 횟수를 바꾼 후보를 여럿 만듭니다. 이 후보들을 테스트 점수로 고르기를 되풀이하면 모델이 테스트 세트에 맞춰집니다. 그러면 테스트 오차가 일반화 오차보다 작게 나옵니다.

그래서 후보 가운데 하나를 고르는 데는 따로 떼어 둔 검증 세트를 씁니다. 검증 세트에서 잰 오차가 검증 오차입니다. 테스트 세트는 고르기가 다 끝난 뒤 마지막에 한 번 씁니다.

데이터가 적어 세 몫으로 나누기 아까울 때는 교차 검증을 씁니다. 데이터를 여러 조각으로 나누고 조각을 돌아가며 한 번씩 채점용으로 씁니다. 그렇게 얻은 점수들을 평균 내어 일반화를 가늠합니다.

일반화를 망치는 두 방향

모델이 일반화를 못 하는 모양은 둘입니다. 둘을 가르는 것은 모델이 얼마나 복잡한가입니다. 모델이 복잡하다는 것은 파라미터가 많아서 맞출 수 있는 모양이 많다는 뜻입니다.

하나는 모델이 너무 복잡해서 훈련 데이터에 우연히 끼어든 잡음(노이즈)까지 외우는 것입니다. 이것이 과적합입니다. 훈련 오차는 작습니다. 그런데 테스트 오차가 큽니다.

잡음은 규칙과 상관없이 우연히 끼어든 값입니다. 지난달 스팸 몇 통이 마침 새벽 세 시에 왔다고 해 봅니다. 과적합한 필터는 「새벽 세 시에 온 메일은 스팸」을 규칙으로 배웁니다. 그래서 그 시각에 온 정상 메일까지 스팸으로 가릅니다.

과적합은 학습을 오래 끌 때도 생깁니다. 학습을 계속하면 훈련 오차는 줄기만 합니다. 검증 오차는 한동안 같이 줄다가 어느 때부터 다시 커집니다. 그때부터 모델이 잡음을 외우기 시작한 것입니다.

다른 하나는 모델이 너무 단순해서 데이터 속 규칙조차 못 담는 것입니다. 이것이 과소적합입니다. 훈련 오차와 테스트 오차가 함께 큽니다.

일반화가 잘 된 모델은 둘 사이에 있습니다. 모델을 복잡하게 할수록 과소적합에서는 멀어집니다. 대신 과적합에 가까워집니다. 이 트레이드오프를 따지는 틀이 편향과 분산입니다.

일반화를 돕는 방법

일반화를 높이는 방법은 대개 모델이 우연한 잡음을 외우기 어렵게 만듭니다. 아래 표는 흔히 쓰는 방법과 그 방법이 바꾸는 것을 적습니다.

방법 무엇을 바꾸나
데이터를 더 모은다 예제가 많아져 잡음을 외우기보다 공통 규칙을 배우는 쪽이 오차를 더 줄인다
데이터 증강 가진 예제를 조금씩 바꿔 예제 수를 늘린다
모델을 단순하게 한다 파라미터 수를 줄여 잡음을 따라갈 여유를 뺀다
규제 파라미터 값이 클수록 커지는 벌점을 오차에 더해, 훈련이 둘을 함께 줄이게 한다. 값이 작은 모델은 입력이 조금 바뀌어도 답이 크게 흔들리지 않는다
조기 종료 검증 오차가 줄다가 다시 커지기 시작하면 학습을 멈춘다

어느 방법이든 세기는 검증 세트의 점수를 보며 정합니다. 너무 세게 누르면 과소적합으로 넘어갑니다.

점수가 일반화를 부풀리는 경우

테스트 오차가 작다고 늘 일반화가 된 것은 아닙니다. 테스트 세트의 정보가 학습 쪽으로 새어 들어가면 점수가 부풀려집니다. 같은 메일이 훈련 데이터와 테스트 세트에 둘 다 들어간 경우가 흔한 예입니다. 이 문제를 데이터 누수라고 합니다.

누수가 있으면 외운 모델도 테스트 세트에서 점수가 높게 나옵니다. 이미 본 문제가 시험에 나왔기 때문입니다. 서비스에 내놓은 뒤에야 점수가 떨어진 것을 알게 됩니다.

객체지향 설계의 일반화

같은 낱말이 객체지향 설계에서는 다른 뜻으로 쓰입니다. 여러 클래스에 겹치는 속성과 동작을 뽑아 상위 클래스 하나로 묶는 일입니다. 반대로 상위 클래스에서 갈라져 나와 세부를 더하는 방향은 특수화라고 부릅니다.

결제 시스템을 예로 듭니다. 카드 결제와 계좌 이체는 둘 다 금액과 결제 시각을 갖습니다. 둘 다 승인과 취소도 합니다. 이 공통점을 「결제」라는 상위 클래스로 올리는 것이 일반화입니다.

UML(Unified Modeling Language, 통합 모델링 언어) 클래스 다이어그램은 이 관계를 화살표로 그립니다. 화살표는 하위 클래스에서 상위 클래스로 향합니다. 화살표 끝은 속이 빈 삼각형입니다. 코드에서는 대개 상속으로 옮겨집니다.

두 뜻 모두 낱낱의 사례에서 공통점을 뽑아 더 넓게 쓴다는 점은 같습니다. 머신러닝은 뽑아낸 규칙을 처음 보는 데이터에 씁니다. 객체지향 설계는 뽑아낸 공통점을 클래스 구조로 남깁니다.

관련 항목

일반화를 재는 데이터 나눔

훈련 데이터 · 검증 세트 · 테스트 세트 · 교차 검증 · 홀드아웃 검증 · 학습 곡선

일반화를 깨뜨리는 실패

과적합 · 과소적합 · 데이터 누수 · 분포 이동 · 표본 편향 · 잡음

일반화를 높이는 기법

규제 (머신러닝) · 가중치 감쇠 · 드롭아웃 · 조기 종료 · 데이터 증강 · 앙상블

일반화를 설명하는 이론

편향과 분산 · 모델 용량 · 일반화 오차 · 독립 동일 분포 · 확률 분포 · VC 차원 · PAC 학습 · 오컴의 면도날

일반화가 일어나는 학습 과정의 구성 요소

머신러닝 · 모델 · 훈련 · 파라미터 · 하이퍼파라미터 · 손실 함수 · 경사 하강법

일반화를 가늠하는 평가 지표

정확도 · 오차율 · 정밀도와 재현율 · F1 점수 · 혼동 행렬

객체지향 설계에서 일반화와 짝을 이루는 개념

특수화 · 상속 · UML · 클래스 다이어그램 · 추상 클래스 · 인터페이스

다른 이름: generalization · 일반화 성능 · 일반화 능력