사전 데이터 누수
문제

데이터 누수

gabury1고친 사람 github-actions[bot]

데이터 누수는 모델의 평가 점수를 부풀리는 고장입니다. 예측하는 순간에는 알 수 없는 정보가 학습과 평가에 섞여 들어가서 생깁니다. 모델은 그 정보에 기대어 평가에서 답을 쉽게 맞힙니다. 서비스에 내놓으면 그 정보가 없으니 점수가 떨어집니다.

쉽고 빠른 이해

데이터 누수는 모델의 평가 점수를 부풀리는 고장입니다. 고객이 서비스를 해지할지 맞히는 모델에 「해지 사유」 칸이 섞여 있으면, 모델은 평가에서 거의 다 맞힙니다. 해지 사유는 해지한 고객에게만 적혀 있기 때문입니다.

이 고장에 이름이 붙은 까닭은 점수만 봐서는 안 보이기 때문입니다. 평가 점수는 높게 나옵니다. 서비스에 내놓은 뒤에야 떨어진 것이 보입니다.

어떻게 도나:

  1. 예측할 때는 없는 정보가 모델이 배우는 데이터(훈련 세트)에 섞입니다
  2. 모델이 그 정보로 답을 맞히는 법을 배웁니다
  3. 점수를 재려고 떼어 둔 데이터(테스트 세트)에도 같은 정보가 있어서 점수가 높게 나옵니다
  4. 서비스에서는 그 정보가 없어서 점수가 떨어집니다

무엇이 나빠지나 — 쓸모없는 모델을 쓸 만하다고 믿고 내보냅니다. 막으려면 데이터를 먼저 나눠야 합니다. 모든 계산은 훈련 세트로만 합니다. 그만큼 준비 과정이 번거로워집니다.

상세

이 절은 데이터 누수가 무엇인지부터 세웁니다. 이어서 정보가 새는 길 다섯을 작은 예로 하나씩 보입니다. 끝으로 누수를 알아채는 신호와 막는 원칙을 적습니다. 이웃한 문제와도 가릅니다.

미리 새어 나간 시험지

기말고사 문제지가 시험 전날 한 반에 돌았습니다. 그 반의 평균 점수가 크게 올랐습니다. 점수가 오른 만큼 실력이 오른 것은 아닙니다. 다음 시험에서 그 반은 원래 실력만큼 점수를 받습니다.

데이터 누수는 모델에게 이 시험지가 새는 일입니다. 부풀려진 기말고사 점수가 모델의 평가 점수입니다. 다음 시험은 서비스입니다.

모델을 시험하는 방법

머신러닝에서 모델은 입력을 받아 답을 내는 함수입니다. 고객 기록을 넣으면 「해지한다」나 「안 한다」를 내는 식입니다. 모델은 답을 아는 예제를 많이 보면서 이 함수를 맞춰 갑니다. 이 과정을 학습이라고 부릅니다.

학습에 쓰는 예제 묶음을 훈련 세트라고 합니다. 모델을 만드는 목적은 훈련 세트를 맞히는 것이 아닙니다. 앞으로 들어올 새 입력을 맞히는 것입니다.

그래서 모델이 한 번도 보지 않은 예제를 따로 떼어 두고 거기서 점수를 잽니다. 이 예제 묶음이 테스트 세트입니다. 테스트 세트의 점수는 「서비스에 내놓으면 이 정도 맞힐 것이다」라는 예상으로 쓰입니다.

이 예상이 맞으려면 조건이 하나 있습니다. 테스트 세트가 모델에게 새 입력과 똑같이 낯설어야 합니다. 모델이 테스트 세트에 대해 무언가를 미리 알고 있으면 점수는 예상이 되지 못합니다.

새어 들어간 정보

데이터 누수는 모델이 서비스에서는 얻을 수 없는 정보를 학습이나 평가 과정에서 얻는 일입니다. 예측하는 순간에는 아직 생기지 않은 정보도, 테스트 세트에만 있어야 할 정보도 여기에 듭니다.

어느 쪽이든 결과는 같습니다. 모델은 그 정보에 기대어 테스트 세트를 쉽게 맞힙니다. 테스트 점수는 서비스에서 낼 점수보다 높게 나옵니다.

이 고장이 까다로운 것은 오류 메시지가 없다는 점입니다. 코드는 멀쩡히 돌고 점수는 높습니다. 서비스에 내놓은 뒤 점수가 떨어지고 나서야 드러납니다.

정답을 품은 특성

첫 번째 길은 입력 안에 정답의 흔적이 들어 있는 경우입니다. 모델에 넣는 입력의 칸 하나하나를 특성이라고 합니다. 고객 기록이라면 가입 기간, 월 요금, 문의 횟수가 특성입니다.

모델이 맞혀야 하는 답은 레이블이라고 합니다. 해지 예측에서는 「해지했나」가 레이블입니다. 학습은 특성을 보고 레이블을 맞히는 법을 배우는 일입니다.

고객 테이블에 「해지 사유」 칸이 있다고 합시다. 이 칸은 해지한 고객에게만 값이 있습니다. 이 칸을 특성으로 넣으면 모델은 「해지 사유가 비어 있지 않으면 해지」라는 규칙 하나로 테스트 세트를 거의 다 맞힙니다.

서비스에서는 아직 해지하지 않은 고객을 두고 예측합니다. 그 고객의 해지 사유는 언제나 비어 있습니다. 모델이 배운 규칙은 여기서 아무것도 못 맞힙니다. 이처럼 레이블이 정해진 뒤에야 채워지는 특성이 새는 경우를 타깃 누수라고 부릅니다.

나누기 전에 계산한 값

두 번째 길은 데이터를 다듬는 계산에서 생깁니다. 모델에 넣기 전에 값을 다듬는 일을 전처리라고 합니다. 특성마다 평균을 빼고 표준편차로 나눠 크기를 맞추는 표준화가 흔한 전처리입니다.

문제는 이 평균을 어느 데이터로 구하느냐입니다. 아래 코드는 값 다섯 개 중 앞의 넷을 훈련 세트로, 마지막 하나를 테스트 세트로 둡니다. 그리고 평균을 두 방법으로 구합니다.

Python
data = [10, 20, 30, 40, 1000]
train, test = data[:4], data[4:]

sum(data) / len(data)    # 220.0
sum(train) / len(train)  # 25.0

전체로 구한 평균은 테스트 세트의 1000 에 끌려 올라갔습니다. 테스트 세트에만 있어야 할 값이 훈련 세트를 다듬는 기준에 들어간 것입니다. 모델은 테스트 세트를 보기 전에 그 값의 흔적을 먼저 본 셈입니다.

평균 하나로 새는 정보는 대개 작습니다. 평균에는 테스트 세트의 답인 레이블이 들어 있지 않기 때문입니다. 그래서 이 경우 점수가 부푸는 폭도 작은 편입니다.

새는 정보가 커지는 것은 특성 선택을 나누기 전에 할 때입니다. 특성 선택은 여러 특성 가운데 레이블과 관계가 깊은 것만 골라내는 일입니다. 전체 데이터로 고르면 테스트 세트의 레이블까지 보고 고르게 됩니다. 그렇게 뽑힌 특성은 테스트 세트의 답과 잘 맞으니 테스트 점수가 부풉니다.

지키는 원칙은 하나입니다. 데이터를 먼저 나눕니다. 다듬는 데 쓰는 값은 훈련 세트로만 구합니다. 그렇게 구한 값으로 두 세트를 똑같이 다듬습니다. 아래 그림이 두 순서를 나란히 보입니다.

flowchart TD
    subgraph S1["새는 순서"]
        A1["전체 데이터"] --> A2["전체로 평균 계산"]
        A2 --> A3["다듬은 뒤 나누기"]
        A3 --> A4["학습과 평가"]
    end
    subgraph S2["새지 않는 순서"]
        B1["전체 데이터"] --> B2["먼저 나누기"]
        B2 --> B3["훈련 세트로만 평균 계산"]
        B3 --> B4["그 평균으로 두 세트 다듬기"]
        B4 --> B5["학습과 평가"]
    end
    S1 ~~~ S2

미래가 섞인 시계열

세 번째 길은 시간 순서를 무시하고 나눌 때 생깁니다. 날마다 쌓이는 주문 수처럼 시간 순서로 늘어선 데이터를 시계열이라고 합니다. 이런 데이터로 「다음 주 주문 수」를 맞히는 모델을 만든다고 합시다.

데이터를 무작위로 섞어 나누면 훈련 세트에 다음 달 기록이 들어갑니다. 테스트 세트에는 지난달 기록이 들어갑니다. 모델은 미래를 보고 과거를 맞히는 셈이 됩니다.

서비스에서는 언제나 과거만 보고 미래를 맞힙니다. 그래서 시계열은 한 시점을 정해 그 앞을 훈련 세트로, 뒤를 테스트 세트로 자릅니다.

양쪽에 걸친 같은 대상

네 번째 길은 같은 대상의 기록이 두 세트에 나뉘어 들어갈 때 생깁니다. 가장 단순한 경우는 똑같은 행이 두 번 들어 있는 중복입니다. 무작위로 나누면 하나는 훈련 세트로, 하나는 테스트 세트로 갑니다.

똑같지는 않아도 같은 대상에서 나온 기록도 마찬가지입니다. 한 고객이 남긴 주문 기록 열 건이 두 세트에 섞였다고 합시다. 모델은 그 고객의 버릇을 외워서 테스트 세트의 나머지 주문을 맞힙니다. 처음 보는 고객 앞에서는 그 버릇이 통하지 않습니다.

이럴 때는 행 단위가 아니라 대상 단위로 나눕니다. 한 고객의 기록은 전부 훈련 세트에 가거나 전부 테스트 세트에 갑니다.

테스트 세트로 고른 모델

다섯 번째 길은 학습이 끝난 뒤에 생깁니다. 모델을 여러 개 만들어 두고 테스트 세트 점수가 가장 높은 것을 고르는 경우입니다. 고르는 순간 테스트 세트의 정보가 선택에 쓰였습니다.

여러 후보 중 하나는 우연히 테스트 세트와 잘 맞기 쉽습니다. 그 후보를 고르면 그 우연까지 점수에 들어갑니다. 고른 모델의 테스트 점수는 새 데이터에서의 점수보다 높게 나오기 쉽습니다.

그래서 모델을 고를 때는 검증 세트를 따로 씁니다. 검증 세트는 학습에는 안 쓰고 후보를 견주는 데만 쓰는 데이터입니다. 테스트 세트는 고르기가 다 끝난 뒤 한 번만 씁니다.

누수가 생기는 조건

다섯 길을 모으면 누수는 아래 둘이 겹칠 때 납니다.

  1. 모델이 학습하거나 뽑히는 동안, 서비스에서 예측하는 순간에는 얻을 수 없는 정보를 봅니다
  2. 그 정보가 테스트 세트의 답을 맞히는 데 도움이 됩니다

아래 표는 앞의 다섯 길을 두 조건에 맞춰 봅니다.

새는 길 모델이 미리 본 정보 그 정보가 테스트 세트에서 통하는 까닭
정답을 품은 특성 해지 사유 칸 테스트 세트의 해지 고객에게도 해지 사유가 적혀 있다
나누기 전에 계산한 값 전체 데이터로 고른 특성 테스트 세트의 답과 잘 맞는 특성이 뽑혔다
미래가 섞인 시계열 테스트 기간보다 뒤의 기록 뒤의 기록이 앞 기간의 흐름을 알려 준다
양쪽에 걸친 같은 대상 같은 고객의 다른 기록 테스트 세트에 그 고객이 다시 나온다
테스트 세트로 고른 모델 후보마다의 테스트 점수 그 점수가 높은 후보를 골랐다

둘 중 하나만 빼도 점수는 부풀지 않습니다. 1번이 없으면 모델이 기댈 정보가 없습니다. 2번이 없으면 모델이 기댄 정보가 테스트 세트에서 답을 맞히는 데 도움이 안 됩니다. 그러면 테스트 점수는 서비스에서 낼 점수와 비슷하게 나옵니다.

부풀려진 정밀도와 재현율

해지 예측처럼 「한다」와 「안 한다」 가운데 하나를 고르는 모델은 흔히 두 비율로 점수를 잽니다. 첫째가 정밀도입니다. 모델이 「해지한다」고 고른 고객 가운데 진짜 해지한 고객의 비율입니다.

둘째가 재현율입니다. 진짜 해지한 고객 가운데 모델이 찾아낸 고객의 비율입니다. 두 비율 모두 높을수록 모델이 잘 맞힌 것입니다. 하나도 안 틀리면 두 비율이 모두 만점이 됩니다.

누수가 있으면 두 비율이 함께 만점에 가깝게 나옵니다. 해지 사유 칸처럼 정답의 흔적을 보고 고르기 때문입니다. 서비스에서는 흔적이 없으니 두 비율이 함께 떨어집니다.

알아채는 신호

누수는 오류로 드러나지 않으니 점수의 모양으로 의심합니다. 첫째 신호는 그 문제에서 기대하기 어려운 만큼 높은 점수입니다. 사람이 해도 자주 틀리는 문제를 모델이 거의 다 맞히면 먼저 누수를 의심합니다.

둘째 신호는 특성 하나가 예측을 거의 혼자 떠맡는 경우입니다. 모델이 어느 특성에 얼마나 기대는지를 잰 값을 특성 중요도라고 합니다. 한 특성의 중요도가 다른 특성들보다 크게 앞서면, 그 특성이 레이블이 정해진 뒤에 채워지는 값인지 확인합니다.

셋째 신호는 서비스에 내놓은 뒤 점수가 테스트 점수보다 크게 낮은 경우입니다. 이 차이는 데이터 분포가 시간이 지나며 바뀌는 분포 이동 때문일 수도 있습니다. 내놓자마자 떨어졌다면 누수 쪽을 먼저 봅니다.

막는 원칙

막는 방법은 앞의 두 조건 가운데 1번을 끊는 쪽입니다. 특성마다 「예측하는 순간에 이 값이 있나」를 묻습니다. 없으면 뺍니다.

전처리와 특성 선택은 나눈 뒤에 훈련 세트로만 합니다. 여기에는 대가가 따릅니다. 다듬는 데 쓴 평균 같은 값을 따로 저장해 두었다가 테스트 세트와 서비스 입력에 똑같이 써야 합니다. 준비 과정이 한 덩어리 계산에서 「구하기」와 「적용하기」 두 단계로 갈립니다.

훈련 세트를 여러 조각으로 나눠 한 조각씩 돌아가며 검증을 맡기는 방법을 교차 검증이라고 합니다. 검증을 맡은 조각은 그 차례의 테스트 세트 노릇을 합니다. 그래서 평균 같은 값은 그 조각을 뺀 나머지로 구합니다. 차례가 바뀔 때마다 새로 구합니다.

과적합과 다른 점

과적합은 모델이 훈련 세트의 우연한 흔들림까지 외워서 새 데이터에서 틀리는 문제입니다. 과적합이 있으면 훈련 점수는 높고 테스트 점수는 낮게 나옵니다. 테스트 세트가 제 일을 해서 문제를 드러낸 것입니다.

데이터 누수는 그 테스트 세트가 고장 난 문제입니다. 누수가 있으면 테스트 점수까지 높게 나옵니다. 그래서 과적합도 가려집니다. 과적합을 재려면 누수부터 막아야 합니다.

보안의 데이터 유출과 다른 점

보안에서 말하는 데이터 유출은 비밀 정보가 허락 없이 밖으로 나가는 사고입니다. 머신러닝의 데이터 누수는 모델 평가 안에서 일어나는 일이라 서로 다른 말입니다.

관련 항목

데이터 누수를 드러내거나 가리는 데이터 나눔

훈련 데이터 · 검증 세트 · 테스트 세트 · 교차 검증 · 홀드아웃 검증 · 시계열 교차 검증 · 그룹 분할 · 층화 추출

데이터 누수의 하위 종류

타깃 누수 · 훈련-테스트 오염 · 전처리 누수 · 시간 누수 · 중복 데이터

데이터 누수가 끼어드는 준비 단계

전처리 · 표준화 · 정규화 · 결측값 · 특성 선택 · 특성 공학 · 특성 · 레이블

데이터 누수가 부풀리는 평가 지표

정밀도 · 재현율 · 정확도 · F1 점수 · 혼동 행렬 · ROC 곡선

데이터 누수와 함께 평가를 어긋나게 하는 문제

과적합 · 과소적합 · 표본 편향 · 분포 이동 · 클래스 불균형 · 일반화

데이터 누수를 다루는 머신러닝 작업 흐름

머신러닝 · 지도학습 · 시계열 · 하이퍼파라미터 · 특성 중요도 · 모델 서빙

다른 이름: data leakage · 데이터 리키지 · 정보 누수