TIL(Today I Learned)
1️⃣최종 프로젝트(10)
908 샘플 × 2,881 컬럼짜리 초고차원 제조 데이터를 누수 없이 2,876 → 549/334개 피처로 줄이고, 최종적으로 18~75개 피처만으로 성능의 99%를 확보한 과정을 정리한다.
1. 왜 전처리가 필요했나

데이터는 908 샘플 × 2,881 컬럼(센서 피처 2,876개 + 제품 코드 T·A·O). 타깃(Y_Class)은 정상 640 vs 불량 124/144로 편중된 3-클래스다.
전처리가 필수였던 이유는 다섯 가지다.
- 고차원 — 피처(2,876) ≫ 샘플(908)이라 과적합 위험이 구조적으로 크다.
- 위장 결측 —
999,-9999같은 placeholder가 실제 결측을 숫자로 은폐하고 있다. 이를 NaN으로 통일하는 작업을 최우선으로 해야 이후의 결측률·분산 계산이 왜곡되지 않는다. - 무정보 컬럼 — 완전결측·상수·저분산 센서가 다수.
- 다중공선성 — 센서 간 상관이 높아 정보가 중복된다.
- 클래스 불균형 — macro-F1 평가와 층화 추출이 필요해지는 이유.
2. 10단계 전처리 파이프라인
전처리는 준비 → 정제(Cleaning) → 차원 축소(Reduction) → 인코딩·결측 정책 흐름으로 구성했다.
| 국면 | 단계 | 내용 |
|---|---|---|
| 준비 | 1–2 | 제품별 분리(A_31 / T·O_31 두 트랙), 타깃·ID·시간 등 누수 컬럼 제거 |
| 정제 | 3–5 | 위장 결측 → NaN 통일(최우선), 완전결측 제거, 결측 60%↑ 제거 |
| 차원 축소 | 6–8 | 상수·제로분산 제거, 저분산(정규화 분산 < 0.01) 제거, 고상관(|corr| > 0.95) 제거 |
| 인코딩·결측 정책 | 9–10 | LINE 원-핫 인코딩(drop_first), 남은 NaN은 대체하지 않음 |
핵심 설계 결정 두 가지.
- 제품별 분리: 결측 구조의 원인이 '제품'이다. A 계열과 T·O 계열은 측정하는 센서 구성 자체가 다르므로, 하나의 글로벌 파이프라인으로 처리하면 안 된다.
- 결측 유지: 결측이 MNAR(Missing Not At Random)이므로 평균/중앙값 대치는 정보를 왜곡한다. 대신 XGBoost·LightGBM 같은 NaN-native 트리 모델에 결측을 그대로 넘긴다.
3. 전처리 결과 — 제품마다 제거 분포가 다르다

- T·O_31: 완전결측이 2,195개로 압도적 → 제품별 센서 구성 차이의 직접 증거
- A_31: 고상관(764)·결측 60%↑(612)에서 집중 제거
- 결과: A_31 2,876 → 549 (81%↓), T·O_31 2,876 → 334 (88%↓)
제거 분포가 제품마다 다르다는 사실 자체가, 개별 파이프라인 적용이 타당하다는 사후 근거가 된다.
4. 피처선택 파이프라인 — 4단계 + Nested CV
피처선택은 싼 필터 → 통계적 검증 → 개수 확정 순서로, 계산 비용이 낮은 것부터 배치했다.
- 값 기반 필터 — 중복·상수·저분산 피처 저비용 제거
- 상관 클러스터링 — 다중공선성 피처를 클러스터 대표 1개로 압축
- 기여도 산출 — permutation + SHAP, 3개 모델 교차 확인
- 성능곡선 + 1-SE rule — 최종 피처 개수를 데이터로 확정
검증 뼈대는 Nested 3×3 CV다. 바깥 3-fold는 채점만, 안쪽 3-fold는 선택만 담당한다. 선택과 채점을 물리적으로 분리하고 모든 단계를 각 fold의 train에서만 fit하기 때문에 성능 추정이 부풀려지지 않는다.
4-1. 상관 클러스터링

거리 = 1 − |상관계수|로 계층적 클러스터링을 하고, 상관 0.9 컷에서 클러스터 대표만 남긴다. 상관된 피처를 방치하면 뒤의 기여도 측정에서 중요도가 서로 나뉘어 과소평가되기 때문에, 기여도 산출보다 먼저 수행해야 한다. 결과: A 계열 1,175 → 1,099개.
4-2. 기여도 — permutation + SHAP

- Permutation importance: 그 피처를 섞으면 macro-F1이 얼마나 떨어지나 → 전역 성능 기여
- SHAP mean |contribution|: 각 예측을 평균에서 얼마나 밀어냈나 → 예측 단위 기여
X318 · X1152 · X1560처럼 두 지표 모두 상위인 피처는 확실한 신호, 한쪽만 상위인 피처는 추가 검토 대상으로 분류한다.
4-3. 성능곡선 + 1-SE rule

"몇 개 남길까"를 감이 아니라 데이터로 확정하는 단계다. 피처 개수를 늘려가며 3-fold macro-F1을 측정하고, 최고 성능 − 1 표준오차를 임계선으로 삼아 그 위로 올라오는 가장 적은 피처 개수를 선택한다. 성능이 통계적으로 동급이면 더 단순한 모델을 고른다
실측 결과가 흥미롭다. 18~75개면 성능의 99%를 확보하고, 1,099개를 전부 쓰면 오히려 0.64로 하락한다. "피처는 많을수록 좋다"는 이 데이터에서 명확히 틀렸다.
6. 정리
| # | 원칙 | 내용 |
|---|---|---|
| 01 | 제품군별 독립 | 결측 구조의 원인이 제품 → A / T·O 분리, LINE은 피처로 |
| 02 | 결측 유지 | MNAR이므로 대치는 정보 왜곡 → NaN-native 트리 모델 |
| 03 | 단계적 피처선택 | 싼 필터 → 상관 압축 → 기여도 → 성능곡선(1-SE) |
| 04 | 정직한 검증 | Nested 3×3 CV로 선택·채점 분리, 위장 결측 정규화는 최우선 |
7. 튜터링 피드백
- 차원축소 없이 그대로 진행 => 축소 더 해보면 좋은데 이건 나중에.
- 퀄리티 예측 후 임계치 설정은 어쩔 수 없이 하드코딩 해야 한다.
- 실제로 회귀 예측보다 다이렉트 분류가 더 잘됨 = 근데 그렇게 하면 안된다.
- 내일 추가 컬럼 정보 나가니 내일 설명 예정
💡 느낀점
결측을 무작정 채우기 전에 왜 비어 있나 생각했다. 그래서 대치 대신 NaN을 그대로 두는 게 맞다는 결론에 도달했다. 제품군을 나눈 것도 데이터를 뜯어보니 애초에 센서 구성이 다른 두 집단이었기 때문이다. 성능곡선을 그려보니 피처를 다 쓰면 오히려 성능이 떨어졌다. 많을수록 좋다는 게 착각이었다는 걸 숫자로 확인한 순간이 가장 기억에 남는다. 마지막으로 Nested CV로 선택과 채점을 분리하면서, 성능을 부풀리지 않고 정직하게 검증하는 게 중요하다고 생각되어 채택하였다.
'최종 프로젝트' 카테고리의 다른 글
| Chapter.9 최종 실전 자동화 프로젝트 (14) (0) | 2026.07.21 |
|---|---|
| Chapter.9 최종 실전 자동화 프로젝트 (13) (0) | 2026.07.20 |
| Chapter.9 최종 실전 자동화 프로젝트 (11) (0) | 2026.07.10 |
| Chapter.9 최종 실전 자동화 프로젝트 (10) (1) | 2026.07.09 |
| Chapter.9 최종 실전 자동화 프로젝트 (9) (0) | 2026.07.08 |