---
title: "데이터셋 구성의 모든 것 — 수집·분할·전처리·라벨링·품질관리 완전 가이드"
id: "1644"
type: "post"
slug: "ai-dataset-preparation-train-validation-test-labeling2"
published_at: "2026-07-18T13:06:05+00:00"
modified_at: "2026-07-19T10:40:17+00:00"
url: "https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling2/"
markdown_url: "https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling2.md"
excerpt: "좋은 AI 모델은 좋은 데이터셋에서 시작됩니다. 이 글은 문제 정의와 데이터 수집부터 훈련·검증·테스트 분할, 데이터 누수와 중복 방지, 전처리, 라벨링, 클래스 불균형, 증강, 골든 세트, 문서화와 버전 관리까지 데이터셋 구축 전 과정을 실전 중심으로 정리합니다."
taxonomy_category:
  - "AI"
  - "AI 101"
taxonomy_post_tag:
  - "AI 101"
  - "AI 데이터셋"
  - "MLOps"
  - "데이터 누수"
  - "데이터 라벨링"
  - "데이터 전처리"
  - "데이터 증강"
  - "데이터 품질관리"
  - "데이터셋 구성"
  - "데이터셋 구축"
  - "데이터셋 분할"
  - "학습 데이터"
---

모델 구조를 바꾸면 성능이 조금 좋아질 수 있습니다. 하지만 **데이터셋의 정의, 수집 범위, 분할 방식, 라벨 품질이 잘못되면 어떤 모델을 사용해도 결과를 신뢰하기 어렵습니다.**

데이터셋 구성은 단순히 파일을 많이 모아 `train`, `validation`, `test` 폴더로 나누는 작업이 아닙니다. 실제로는 다음 질문에 답하는 설계 과정입니다.

- 모델이 실제로 예측해야 하는 대상은 무엇인가?
- 운영 환경에서 어떤 데이터가 들어오는가?
- 같은 사람·장비·문서·장면이 여러 세트에 섞이지 않았는가?
- 라벨은 일관되고 재현 가능한가?
- 테스트 세트가 실제 배포 환경과 실패 위험을 대표하는가?
- 어떤 원본과 코드로 이 데이터셋을 만들었는지 다시 추적할 수 있는가?

Google의 머신러닝 교육 자료도 머신러닝 프로젝트에서 데이터셋 구축과 변환에 매우 많은 시간이 사용된다고 설명합니다. 중요한 점은 단순히 데이터 작업 시간이 길다는 사실이 아니라, **데이터 준비 단계가 모델의 성능 상한과 평가의 신뢰도를 동시에 결정한다는 것**입니다.

이 글에서는 정형 데이터, 이미지, 텍스트, 음성, 시계열, LLM·RAG 데이터까지 공통으로 적용할 수 있는 데이터셋 설계 원칙을 실전 중심으로 정리합니다.

## 핵심 요약

좋은 데이터셋은 다음 조건을 만족해야 합니다.

1. **목표 적합성**: 실제 서비스에서 해결하려는 문제와 데이터의 입력·라벨이 일치해야 합니다.
2. **대표성**: 운영 환경의 사용자, 장비, 지역, 시간, 조건, 예외 사례를 포함해야 합니다.
3. **독립적인 분할**: 동일 개체나 유사 샘플이 훈련 세트와 테스트 세트에 동시에 들어가면 안 됩니다.
4. **누수 방지**: 결측치 대체, 정규화, 특성 선택, 증강 등은 분할 후 훈련 데이터만으로 학습해야 합니다.
5. **라벨 신뢰성**: 명확한 가이드라인, 다중 검수, 합의 절차, 불확실성 처리가 필요합니다.
6. **평가 가능성**: 전체 평균뿐 아니라 클래스·사용자군·환경·난이도별 성능을 측정할 수 있어야 합니다.
7. **재현 가능성**: 원본 출처, 라이선스, 변환 코드, 데이터 버전, 분할 목록을 기록해야 합니다.

데이터셋 비율이나 최소 샘플 수에는 모든 프로젝트에 통하는 정답이 없습니다. `70/15/15`, `80/10/10`은 시작점일 뿐이며, 실제 결정은 **데이터의 독립 단위, 희귀 클래스 수, 목표 지표의 불확실성, 배포 환경의 다양성**을 기준으로 내려야 합니다.

## 목차

1. 데이터셋 설계는 문제 정의부터 시작한다
2. 데이터 수집 방법과 출처
3. 데이터는 몇 개가 필요할까?
4. Training·Validation·Test 세트의 역할
5. 랜덤 분할보다 중요한 분할 전략
6. 데이터 누수와 중복을 막는 방법
7. 데이터 정제와 전처리
8. 데이터 유형별 전처리 핵심
9. 데이터 라벨링과 품질 검증
10. 클래스 불균형·대표성·편향 관리
11. 데이터 증강과 합성 데이터
12. 평가 데이터셋과 골든 세트
13. 데이터 문서화·버전 관리·계보 추적
14. 실전 디렉터리와 메타데이터 구조
15. 엔드투엔드 데이터셋 구축 절차
16. 최종 체크리스트
17. FAQ

## 1. 데이터셋 설계는 문제 정의부터 시작한다

### 1-1. 먼저 예측 단위를 정의한다

데이터를 모으기 전에 **한 개의 샘플이 무엇인지**부터 명확히 해야 합니다.

| 프로젝트 | 예측 단위 예시 | 입력 | 라벨 |
| --- | --- | --- | --- |
| 고객 이탈 예측 | 고객 1명 | 최근 90일 이용 기록 | 30일 이내 이탈 여부 |
| 제품 불량 탐지 | 제품 이미지 1장 또는 제품 1개 | 촬영 이미지 | 정상·불량 유형 |
| 배터리 수명 예측 | 배터리 또는 운전 구간 | 전압·전류·온도 시계열 | 잔여 수명 |
| 문서 분류 | 문서 1건 | 본문·메타데이터 | 문서 유형 |
| 음성 인식 | 발화 구간 | 오디오 | 전사 문장 |
| RAG 평가 | 질문 1건 | 질문·검색 문서·답변 | 정답·근거·평가 기준 |

예측 단위가 불명확하면 같은 사용자의 여러 기록이 서로 다른 세트에 섞이거나, 한 사건에서 잘라낸 여러 프레임이 훈련과 테스트에 동시에 들어가는 문제가 생깁니다.

### 1-2. 입력 시점과 예측 시점을 구분한다

특히 시계열과 비즈니스 데이터에서는 **예측 시점에 실제로 알 수 있는 정보만 입력 특성으로 사용**해야 합니다.

예를 들어 고객이 다음 달에 이탈할지 예측하면서 다음 달에 생성된 해지 사유를 입력에 포함하면, 모델은 미래 정보를 미리 본 셈입니다. 이를 시간 누수 또는 미래 정보 누수라고 합니다.

데이터 사전에는 각 열마다 다음 정보를 기록하는 것이 좋습니다.

| 항목 | 기록 예시 |
| --- | --- |
| 열 이름 | avg_usage_30d |
| 의미 | 예측 기준일 이전 30일 평균 사용량 |
| 생성 시점 | 매일 00시 배치 집계 |
| 사용 가능 시점 | 예측 당일 01시 이후 |
| 단위 | 분 |
| 결측 의미 | 사용 기록 없음 또는 수집 실패 |
| 허용 범위 | 0 이상 |
| 개인정보 여부 | 비식별 통계값 |

### 1-3. 목표 모집단과 운영 환경을 정의한다

데이터셋은 세상 전체를 표현할 필요가 없습니다. 대신 **모델이 사용될 환경을 충분히 대표해야 합니다.**

다음 범위를 문서로 먼저 정합니다.

- 대상 사용자 또는 대상 장비
- 서비스 지역과 언어
- 촬영 장비·센서·해상도·샘플링 주기
- 주간·야간, 계절, 날씨, 조명 등 환경 조건
- 정상 사례와 실패 사례
- 모델이 처리하지 않을 범위
- 잘못 예측했을 때의 비용

NIST AI 위험관리 프레임워크도 데이터의 대표성, 적합성, 품질과 실제 사용 맥락을 함께 검토할 것을 강조합니다. 데이터가 많더라도 목표 환경을 대표하지 않으면 모델은 실전에서 실패할 수 있습니다.

### 1-4. 라벨 체계부터 설계한다

데이터 수집을 시작한 뒤 라벨을 고민하면 수집 조건이 뒤틀립니다. 먼저 다음을 정의해야 합니다.

- 클래스 목록과 클래스별 정의
- 포함 조건과 제외 조건
- 클래스 간 우선순위
- 다중 라벨 허용 여부
- 애매한 사례 처리 방식
- `기타`, `판단 불가`, `라벨 보류` 클래스 필요 여부
- 라벨 근거와 전문가 자격

예를 들어 불량 탐지에서 `스크래치`, `균열`, `오염`을 정의했더라도 한 제품에 세 결함이 동시에 존재할 수 있습니다. 이때 단일 클래스 분류인지, 다중 라벨 분류인지, 객체 탐지인지에 따라 데이터 구조와 모델이 완전히 달라집니다.

## 2. 데이터 수집 방법과 출처

### 2-1. 공개 데이터셋

빠르게 기준 모델을 만들거나 벤치마크를 비교할 때 유용합니다.

대표적인 검색 경로는 다음과 같습니다.

- Kaggle Datasets
- Hugging Face Datasets
- Google Dataset Search
- AI Hub
- 공공데이터포털
- UCI Machine Learning Repository
- 분야별 연구기관·학회 공개 데이터

공개 데이터셋을 사용할 때는 파일만 내려받지 말고 다음 내용을 확인해야 합니다.

- 사용 라이선스와 상업적 이용 가능 여부
- 원본 데이터 출처
- 수집 시기와 지역
- 라벨 생성 방식
- 알려진 오류와 제한사항
- 훈련·검증·테스트 분할 기준
- 중복 또는 벤치마크 오염 가능성
- 개인정보·민감정보 포함 여부

공개 데이터셋의 라벨이 존재한다고 해서 곧바로 자신의 문제에 맞는 정답은 아닙니다. 클래스 정의와 운영 환경이 다르면 라벨 매핑 또는 재라벨링이 필요합니다.

### 2-2. 내부 데이터베이스와 서비스 로그

실제 운영 환경과 가장 가까운 데이터를 확보할 수 있다는 장점이 있습니다. 그러나 로그는 분석이나 학습을 위해 설계되지 않은 경우가 많습니다.

점검할 항목은 다음과 같습니다.

- 로그 누락과 중복 전송
- 앱·서버 버전별 스키마 차이
- 이벤트 이름 변경 이력
- 시간대와 타임스탬프 기준
- 재시도 요청으로 생긴 중복
- 봇·테스트 계정·내부 사용자
- 개인정보와 접근 권한
- 라벨 생성 지연

내부 로그를 사용할 때는 **온라인 서비스가 보는 특성과 오프라인 학습 데이터가 보는 특성이 같은지** 확인해야 합니다. 오프라인에서만 계산 가능한 특성을 학습에 사용하면 배포 시 특성 불일치가 발생합니다.

### 2-3. API 수집

공식 API는 웹페이지 구조 변화에 덜 취약하고 메타데이터가 비교적 명확합니다.

반드시 함께 저장할 항목은 다음과 같습니다.

- API 이름과 버전
- 요청 URL 또는 엔드포인트 식별자
- 요청 시각과 시간대
- 요청 파라미터
- 응답 코드
- 페이지 번호 또는 커서
- 원본 응답 파일
- 수집 코드 버전

API 사용량, 반환 필드, 가격 정책은 변경될 수 있으므로 글이나 코드에 고정된 제한값을 영구적인 사실처럼 기록하지 않는 것이 좋습니다.

### 2-4. 웹 수집

웹 스크래핑은 많은 데이터를 빠르게 모을 수 있지만, 기술적으로 접근 가능하다는 사실이 곧 자유로운 학습 이용을 의미하지는 않습니다.

확인해야 할 사항은 다음과 같습니다.

- 사이트 이용약관
- 저작권과 데이터베이스 권리
- robots.txt와 접근 정책
- 로그인·유료 콘텐츠 여부
- 개인정보와 초상권
- 요청 빈도와 서버 부하
- 원문 삭제·정정 요청 대응 방식

한국저작권위원회는 생성형 AI의 저작물 학습과 관련한 별도 안내서를 제공하고 있습니다. 저작물, 개인정보, 영업비밀이 섞일 수 있는 웹 데이터는 기술팀만의 판단으로 수집하지 말고 법무·보안 검토를 포함하는 것이 안전합니다.

### 2-5. 센서·카메라·IoT 수집

직접 수집 데이터는 목적에 맞게 설계할 수 있지만, 센서 자체의 편향과 수집 프로토콜을 관리해야 합니다.

기록해야 할 메타데이터 예시는 다음과 같습니다.

- 장비 ID와 모델명
- 펌웨어 버전
- 센서 보정 일자
- 설치 위치
- 샘플링 주기
- 단위
- 온도·습도·조명 등 환경 조건
- 수집 시작·종료 시각
- 통신 장애와 누락 구간
- 장비 교체 이력

같은 현상을 한 장비로만 수집하면 모델이 현상보다 장비의 노이즈 패턴을 학습할 수 있습니다. 가능하다면 장비·설치 위치·수집일을 다양화하고, 일부 장비나 현장을 통째로 테스트 세트에 남겨 두는 것이 좋습니다.

### 2-6. 크라우드소싱과 사용자 제공 데이터

다양한 데이터를 빠르게 확보할 수 있지만 참여자 구성 자체가 편향의 원인이 될 수 있습니다.

- 참여자의 지역·연령·기기 분포
- 중복 참여 방지
- 품질 검증용 정답 문항
- 비정상 작업 탐지
- 개인정보 수집 동의
- 보상 구조가 작업 품질에 미치는 영향
- 철회 요청과 삭제 절차

### 2-7. 수집 단계에서 반드시 남겨야 할 계보 정보

최소한 다음 필드는 남겨 두는 것이 좋습니다.

```
source_id
source_type
source_uri_or_system
collected_at
collector_version
license
consent_status
privacy_level
raw_checksum
processing_status
```

데이터 출처와 가공 이력을 추적할 수 있어야 잘못된 원본이 발견됐을 때 영향을 받은 샘플과 모델을 찾아낼 수 있습니다.

## 3. 데이터는 몇 개가 필요할까?

### 3-1. “최소 1만 개” 같은 보편적 기준은 없다

필요한 데이터 수는 다음 요인에 따라 달라집니다.

- 문제의 난이도
- 입력 차원과 다양성
- 클래스 수
- 희귀 클래스 비율
- 라벨 노이즈
- 사전학습 모델 사용 여부
- 허용 가능한 오류
- 목표 신뢰구간
- 운영 환경의 변동성

간단한 정형 분류 문제는 수천 건으로도 의미 있는 모델을 만들 수 있지만, 개방형 이미지·음성·언어 모델은 훨씬 많은 데이터가 필요할 수 있습니다. 반대로 데이터가 수백만 건이어도 거의 같은 장면이나 같은 사용자의 반복 기록이라면 실질적 다양성은 낮습니다.

### 3-2. 원시 데이터 수보다 독립 샘플 수가 중요하다

동일 영상에서 연속으로 추출한 10만 프레임은 서로 매우 비슷합니다. 이를 10만 개의 독립 샘플로 간주하면 데이터 규모를 과대평가하게 됩니다.

다음 단위를 따로 계산하세요.

- 전체 파일 수
- 고유 사용자 수
- 고유 장비 수
- 고유 세션 수
- 고유 촬영 장면 수
- 고유 문서 수
- 고유 사건 수
- 중복 제거 후 샘플 수

### 3-3. 희귀 클래스 기준으로 역산한다

전체 데이터보다 중요한 것은 각 평가 대상 그룹에 충분한 샘플이 있는지입니다.

예를 들어 실제 불량률이 1%이고 테스트 세트에서 불량 샘플 300개를 확보하려면, 단순 무작위 수집 기준으로 약 3만 개의 테스트 후보가 필요합니다. 지역·장비·불량 유형별로 따로 성능을 보고 싶다면 더 많은 데이터가 필요합니다.

따라서 다음 순서로 계산하는 것이 실용적입니다.

1. 반드시 평가할 클래스와 데이터 슬라이스를 정의한다.
2. 각 슬라이스에 필요한 최소 양성·음성 사례 수를 정한다.
3. 실제 발생률을 반영해 필요한 원시 데이터 수를 역산한다.
4. 중복·불명확·수집 실패율을 고려해 여유분을 추가한다.

### 3-4. 학습 곡선으로 추가 수집 가치를 판단한다

훈련 데이터의 10%, 20%, 40%, 60%, 80%, 100%를 사용해 성능을 비교하면 데이터 추가가 아직 효과적인지 알 수 있습니다.

```
import numpy as np
from sklearn.model_selection import learning_curve
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(random_state=42)

train_sizes, train_scores, val_scores = learning_curve(
    model,
    X,
    y,
    cv=5,
    train_sizes=np.linspace(0.1, 1.0, 6),
    scoring="f1_macro",
    n_jobs=-1,
)

print("훈련 크기:", train_sizes)
print("훈련 평균:", train_scores.mean(axis=1))
print("검증 평균:", val_scores.mean(axis=1))
```

검증 성능이 계속 상승한다면 데이터 추가가 도움이 될 가능성이 큽니다. 성능이 정체된다면 단순 수량보다 라벨 오류, 클래스 정의, 입력 특성, 모델 한계를 점검해야 합니다.

## 4. Training·Validation·Test 세트의 역할

### 4-1. Training Set

모델 파라미터를 학습하는 데이터입니다.

훈련 세트에만 적용해야 하는 작업은 다음과 같습니다.

- 모델 학습
- 결측치 대체 기준 학습
- 평균·표준편차·최솟값·최댓값 계산
- 어휘집과 토크나이저 학습
- 특성 선택
- 차원 축소
- 오버샘플링·언더샘플링
- 데이터 증강

### 4-2. Validation Set

모델 선택과 개발 판단에 사용합니다.

- 하이퍼파라미터 선택
- 임계값 결정
- Early Stopping
- 모델 구조 비교
- 전처리 방식 비교
- 오류 분석

검증 세트를 반복해서 확인하며 모델을 수정하면 검증 세트에도 점차 과적합됩니다. 반복 실험이 많다면 검증 세트를 여러 개로 나누거나 교차검증을 사용하고, 최종 테스트 세트는 별도로 보호해야 합니다.

### 4-3. Test Set

최종 모델의 일반화 성능을 추정하는 데이터입니다.

테스트 세트는 다음 조건을 만족해야 합니다.

- 모델과 전처리 기준 학습에 사용되지 않음
- 하이퍼파라미터 선택에 사용되지 않음
- 개발 중 반복적인 오류 분석에 사용되지 않음
- 실제 배포 환경 또는 평가 목적을 대표함
- 중복과 같은 개체의 교차 포함이 없음

“테스트는 딱 한 번만 봐야 한다”는 원칙은 테스트 파일을 기술적으로 한 번만 연다는 뜻이 아닙니다. **테스트 결과를 보고 모델 설계를 반복 수정하지 말라**는 뜻입니다. 제품 운영에서는 고정된 회귀 테스트 세트를 반복 사용할 수 있지만, 장기간 사용해 개발팀이 그 세트에 맞춰지면 새 블라인드 세트를 추가해야 합니다.

### 4-4. 분할 비율은 목적에 맞게 결정한다

자주 사용하는 시작점은 다음과 같습니다.

| 상황 | 시작 비율 예시 | 비고 |
| --- | --- | --- |
| 일반적인 중간 규모 데이터 | 70/15/15 | 무난한 출발점 |
| 데이터가 비교적 충분함 | 80/10/10 | 훈련 데이터 확대 |
| 데이터가 적음 | 교차검증 + 최종 홀드아웃 | 단순 3분할보다 안정적 |
| 시계열 | 과거/중간/최근 순서 분할 | 무작위 셔플 금지 |
| 사용자·환자·장비 반복 데이터 | 그룹 단위 분할 | 같은 그룹의 교차 포함 금지 |
| 지역·도메인 일반화 목표 | 도메인 홀드아웃 | 특정 지역·기관을 통째로 평가 |

비율보다 중요한 것은 **검증·테스트 세트에 목표 지표를 안정적으로 계산할 만큼 충분한 독립 샘플이 있는가**입니다.

## 5. 랜덤 분할보다 중요한 분할 전략

### 5-1. 단순 무작위 분할

각 행이 독립이고 시간·사용자·장비·그룹 상관이 거의 없을 때 사용할 수 있습니다.

```
from sklearn.model_selection import train_test_split

X_train, X_temp, y_train, y_temp = train_test_split(
    X,
    y,
    test_size=0.30,
    random_state=42,
    stratify=y,
)

X_val, X_test, y_val, y_test = train_test_split(
    X_temp,
    y_temp,
    test_size=0.50,
    random_state=42,
    stratify=y_temp,
)
```

`stratify=y`는 각 세트의 클래스 비율을 비슷하게 유지합니다. 그러나 같은 사용자의 여러 행이 있다면 계층 분할만으로는 누수를 막지 못합니다.

### 5-2. 그룹 분할

같은 사용자, 환자, 장비, 문서, 영상, 촬영 세션의 샘플이 여러 개 존재한다면 그룹 단위로 나눠야 합니다.

```
from sklearn.model_selection import GroupShuffleSplit

splitter = GroupShuffleSplit(
    n_splits=1,
    test_size=0.20,
    random_state=42,
)

train_idx, test_idx = next(
    splitter.split(df, df["target"], groups=df["user_id"])
)

train_df = df.iloc[train_idx].copy()
test_df = df.iloc[test_idx].copy()

assert set(train_df["user_id"]).isdisjoint(set(test_df["user_id"]))
```

그룹 분할이 필요한 대표 사례는 다음과 같습니다.

- 한 환자의 여러 검사 이미지
- 한 사용자의 여러 거래
- 한 장비의 여러 센서 구간
- 한 영상에서 추출한 여러 프레임
- 한 원문에서 생성한 여러 질문
- 같은 상품의 여러 촬영 각도

### 5-3. 시계열 분할

미래를 예측하는 모델은 과거 데이터로 학습하고 이후 시점으로 평가해야 합니다.

```
Train: 2023-01 ~ 2024-06
Validation: 2024-07 ~ 2024-12
Test: 2025-01 ~ 2025-06
```

무작위 분할을 사용하면 미래의 패턴, 이벤트, 가격 체계, 센서 상태가 훈련 데이터에 섞일 수 있습니다.

```
from sklearn.model_selection import TimeSeriesSplit

cv = TimeSeriesSplit(n_splits=5)

for fold, (train_idx, val_idx) in enumerate(cv.split(X), start=1):
    X_train_fold = X.iloc[train_idx]
    X_val_fold = X.iloc[val_idx]
    print(f"Fold {fold}: {len(train_idx)} / {len(val_idx)}")
```

필요하다면 훈련 종료 시점과 검증 시작 시점 사이에 간격을 두는 `gap`을 사용해 시간적으로 인접한 샘플의 정보 공유를 줄일 수 있습니다.

### 5-4. 공간·기관·도메인 분할

새로운 병원, 공장, 지역, 카메라, 언어, 고객사로 일반화해야 한다면 특정 도메인을 통째로 테스트 세트에 남기는 것이 좋습니다.

무작위 분할 성능은 높지만 새 기관에서 성능이 급락한다면 모델이 핵심 패턴보다 기관별 장비·문서 양식·배경을 학습했을 가능성이 있습니다.

### 5-5. 계층 분할과 그룹 분할을 함께 사용한다

그룹이 존재하면서 클래스 비율도 유지해야 한다면 `StratifiedGroupKFold` 같은 방법을 고려할 수 있습니다. 다만 희귀 클래스가 일부 그룹에만 존재하면 완벽한 비율 일치는 불가능합니다. 이 경우 분할 후보를 여러 개 생성한 뒤 다음 항목을 비교하세요.

- 그룹 중복 여부
- 클래스별 샘플 수
- 지역·장비·기간 분포
- 라벨 품질 분포
- 난이도 분포

### 5-6. K-Fold 교차검증의 올바른 사용

K-Fold는 데이터가 적거나 모델 비교의 변동성을 확인하고 싶을 때 유용합니다. 그러나 교차검증의 검증 폴드를 최종 테스트 세트와 혼동하면 안 됩니다.

권장 구조는 다음과 같습니다.

```
전체 데이터
├─ 개발 데이터: 교차검증으로 모델·하이퍼파라미터 선택
└─ 최종 테스트 데이터: 마지막 일반화 성능 평가
```

그룹이 있으면 `GroupKFold`, 클래스 불균형이 있으면 `StratifiedKFold`, 시계열이면 `TimeSeriesSplit`처럼 문제 구조에 맞는 분할기를 사용해야 합니다.

## 6. 데이터 누수와 중복을 막는 방법

데이터 누수는 모델이 실제 예측 시점에는 알 수 없는 정보를 학습하거나, 평가 데이터의 정보를 간접적으로 이용하는 현상입니다. 성능이 비정상적으로 높게 나오지만 배포 후 급격히 무너지는 대표적인 원인입니다.

### 6-1. 전처리 누수

잘못된 순서:

```
전체 데이터 정규화 → 전체 데이터 결측치 대체 → Train/Test 분할
```

올바른 순서:

```
Train/Test 분할 → Train으로 전처리 기준 학습 → Train/Test에 같은 변환 적용
```

scikit-learn 공식 문서도 먼저 데이터를 분할하고, 스케일러·결측치 처리기·특성 선택기는 훈련 데이터에만 `fit`하도록 권장합니다.

### 6-2. 중복과 근접 중복

완전히 같은 행뿐 아니라 다음도 검사해야 합니다.

- 크기만 다른 동일 이미지
- 압축률·밝기만 다른 이미지
- 같은 영상의 인접 프레임
- 문장 부호만 다른 텍스트
- 번역·요약·패러프레이즈된 동일 내용
- 같은 상품·환자·사용자의 반복 샘플
- 합성 데이터의 원본과 파생본

정형 데이터의 단순 중복 확인:

```
key_columns = ["feature_a", "feature_b", "feature_c", "target"]

duplicate_count = df.duplicated(subset=key_columns).sum()
print("중복 행:", duplicate_count)

df = df.drop_duplicates(subset=key_columns).copy()
```

파일 해시 예시:

```
from pathlib import Path
import hashlib

def sha256_file(path: Path, chunk_size: int = 1024 * 1024) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as f:
        while chunk := f.read(chunk_size):
            digest.update(chunk)
    return digest.hexdigest()
```

이미지는 SHA-256뿐 아니라 pHash·dHash 같은 지각 해시, 텍스트는 정규화 후 n-gram·MinHash·임베딩 유사도도 함께 사용할 수 있습니다.

### 6-3. 개체 누수

같은 환자의 흉부 X-ray가 훈련과 테스트에 나뉘면 모델이 질병보다 환자·촬영 장비 특성을 기억할 수 있습니다. 같은 원문에서 만든 질문이 양쪽에 나뉘는 경우도 마찬가지입니다.

분할 후 반드시 교집합을 검사합니다.

```
for column in ["user_id", "device_id", "session_id", "source_document_id"]:
    overlap = set(train_df[column]) & set(test_df[column])
    print(column, "중복 그룹 수:", len(overlap))
```

### 6-4. 타깃 누수

예측하려는 결과가 입력 특성에 직접 또는 간접적으로 들어간 경우입니다.

예시:

- 대출 부도 예측에 부도 처리 상태 코드 포함
- 질병 예측에 확진 후 처방된 약물 포함
- 이탈 예측에 해지 완료 이벤트 포함
- 불량 예측에 검사자가 입력한 최종 판정 코드 포함
- 리뷰 감정 분류에 별점 포함

각 특성에 대해 “이 값은 실제 예측 시점에 존재하는가?”를 질문해야 합니다.

### 6-5. 시간 누수

미래 데이터뿐 아니라 집계 창의 끝이 예측 시점을 넘어가는지도 확인해야 합니다.

```
예측 기준일: 7월 1일
잘못된 특성: 6월 15일~7월 15일 평균 사용량
올바른 특성: 6월 1일~6월 30일 평균 사용량
```

### 6-6. 증강 누수

원본을 먼저 증강한 뒤 무작위 분할하면 원본은 훈련 세트에, 회전·자른 이미지는 테스트 세트에 들어갈 수 있습니다.

올바른 순서는 다음과 같습니다.

```
원본 그룹 기준 분할 → 훈련 세트만 증강 → 검증·테스트는 원본 유지
```

### 6-7. LLM·RAG 벤치마크 오염

LLM에서는 공개 벤치마크, 정답 해설, 문제 변형이 사전학습 또는 파인튜닝 데이터에 포함될 수 있습니다. RAG에서는 평가 질문과 정답을 생성한 문서가 학습용 예시 또는 프롬프트 튜닝 데이터에 섞일 수 있습니다.

대응 방법은 다음과 같습니다.

- 평가 문항 원본과 훈련 코퍼스의 문자열·n-gram 유사도 검사
- 소스 문서 단위 분할
- 공개되지 않은 신규 평가 세트 유지
- 생성 시점·데이터 컷오프 기록
- 문제 변형만으로 독립성이 확보됐다고 가정하지 않기
- 실제 운영 실패 사례를 골든 세트에 추가

## 7. 데이터 정제와 전처리

### 7-1. 스키마 검증부터 시작한다

전처리 전에 데이터 구조가 기대와 같은지 검사합니다.

- 필수 열 존재 여부
- 데이터 타입
- 허용 범위
- 단위
- 범주 목록
- 고유 키
- null 허용 여부
- 파일명과 메타데이터 일치
- 이미지·라벨 파일 쌍 존재 여부

간단한 점검 함수:

```
import pandas as pd

def audit_dataframe(df: pd.DataFrame, target: str) -> dict:
    return {
        "rows": len(df),
        "columns": len(df.columns),
        "duplicate_rows": int(df.duplicated().sum()),
        "missing_by_column": df.isna().sum().to_dict(),
        "target_distribution": df[target].value_counts(dropna=False).to_dict(),
        "unique_by_column": df.nunique(dropna=False).to_dict(),
    }
```

### 7-2. 결측치는 원인부터 구분한다

결측은 모두 같은 의미가 아닙니다.

- 실제 값이 존재하지 않음
- 센서 또는 전송 실패
- 사용자가 입력하지 않음
- 해당 조건에서는 측정하지 않음
- 개인정보 제거 과정에서 삭제됨
- 구버전 시스템에 필드가 없음

결측 원인에 따라 삭제, 대체, 별도 범주, 결측 여부 특성 추가 중 하나를 선택합니다.

```
from sklearn.impute import SimpleImputer

numeric_imputer = SimpleImputer(
    strategy="median",
    add_indicator=True,
)
```

`add_indicator=True`는 값이 결측이었다는 사실을 별도 특성으로 추가합니다. 결측 자체가 의미를 가질 때 유용할 수 있습니다.

### 7-3. 이상치를 무조건 제거하지 않는다

이상치는 크게 세 종류입니다.

1. 수집 오류: 음수 나이, 센서 범위 초과 등
2. 드문 정상 사례: 실제 고액 거래, 폭염, 희귀 질환 등
3. 모델이 반드시 잡아야 할 사건: 사기, 고장, 불량 등

IQR이나 Z-Score로 탐지했다고 바로 삭제하면 중요한 희귀 사례를 제거할 수 있습니다. 먼저 원인을 확인하고 다음 중 하나를 선택합니다.

- 오류 수정
- 수집 실패로 표시
- 상·하한 절단
- 로그 변환
- 강건한 스케일링
- 별도 희귀 이벤트로 유지
- 분석 대상에서 제외하되 원본은 보존

### 7-4. 정규화와 표준화

Min-Max 정규화:

```
x_norm = (x - x_min) / (x_max - x_min)
```

표준화:

```
z = (x - 평균) / 표준편차
```

중요한 원칙은 `x_min`, `x_max`, 평균, 표준편차를 **훈련 세트에서만 계산**하는 것입니다.

### 7-5. 범주형 데이터 인코딩

- 순서 없는 저카디널리티 범주: One-Hot Encoding
- 순서가 있는 범주: 명시적인 순서 인코딩
- 범주가 매우 많음: 빈도 인코딩, 해싱, 임베딩, 교차적합 기반 타깃 인코딩
- 신규 범주 발생 가능: `handle_unknown="ignore"` 등 대응

정수 ID를 단순 숫자로 넣으면 모델이 숫자 크기에 의미가 있다고 오해할 수 있습니다.

### 7-6. 전처리 파이프라인으로 누수를 방지한다

```
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

numeric_features = ["age", "income", "usage_30d"]
categorical_features = ["region", "device_type"]

numeric_pipeline = Pipeline(
    steps=[
        ("imputer", SimpleImputer(strategy="median", add_indicator=True)),
        ("scaler", StandardScaler()),
    ]
)

categorical_pipeline = Pipeline(
    steps=[
        ("imputer", SimpleImputer(strategy="most_frequent")),
        ("onehot", OneHotEncoder(handle_unknown="ignore")),
    ]
)

preprocessor = ColumnTransformer(
    transformers=[
        ("numeric", numeric_pipeline, numeric_features),
        ("categorical", categorical_pipeline, categorical_features),
    ]
)

model = Pipeline(
    steps=[
        ("preprocess", preprocessor),
        ("classifier", LogisticRegression(max_iter=1000)),
    ]
)

model.fit(X_train, y_train)
print(model.score(X_test, y_test))
```

이 구조를 사용하면 교차검증의 각 폴드에서도 전처리 기준이 해당 훈련 폴드에서만 계산됩니다.

## 8. 데이터 유형별 전처리 핵심

### 8-1. 정형 데이터

점검 항목:

- 단위 통일
- 날짜와 시간대
- 코드값 변경 이력
- 중복 키
- 누락 행
- 범주 오타와 대소문자
- 타깃 생성 시점
- 학습·서빙 특성 일치

### 8-2. 이미지 데이터

점검 항목:

- 손상 파일
- EXIF 방향
- 해상도와 종횡비
- 색상 공간 RGB·BGR·그레이스케일
- 알파 채널
- 워터마크·테두리·배경 편향
- 동일 장면의 연속 프레임
- 원본과 썸네일 중복
- 바운딩 박스 범위
- 빈 마스크·겹친 마스크

이미지를 동일 크기로 만들 때 단순 강제 리사이즈는 객체 비율을 왜곡할 수 있습니다. 패딩, 크롭, 멀티스케일 학습 중 목적에 맞는 방식을 선택해야 합니다.

### 8-3. 텍스트·NLP 데이터

점검 항목:

- 인코딩과 깨진 문자
- HTML·마크업 제거 여부
- 언어 식별
- 중복·근접 중복
- 개인식별정보
- 문서 경계
- 텍스트 정규화가 의미를 손상하는지
- 토큰 길이 분포
- 잘림 위치
- 원문과 요약·질문 파생본의 그룹 관리

대소문자, 이모지, 문장 부호, 맞춤법을 무조건 정규화하면 감정·개체명·코드·보안 분석에 필요한 신호를 없앨 수 있습니다.

### 8-4. LLM 파인튜닝 데이터

기본 구조 예시:

```
{
  "id": "sample_000001",
  "system": "당신은 기술 지원 상담원입니다.",
  "user": "로그인이 반복해서 풀립니다.",
  "assistant": "브라우저 쿠키 설정과 세션 만료 시간을 확인해 주세요.",
  "source": "support_manual_v3",
  "quality": "reviewed",
  "license": "internal",
  "split_group": "issue_session_9281"
}
```

점검 항목:

- 지시문과 답변의 정확성
- 답변 스타일의 일관성
- 시스템 지시와 사용자 지시 충돌
- 민감정보·비밀키·내부 URL
- 거절해야 할 요청의 처리
- 장황하거나 근거 없는 답변
- 동일 지시문의 반복
- 평가 문항과의 오염
- 합성 데이터 생성 모델과 프롬프트 기록

### 8-5. RAG 데이터

RAG는 하나의 데이터셋이 아니라 여러 데이터셋이 결합됩니다.

- 검색 코퍼스
- 문서 메타데이터
- 청크 데이터
- 질문·정답 평가 세트
- 관련 문서 정답
- 인용 근거
- 검색 실패·답변 거절 사례

문서 청크는 원문 문서 ID와 버전을 반드시 유지해야 합니다. 평가 질문을 만든 문서와 질문이 여러 세트에 섞이지 않도록 문서 단위로 분할하는 것이 안전합니다.

### 8-6. 음성 데이터

점검 항목:

- 샘플레이트
- 채널 수
- 비트 깊이
- 무음 구간
- 클리핑
- 배경 소음
- 화자 중복
- 발화 경계
- 전사 규칙
- 방언·연령·성별·마이크 다양성

음성 인식 모델을 새로운 화자에게 일반화하려면 화자 단위 분할이 필수입니다.

### 8-7. 시계열 데이터

점검 항목:

- 시간대와 서머타임
- 중복 타임스탬프
- 불규칙 간격
- 센서 재시작
- 결측 구간 길이
- 보간 가능 범위
- 예측 시점 이후 정보 포함 여부
- 윈도우 간 과도한 중첩
- 장비·현장 단위 독립성

슬라이딩 윈도우를 만든 뒤 분할하면 거의 같은 구간이 양쪽 세트에 섞일 수 있습니다. **원시 시계열을 먼저 기간·장비별로 나눈 뒤 각 세트 안에서 윈도우를 생성**하는 것이 좋습니다.

### 8-8. 멀티모달 데이터

이미지·텍스트·센서·음성의 동기화와 연결 키가 핵심입니다.

- 모달리티별 타임스탬프
- 허용 동기화 오차
- 누락 모달리티 처리
- 한 모달리티에서만 라벨이 드러나는 누수
- 동일 사건의 파생 샘플 그룹
- 파일·메타데이터 참조 무결성

## 9. 데이터 라벨링과 품질 검증

### 9-1. 좋은 가이드라인의 조건

라벨링 가이드라인은 클래스 이름만 나열한 문서가 아닙니다. 다음을 포함해야 합니다.

- 작업 목적
- 라벨 단위
- 클래스 정의
- 포함·제외 사례
- 경계 사례
- 우선순위 규칙
- 불확실성 처리
- 이미지 박스·마스크 경계 규칙
- 텍스트 범위 선택 규칙
- 예시와 반례
- 변경 이력

“고양이는 고양이로 표시한다”보다 다음처럼 구체적이어야 합니다.

```
부분 가림이 있어도 머리와 몸통 일부가 식별되면 고양이로 라벨링한다.
사진·그림·인형은 실제 동물 클래스에 포함하지 않는다.
화면 면적의 2% 미만이고 종 판별이 어려우면 판단 불가로 표시한다.
고양이와 개가 함께 있으면 다중 객체로 각각 표시한다.
```

### 9-2. 파일럿 라벨링을 먼저 수행한다

전체 라벨링 전에 소규모 파일럿을 수행합니다.

1. 다양한 난이도의 샘플을 뽑는다.
2. 여러 작업자가 독립적으로 라벨링한다.
3. 불일치 사례를 유형별로 정리한다.
4. 가이드라인을 수정한다.
5. 동일 샘플을 다시 라벨링한다.
6. 기준이 안정된 뒤 본 작업을 시작한다.

### 9-3. 일치율 하나만으로 품질을 판단하지 않는다

단순 일치율은 클래스 불균형에 취약합니다. 대부분이 정상인 데이터에서는 모두 정상이라고 표시해도 높은 일치율이 나올 수 있습니다.

과제에 따라 다음 지표를 사용합니다.

| 라벨 유형 | 품질 지표 예시 |
| --- | --- |
| 단일 클래스 | 정확 일치율, Cohen’s Kappa, Fleiss’ Kappa |
| 순서형 등급 | 가중 Kappa |
| 다중 작업자·결측 라벨 | Krippendorff’s Alpha |
| 바운딩 박스 | 클래스 일치, IoU, 누락·과검출률 |
| 세그멘테이션 | IoU, Dice, 경계 오차 |
| 텍스트 범위 | Span F1, 토큰 F1 |
| 주관적 평가 | 평가자별 분포, 평균·분산, 합의 절차 |

모든 프로젝트에 “95% 이상” 같은 단일 기준을 적용하지 말고, 오류 비용과 라벨 난이도에 따라 기준을 정해야 합니다.

### 9-4. 합의와 전문가 판정

권장 구조:

```
1차 작업자 라벨링
→ 자동 규칙 검사
→ 2차 검수
→ 불일치 샘플 재검토
→ 전문가 또는 선임 검수자의 최종 판정
```

의료·법률·산업 안전처럼 정답 자체가 불확실한 분야에서는 한 명의 라벨을 절대적인 정답으로 간주하지 말고 다음을 저장하는 것이 좋습니다.

- 작업자별 원 라벨
- 합의 라벨
- 확신도
- 판정 근거
- 불확실성 유형
- 최종 판정자

### 9-5. 자동 품질 검사

라벨링 도구 밖에서도 다음 검사를 자동화할 수 있습니다.

- 허용되지 않은 클래스
- 빈 라벨
- 좌표 범위 초과
- 음수 너비·높이
- 이미지 밖 박스
- 자기 교차 폴리곤
- 빈 마스크
- 파일명 불일치
- 중복 객체
- 비정상적으로 작은 객체
- 클래스별 개수 급변

### 9-6. 모델 기반 오류 탐색

초기 모델을 학습한 뒤 다음 샘플을 우선 검수하면 효율적입니다.

- 모델과 라벨이 크게 다른 샘플
- 손실이 높은 샘플
- 확신도가 낮은 샘플
- 여러 모델이 서로 다르게 예측한 샘플
- 임베딩 공간에서 주변 샘플과 라벨이 다른 샘플

다만 모델의 예측을 정답으로 자동 덮어쓰면 모델 편향이 라벨에 되먹임될 수 있습니다. 최종 판정은 가이드라인과 원본 근거를 기준으로 해야 합니다.

### 9-7. 액티브 러닝·약한 지도·반지도 학습

라벨 비용이 높을 때 사용할 수 있습니다.

- 액티브 러닝: 정보 가치가 높은 샘플을 우선 라벨링
- 약한 지도: 규칙·사전·기존 시스템으로 후보 라벨 생성
- 반지도 학습: 소량의 정답 라벨과 다량의 비라벨 데이터 사용
- 자기지도 학습: 라벨 없이 표현을 사전학습
- 사전 라벨링: 모델 예측을 작업자에게 제시하고 사람이 수정

비용 절감 폭은 문제와 초기 모델 품질에 따라 크게 달라지므로 고정된 절감률을 약속하기보다 파일럿으로 측정해야 합니다.

## 10. 클래스 불균형·대표성·편향 관리

### 10-1. 클래스 수를 무조건 같게 만들 필요는 없다

운영 환경에서 불량이 1%, 정상이 99%라면 테스트 세트도 실제 발생률을 반영하는 것이 일반적입니다. 다만 희귀 클래스 성능을 안정적으로 측정하기 위해 별도의 균형 평가 세트나 챌린지 세트를 추가할 수 있습니다.

권장 구조:

- 운영 분포 테스트 세트: 실제 성능과 비용 추정
- 균형 또는 희귀 사례 세트: 클래스별 비교
- 챌린지 세트: 어려운 조건과 경계 사례 평가

훈련 세트는 오버샘플링, 언더샘플링, 클래스 가중치, Focal Loss 등을 적용할 수 있지만 검증·테스트 분포까지 인위적으로 바꾸면 운영 성능 해석이 어려워질 수 있습니다.

### 10-2. 전체 평균이 가리는 실패를 찾는다

다음 슬라이스별 성능을 확인하세요.

- 클래스
- 지역
- 언어
- 사용자군
- 장비 모델
- 해상도
- 조명·날씨
- 시간대·계절
- 신규·기존 사용자
- 입력 길이
- 객체 크기
- 데이터 품질 등급

전체 정확도가 95%여도 야간 영상에서 60%, 특정 장비에서 50%라면 배포 위험이 큽니다.

### 10-3. 대표성과 공정성은 같은 개념이 아니다

인구 비율을 맞추는 것만으로 편향 문제가 해결되지는 않습니다. 라벨 기준, 접근성, 역사적 데이터의 차별, 측정 방식, 누락 패턴도 영향을 줍니다.

데이터셋 문서에는 다음을 기록하세요.

- 누가 데이터에 포함됐는가?
- 누가 빠졌는가?
- 어떤 환경에서 수집됐는가?
- 라벨을 누가 어떤 기준으로 만들었는가?
- 어떤 용도에는 사용하면 안 되는가?
- 알려진 성능 취약 구간은 어디인가?

## 11. 데이터 증강과 합성 데이터

### 11-1. 증강은 라벨 보존 조건을 만족해야 한다

증강된 샘플이 원래 정답을 유지해야 합니다.

예시:

- 일반 사물 분류의 좌우 반전: 대체로 가능
- 글자·교통 표지판 좌우 반전: 의미가 바뀔 수 있음
- 의료 영상 회전: 해부학적 방향이 중요한 경우 주의
- 시계열 시간 역전: 인과관계가 깨질 수 있음
- 텍스트 동의어 치환: 전문 용어와 부정 표현이 변할 수 있음

### 11-2. 훈련 세트에만 적용한다

검증·테스트 세트는 실제 입력을 대표해야 하므로 원칙적으로 원본을 유지합니다. 테스트 시간 증강은 모델 추론 기법이며, 평가 프로토콜에 별도로 기록해야 합니다.

### 11-3. 합성 데이터는 원본과 분리해 추적한다

합성 데이터 메타데이터 예시:

```
is_synthetic: true
generator_model: model_name
generator_version: v2
prompt_template: prompt_v4
seed: 18273
source_sample_id: optional
human_reviewed: true
quality_score: 0.92
```

합성 데이터만으로 테스트 세트를 구성하면 실제 환경 성능을 과대평가할 수 있습니다. 합성 데이터는 훈련 보강, 희귀 사례 탐색, 안전 테스트에 유용하지만 실제 데이터 기반 평가를 대체하지는 못합니다.

### 11-4. 합성 데이터의 대표적인 위험

- 생성 모델의 편향 복제
- 다양성보다 표면적 변형만 증가
- 잘못된 라벨과 환각
- 생성 모델 특유의 패턴 학습
- 원본 데이터의 개인정보 재현
- 평가 세트와 의미상 중복
- 실제 센서·사용자 노이즈 부족

## 12. 평가 데이터셋과 골든 세트

### 12-1. 하나의 테스트 세트로 모든 질문에 답할 수 없다

평가 목적에 따라 여러 세트를 운영하는 것이 좋습니다.

| 평가 세트 | 목적 |
| --- | --- |
| 최종 홀드아웃 | 일반화 성능 추정 |
| 운영 분포 세트 | 실제 트래픽 성능 추정 |
| 골든 세트 | 반드시 맞혀야 할 핵심 사례 |
| 챌린지 세트 | 희귀·경계·악조건 평가 |
| OOD 세트 | 새로운 장비·지역·기관 일반화 |
| 회귀 테스트 세트 | 배포 버전 간 성능 저하 탐지 |
| 안전 세트 | 유해·민감·거절 상황 평가 |

### 12-2. 골든 세트 구성법

골든 세트에는 무작위 샘플만 넣지 말고 다음을 포함합니다.

- 비즈니스상 중요한 대표 사례
- 과거 장애와 고객 불만 사례
- 클래스별 전형적 사례
- 자주 혼동하는 클래스 쌍
- 어려운 경계 사례
- 라벨 전문가가 합의한 사례
- 운영 중 새로 발견된 실패 사례

각 샘플에는 기대 결과뿐 아니라 **왜 그 결과여야 하는지**를 기록하면 LLM·RAG·주관적 판정 과제에 특히 유용합니다.

### 12-3. LLM·RAG 평가 데이터의 필드 예시

```
{
  "id": "eval_0042",
  "question": "제품의 무상 보증 기간은 얼마인가?",
  "expected_answer": "구매일로부터 2년",
  "source_document_id": "warranty_policy_2026_v2",
  "evidence": "제3조 1항",
  "must_cite": true,
  "allowed_abstention": false,
  "category": "policy_qa",
  "difficulty": "medium",
  "risk": "high"
}
```

검색 품질과 생성 품질을 분리해 평가해야 합니다.

- 검색: Recall@K, MRR, nDCG, 근거 포함률
- 답변: 정확성, 근거성, 완전성, 인용 정확성
- 시스템: 지연시간, 비용, 거절 적절성, 안전성

## 13. 데이터 문서화·버전 관리·계보 추적

### 13-1. 데이터셋 카드가 필요한 이유

Google Research의 Data Cards는 데이터셋 생애주기 전반에 필요한 핵심 사실을 구조화해 기록하는 방식을 제안합니다. 데이터셋 문서가 없으면 시간이 지난 뒤 다음 질문에 답하기 어렵습니다.

- 왜 만들었는가?
- 어디서 수집했는가?
- 누구를 대표하는가?
- 어떤 전처리를 했는가?
- 라벨은 누가 만들었는가?
- 어떤 제한과 위험이 있는가?
- 어떤 버전의 모델이 사용했는가?

### 13-2. 데이터셋 카드 기본 항목

```
데이터셋 이름과 버전
목적과 권장 사용처
금지 또는 비권장 사용처
수집 기간과 지역
원본 출처와 라이선스
샘플 단위와 데이터 구조
클래스·그룹 분포
수집·정제·라벨링 방법
훈련·검증·테스트 분할 기준
중복 제거 방법
개인정보와 보안 조치
알려진 편향과 한계
품질 검사 결과
유지보수 담당자
변경 이력
```

### 13-3. 파일명에 `final_v2_realfinal`을 붙이는 방식은 버전 관리가 아니다

재현 가능한 데이터 버전에는 다음이 필요합니다.

- 변경 불가능한 버전 ID
- 파일 체크섬 또는 데이터 다이제스트
- 생성 코드 커밋
- 원본 데이터 버전
- 변환 파라미터
- 분할 목록
- 라벨 스키마 버전
- 생성 일자

MLflow는 학습·검증·평가 데이터의 출처, 다이제스트, 스키마와 모델 실행 간 연결을 추적하는 기능을 제공합니다. 대규모 파일 기반 데이터는 DVC, lakeFS, 객체 스토리지 버전 관리, 데이터 레이크 테이블 버전 등을 사용할 수 있습니다.

### 13-4. 분할 목록을 별도 파일로 고정한다

매번 실행할 때 무작위 분할을 다시 만들면 모델 비교가 어려워집니다.

```
splits/
├─ train_ids.txt
├─ validation_ids.txt
├─ test_ids.txt
└─ split_metadata.json
```

`split_metadata.json` 예시:

```
{
  "dataset_version": "2026.07.1",
  "strategy": "group_stratified",
  "group_key": "user_id",
  "random_seed": 42,
  "created_at": "2026-07-16",
  "train_count": 70000,
  "validation_count": 15000,
  "test_count": 15000
}
```

### 13-5. 원본은 수정하지 않는다

권장 계층:

```
raw → interim → processed → curated → split → training-ready
```

- `raw`: 수집 당시 원본, 읽기 전용
- `interim`: 압축 해제·형식 통일 등 중간 결과
- `processed`: 정제와 표준화 완료
- `curated`: 품질 검수와 라벨 확정
- `split`: 분할 정보 적용
- `training-ready`: 모델 입력 형식

문제가 발견되면 원본부터 동일한 파이프라인으로 다시 생성할 수 있어야 합니다.

## 14. 실전 디렉터리와 메타데이터 구조

### 14-1. 범용 구조

```
dataset/
├─ README.md
├─ DATASET_CARD.md
├─ LICENSE
├─ metadata/
│  ├─ samples.parquet
│  ├─ label_schema.json
│  ├─ collection_sources.csv
│  └─ quality_report.json
├─ raw/
├─ processed/
├─ labels/
├─ splits/
│  ├─ train.txt
│  ├─ validation.txt
│  └─ test.txt
├─ scripts/
│  ├─ collect.py
│  ├─ validate.py
│  ├─ preprocess.py
│  ├─ deduplicate.py
│  └─ create_splits.py
└─ reports/
   ├─ class_distribution.md
   ├─ duplicate_report.md
   ├─ labeling_agreement.md
   └─ sample_gallery.html
```

### 14-2. 이미지 탐지 데이터 메타데이터 예시

```
sample_id
image_path
width
height
source_id
scene_id
camera_id
captured_at
split
object_count
classes
labeler_id
review_status
sha256
perceptual_hash
license
```

### 14-3. 시계열 데이터 메타데이터 예시

```
series_id
device_id
site_id
start_time
end_time
sampling_interval
missing_ratio
sensor_version
calibration_date
target_window_start
target_window_end
split
```

## 15. 엔드투엔드 데이터셋 구축 절차

### 단계 1. 문제와 평가 기준 정의

- 예측 단위
- 입력 시점
- 라벨 정의
- 운영 환경
- 실패 비용
- 핵심 평가 지표

### 단계 2. 데이터 명세 작성

- 필요한 데이터 유형
- 필수 메타데이터
- 수집 범위
- 목표 클래스·슬라이스
- 포함·제외 기준
- 법적·보안 요구사항

### 단계 3. 파일럿 수집

- 실제 수집 가능성 확인
- 누락과 오류 유형 파악
- 라벨 체계 검증
- 예상 비용과 속도 측정

### 단계 4. 원본 저장과 계보 기록

- 원본 불변 저장
- 체크섬
- 수집 코드 버전
- 출처·라이선스·동의 상태

### 단계 5. 품질 프로파일링

- 스키마
- 결측
- 중복
- 분포
- 이상치
- 그룹 수
- 시간 범위
- 클래스·슬라이스 분포

### 단계 6. 그룹과 시간 기준으로 분할

- 먼저 최종 테스트 세트 격리
- 개발 데이터에서 검증 또는 교차검증
- 분할 ID 고정
- 그룹 교집합 검사

### 단계 7. 전처리 파이프라인 구축

- 훈련 세트로만 `fit`
- 동일 변환을 검증·테스트에 적용
- 변환 코드와 파라미터 버전 관리

### 단계 8. 라벨링과 검수

- 파일럿 라벨링
- 가이드라인 수정
- 본 라벨링
- 자동 검사
- 다중 검수와 합의

### 단계 9. 중복·누수 감사

- 정확 중복
- 근접 중복
- 그룹 중복
- 시간 누수
- 파생 데이터 누수
- 평가 오염

### 단계 10. 기준 모델 학습과 오류 분석

- 클래스별 지표
- 슬라이스별 지표
- 고손실 샘플
- 불확실 샘플
- 라벨 오류 후보

### 단계 11. 데이터셋 카드와 품질 보고서 작성

- 구성과 출처
- 품질 지표
- 알려진 한계
- 권장·비권장 사용처
- 버전 이력

### 단계 12. 배포 후 데이터 유지보수

- 입력 분포 변화
- 신규 클래스
- 라벨 지연
- 센서·서비스 버전 변화
- 운영 실패 사례
- 재학습 데이터 승인 절차

## 16. 최종 체크리스트

### 문제 정의

- [ ] 한 샘플의 단위를 명확히 정의했다.
- [ ] 예측 시점에 사용 가능한 특성만 포함했다.
- [ ] 목표 모집단과 운영 환경을 정의했다.
- [ ] 클래스와 라벨의 포함·제외 기준을 문서화했다.
- [ ] 모델이 처리하지 않을 범위를 정의했다.

### 수집과 권리

- [ ] 데이터 출처와 수집 시각을 기록했다.
- [ ] 라이선스와 상업적 이용 조건을 확인했다.
- [ ] 개인정보·민감정보·저작물 포함 여부를 확인했다.
- [ ] 동의·보관 기간·삭제 요청 절차를 검토했다.
- [ ] 원본 데이터와 체크섬을 보존했다.

### 분할

- [ ] 랜덤·계층·그룹·시간·도메인 중 적절한 전략을 선택했다.
- [ ] 동일 사용자·환자·장비·문서·장면이 여러 세트에 섞이지 않았다.
- [ ] 시계열에서 미래 정보가 훈련 데이터에 들어가지 않았다.
- [ ] 분할 목록과 랜덤 시드를 저장했다.
- [ ] 최종 테스트 세트를 개발 과정에서 보호했다.

### 전처리

- [ ] 분할을 전처리보다 먼저 수행했다.
- [ ] 결측치 대체와 스케일링 기준을 훈련 세트에서만 학습했다.
- [ ] 특성 선택과 차원 축소를 훈련 세트에서만 학습했다.
- [ ] 검증·테스트에는 훈련과 동일한 변환만 적용했다.
- [ ] 학습과 서빙의 전처리가 일치한다.

### 중복과 누수

- [ ] 정확 중복을 검사했다.
- [ ] 이미지·텍스트·시계열의 근접 중복을 검사했다.
- [ ] 파생본과 원본이 여러 세트에 나뉘지 않았다.
- [ ] 타깃 생성 이후의 정보가 입력에 포함되지 않았다.
- [ ] 공개 벤치마크와 학습 데이터의 오염 가능성을 검토했다.

### 라벨링

- [ ] 라벨링 가이드라인과 예시·반례가 있다.
- [ ] 파일럿 라벨링으로 기준을 검증했다.
- [ ] 불확실·판단 불가 사례 처리 규칙이 있다.
- [ ] 자동 형식 검사와 샘플 육안 검수를 수행했다.
- [ ] 과제에 적합한 작업자 간 일치 지표를 계산했다.
- [ ] 불일치 사례의 합의·전문가 판정 절차가 있다.

### 대표성과 평가

- [ ] 희귀 클래스의 평가 샘플 수가 충분하다.
- [ ] 운영 분포와 테스트 분포의 차이를 설명할 수 있다.
- [ ] 클래스·지역·장비·시간·난이도별 성능을 확인할 수 있다.
- [ ] 골든·챌린지·OOD·회귀 테스트 세트를 구분했다.
- [ ] 평가 데이터의 라벨과 근거를 전문가가 검토했다.

### 재현성과 운영

- [ ] 데이터셋 버전과 변경 이력이 있다.
- [ ] 데이터 생성 코드와 커밋을 연결했다.
- [ ] 스키마·분포·품질 보고서를 저장했다.
- [ ] 어떤 모델이 어떤 데이터 버전을 사용했는지 추적할 수 있다.
- [ ] 배포 후 드리프트와 신규 실패 사례를 수집할 계획이 있다.

## 17. FAQ

### Q1. 데이터는 많을수록 무조건 좋은가요?

아닙니다. 중복, 잘못된 라벨, 운영 환경과 무관한 데이터가 늘어나면 학습 비용만 증가하거나 성능이 나빠질 수 있습니다. 전체 수량보다 독립적인 사례 수, 클래스·환경 다양성, 라벨 정확성, 배포 적합성이 중요합니다.

### Q2. Train과 Test는 반드시 같은 분포여야 하나요?

목표에 따라 다릅니다. 일반적인 성능 추정용 테스트 세트는 실제 배포 분포를 대표해야 합니다. 훈련 데이터도 가능한 한 그 분포를 충분히 포함해야 하지만, 미래·신규 지역·신규 장비 일반화를 평가하려면 의도적으로 다른 분포의 OOD 테스트 세트를 추가할 수 있습니다. 중요한 것은 차이를 모르고 섞는 것이 아니라, **평가 목적에 맞게 분포를 설계하고 문서화하는 것**입니다.

### Q3. Validation Set이 꼭 필요한가요?

모델 선택과 하이퍼파라미터 조정이 있다면 필요합니다. 데이터가 적을 때는 고정 검증 세트 대신 교차검증을 사용할 수 있지만, 최종 성능을 위한 독립 테스트 세트는 남겨 두는 것이 좋습니다.

### Q4. 테스트 세트를 여러 번 평가하면 안 되나요?

반복 실행 자체보다 테스트 결과를 이용해 모델을 계속 수정하는 것이 문제입니다. 자동화된 회귀 테스트는 반복할 수 있지만 개발팀이 특정 테스트 세트에 맞춰지면 새로운 블라인드 세트 또는 시간 기반 신규 세트를 추가해야 합니다.

### Q5. 클래스 불균형이면 모든 클래스를 같은 수로 맞춰야 하나요?

아닙니다. 훈련에서는 샘플링이나 가중치를 적용할 수 있지만, 운영 성능을 추정하는 테스트 세트는 실제 발생률을 반영하는 것이 일반적입니다. 희귀 클래스 분석을 위해 별도의 균형 평가 세트를 함께 운영하세요.

### Q6. 정규화와 표준화 중 무엇을 써야 하나요?

모델과 데이터 분포에 따라 다릅니다. 신경망의 픽셀 입력은 0~1 범위 변환을 자주 사용하고, 선형 모델·거리 기반 모델·신경망의 연속형 특성에는 표준화를 자주 사용합니다. 트리 기반 모델은 스케일링 영향이 비교적 적습니다. 어떤 방법이든 훈련 세트에서만 기준을 학습해야 합니다.

### Q7. 라벨링 비용을 줄이는 가장 현실적인 방법은 무엇인가요?

먼저 라벨 체계를 단순하고 명확하게 만들고, 소규모 파일럿으로 오류를 줄이는 것이 가장 중요합니다. 이후 사전 라벨링, 액티브 러닝, 약한 지도, 반지도 학습을 적용할 수 있습니다. 자동화보다 모호한 기준 때문에 발생하는 재작업 비용이 더 큰 경우가 많습니다.

### Q8. 데이터 증강을 저장해서 데이터 수를 늘려야 하나요?

항상 그럴 필요는 없습니다. 이미지 증강은 학습 시점에 무작위로 적용하면 저장 공간을 줄이고 더 다양한 변형을 만들 수 있습니다. 다만 재현성과 감사가 중요한 프로젝트에서는 증강 정책, 라이브러리 버전, 확률, 랜덤 시드를 기록해야 합니다.

### Q9. 운영 중 새 데이터가 들어오면 기존 테스트 세트에 추가해도 되나요?

가능하지만 역할을 구분해야 합니다. 운영 실패 사례는 회귀 테스트나 골든 세트에 추가하고, 실제 최신 분포를 평가하는 시간 기반 테스트 세트도 별도로 유지하는 것이 좋습니다. 기존 점수와 비교하려면 고정 세트와 최신 세트를 동시에 보고해야 합니다.

### Q10. 데이터셋 완성 여부는 어떻게 판단하나요?

다음 조건을 만족하면 첫 운영 버전으로 볼 수 있습니다.

- 목표 환경의 주요 슬라이스가 포함됨
- 누수와 중복 감사 완료
- 라벨 품질 기준 충족
- 기준 모델과 오류 분석 완료
- 테스트 지표의 불확실성을 해석 가능
- 데이터셋 카드와 버전 정보 작성 완료
- 배포 후 수집·검수·갱신 절차 수립

데이터셋은 한 번 완성하고 끝나는 산출물이 아니라, 운영 환경과 모델 실패를 반영해 지속적으로 관리하는 제품에 가깝습니다.

## 정리

데이터셋 구성의 핵심은 데이터를 많이 모으는 것이 아닙니다. **모델이 실제로 해결해야 할 문제를 정확히 표현하고, 평가 결과를 믿을 수 있도록 독립성과 추적성을 확보하는 것**입니다.

실무에서 가장 중요한 원칙을 다시 정리하면 다음과 같습니다.

- 문제·예측 단위·입력 시점을 먼저 정의한다.
- 원본 출처와 권리, 개인정보 상태를 기록한다.
- 사용자·환자·장비·문서·시간을 고려해 분할한다.
- 전처리 기준은 훈련 데이터에서만 학습한다.
- 원본과 파생본의 중복·근접 중복을 제거한다.
- 라벨의 불확실성과 작업자 간 불일치를 관리한다.
- 테스트 세트는 실제 환경과 평가 목적을 대표하게 만든다.
- 데이터셋 카드, 체크섬, 코드, 분할 목록으로 재현성을 확보한다.
- 배포 후 실패 사례를 다시 데이터셋 개선으로 연결한다.

좋은 모델을 만들기 전에 좋은 데이터셋을 설계해야 합니다. 데이터가 모델의 입력이라면, **데이터셋 설계는 AI 시스템 전체의 요구사항 명세서이자 테스트 계획서**입니다.

## 참고 자료

- [Google Machine Learning Crash Course — Datasets, generalization, and overfitting](https://developers.google.com/machine-learning/crash-course/overfitting)
- [Google Machine Learning Crash Course — Dividing the original dataset](https://developers.google.com/machine-learning/crash-course/overfitting/dividing-datasets)
- [Google Machine Learning Crash Course — Class-imbalanced datasets](https://developers.google.com/machine-learning/crash-course/overfitting/imbalanced-datasets)
- [scikit-learn — Common pitfalls and recommended practices](https://scikit-learn.org/stable/common_pitfalls.html)
- [scikit-learn — Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)
- [scikit-learn — Pipelines and composite estimators](https://scikit-learn.org/stable/modules/compose.html)
- [Google Research — Data Cards: Purposeful and Transparent Dataset Documentation for Responsible AI](https://research.google/pubs/data-cards-purposeful-and-transparent-dataset-documentation-for-responsible-ai/)
- [NIST — Artificial Intelligence Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework)
- [MLflow — Dataset Tracking](https://mlflow.org/docs/latest/ml/dataset/)
- [Hugging Face — Datasets documentation](https://huggingface.co/docs/datasets/en/index)
- [개인정보 포털 — 개인정보의 개념](https://www.privacy.go.kr/front/contents/cntntsView.do?contsNo=27)
- [한국저작권위원회 — AI·저작권 안내서 모음](https://www.copyright.or.kr/notify/notice/view.do?brdctsno=55402)
- [국가법령정보센터 — 인공지능 발전과 신뢰 기반 조성 등에 관한 기본법](https://www.law.go.kr/lsInfoP.do?lsiSeq=268543)

## 같이 보면 좋은 글

- [특성 공학 완전 가이드](https://doyouknow.kr/feature-engineering-selection-extraction-pca-normalization/)
- [데이터 품질과 정제의 모든 것](https://doyouknow.kr/data-quality-labeling-ai-project-failure-prevention/)
- [데이터 증강 완벽 가이드](https://doyouknow.kr/data-augmentation-mixup-cutmix-autoaugment-back-translation-eda-guide/)
- [AI 모델 성능 평가 지표 완전 정복](https://doyouknow.kr/ai-model-evaluation-metrics-complete-guide2/)
- [과적합과 과소적합 해결 가이드](https://doyouknow.kr/overfitting-underfitting-regularization-dropout-solution/)
- [합성 데이터 완벽 가이드](https://doyouknow.kr/synthetic-data-guide-gan-vae-diffusion-ai-training/)
- [MLOps 완벽 가이드](https://doyouknow.kr/mlops-complete-guide-pipeline-serving-monitoring/)

### 이 글 공유하기:

- [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling2/?share=facebook)
- [X에 공유 (새 창에서 열림)X](https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling2/?share=x)
-

### 이것이 좋아요:

좋아하기로드 중...

### *관련*

### 관련된 글:

1. [[AI 101] 데이터셋 구성의 모든 것 – AI 성능을 좌우하는 데이터 준비의 기술](https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling/)
2. [특성 공학 완전 정복: 특성 선택·추출·정규화·PCA와 실전 피처 생성](https://doyouknow.kr/feature-engineering-selection-extraction-pca-normalization2/)
3. [[AI 101] AI가 데이터를 이해하는 방법 – 데이터가 AI의 연료인 이유](https://doyouknow.kr/ai-data-importance-structured-unstructured-bias/)
4. [[AI 101] 특성 공학(Feature Engineering) – AI 성능을 2배 높이는 데이터 변환의 기술](https://doyouknow.kr/feature-engineering-selection-extraction-pca-normalization/)

### 댓글 남기기[응답 취소](/ai-dataset-preparation-train-validation-test-labeling2/?t=1785818552#respond)
