오늘 한 일
LOT/캐비티/설비 기반 불량 예측 모델 — 팀 공유용 설명
첨부 이미지 2개(16_17_성능요약_시각자료.png, 17_stepH_설비별_성능비교_시각자료.png)와 함께 보는 설명 문서입니다.


1. 무엇을 하려는 프로젝트인가
사출성형 공정에서 검사 결과(FAI)가 나오기까지 시간이 오래 걸려서, 그 전에 이미 알 수 있는 공정 조건값만으로 "이번 배치(LOT)가 불량이 많이 나올 것 같다"를 미리 예측하는 모델을 만드는 것이 목표입니다.
이전 실험(shot 단위 baseline)에서는 F1 0.643 수준에서 성능이 정체돼 있었습니다. 이번 작업은 이 정체를 뚫기 위해 (1) 예측 단위를 바꾸고 (2) 캐비티·설비 정보를 구조적으로 반영하고 (3) 시간 흐름(drift) 문제를 다루는 세 방향으로 진행했습니다.
2. 캐비티(cavity)를 어떻게 반영했는가
사출기 1대에는 캐비티(사출 노즐)가 4개 있고, 캐비티마다 불량 경향이 다릅니다. 이걸 모델에 반영한 방법은 다음과 같습니다.
- 캐비티 번호 파싱: 제품 시리얼번호(SN, 예: DGMF28110991B+E05J3+B)를 +로 분리했을 때 두 번째 조각의 끝자리 숫자가 캐비티 번호입니다. 이 규칙으로 모든 shot에 캐비티 번호(1~4)를 붙였습니다.
- 캐비티 키는 항상 "설비+캐비티" 조합으로 사용: 단순히 "캐비티 1"이라고만 하면 서로 다른 설비의 캐비티 1을 같은 것으로 취급하는 오류가 생기므로, 반드시 설비ID와 묶어서 하나의 캐비티로 취급했습니다.
- 캐비티별 정보를 두 종류의 피처로 반영:
- LOT 단위로 집계할 때 캐비티별 불량률(cavity1~4_fail_rate)을 따로 계산
- "직전 LOT의 캐비티별 불량률"(prev_cavity1~4_fail_rate)과 "최근 8시간 이내 같은 캐비티의 불량 현황"(rolling_fail_rate_8h_..._cavity1~4) 같은 시간 기반 힌트도 캐비티별로 따로 만들었습니다.
즉 캐비티 정보는 "이 LOT이 어느 캐비티에서 나왔는지" 자체를 넣은 게 아니라, "그 캐비티가 최근에/직전에 얼마나 불량이 잦았는지"라는 힌트로 녹여 넣은 것입니다. 이 힌트들이 실제로 feature importance 상위권을 계속 차지하는 것으로 확인됐습니다.
3. 설비(MACH_ID)를 어떻게 반영했는가
13개 설비(E05~E10, F01~F04, F06~F08)를 다루는 방식은 두 단계로 나뉩니다.
- 모델은 통합 1개로 운영: 설비별로 따로 모델을 만드는 방식(13개 모델)과 전체를 하나로 합친 통합 모델을 비교해봤는데, 통합 모델이 더 좋은 성능을 보였습니다(데이터가 적은 설비도 통합 학습의 이득을 봄). 그래서 최종적으로는 설비 구분 없이 하나의 모델을 씁니다.
- 평가는 항상 설비별로 쪼개서 확인: 모델은 하나여도, "그 모델이 설비마다 골고루 잘 맞는지"는 반드시 따로따로 확인했습니다. 그 결과 설비 간 성능 편차가 매우 크다는 게 드러났고(잘 맞는 설비 AUROC 0.9+, 못 맞추는 설비 0.5 이하), 이 세부 내용이 두 번째 첨부 이미지의 핵심입니다.
4. Train/Test는 어떻게 나눴는가
두 가지 방식을 각각 실험했고, 둘 다 랜덤으로 섞어서 나누지 않고 반드시 시간 순서를 지켜서 나눴습니다(미래 정보가 과거 예측에 섞이는 걸 막기 위함, 이를 "leakage 방지"라고 부릅니다).
(1) 고정 분할 (기본 방식)
설비별로 LOT을 시간순 정렬한 뒤, 각 설비 안에서 앞의 70%를 학습(train), 다음 15%를 검증(val), 마지막 15%를 평가(test)로 나눴습니다. 설비마다 자기 자신의 타임라인 안에서 비율로 나누는 방식이라, 설비 간에 기간이 섞이지 않습니다. 이 방식으로 학습한 모델 하나를 계속 재사용해서 평가합니다.
(2) Rolling 재학습 (추가 실험)
고정 분할과 별개로, "실제 서비스에 적용했을 때"를 흉내 내는 방식도 시도했습니다. 전체 기간(2025-07~2026-03)을 시간순으로 놓고,
- 최근 8주치 데이터로 학습
- 그 바로 다음 2주를 평가
- 그리고 학습/평가 구간을 통째로 2주씩 뒤로 밀어서 반복 (총 14회)
이렇게 하면 "지금까지 데이터로 학습해서 앞으로 몇 주를 예측하고, 시간이 지나면 최신 데이터를 더해 다시 학습"하는 실제 운영 상황을 시뮬레이션하게 됩니다. 학습 구간끼리는 서로 겹치지만, 평가 구간은 항상 그 직전 학습 구간보다 미래 시점이라 규칙은 동일하게 지켜집니다.
두 방식 모두 "불량이다/아니다"를 가르는 기준선(threshold)은 고정 분할 실험에서 한 번 정한 값을 그대로 재사용해서, 나눌 때마다 기준이 바뀌는 일이 없도록 통제했습니다.
5. 전체 진행 과정 (어떻게 여기까지 왔는가)
- 출발점: shot(개별 제품) 단위로 예측하니 F1 0.643에서 정체. 같은 조건에서도 절반은 양품/절반은 불량이 나오는 경우가 너무 많아 구조적 한계가 있었습니다.
- 1차 개선: 예측 단위를 LOT(배치)으로 바꾸고, "직전 LOT의 불량률"이라는 힌트(lag 피처)를 추가 → F1 0.756, AUROC 0.785로 개선.
- 2차 개선: "직전 LOT" 대신 "같은 캐비티에서 최근 8시간 이내 있었던 일"이라는 더 정교한 시간 기반 힌트를 추가 → AUROC가 한 단계 더 개선.
- 문제 발견: 그런데 성능 지표 중 F1을 자세히 보니, 이 기간 동안 불량률 자체가 계속 올라서(나중엔 90% 이상이 불량) "무조건 불량이라 찍는" 것과 점수 차이가 거의 없는 착시 현상을 발견했습니다.
- 원인 조사: 불량률 상승이 일직선이 아니라 "잠잠한 시기 → 서서히 불안정해지는 시기 → 짧고 격렬한 급등기 → 진정기"의 4단계였고, 원인은 평균값 변화가 아니라 조건값의 변동성(산포) 확대였다는 걸 확인했습니다. (사내에서 들었다는 "설비 재정비" 얘기는 데이터로 교차 확인했지만 확정할 근거는 못 찾았습니다 — 참고 정도로만 남겨뒀습니다.)
- 중요한 경고 발견: "잠잠한 시기 데이터로 학습한 모델을 격변기에 테스트하면 어떻게 되는가"를 실제로 해봤더니 완전히 무너지는 것을 확인했습니다. 정교한 시간 분할이나 피처 추가만으로는 이 문제가 해결되지 않는다는 것도 확인했습니다.
- 대응: 레짐(4단계)별로 성능을 따로 보고하도록 평가 방식을 바꾸고, 위에서 설명한 rolling 재학습 방식을 도입해 비교했습니다. 또한 "조기경보성 피처"(값이 흔들리면 미리 알려주는 신호)도 시도했지만 전체적으로는 효과가 미미했습니다.
- 설비별 세부 확인(Phase H): 마지막으로 이 모든 결과를 설비별로 쪼개봤더니, 두 번째 첨부 이미지에 담긴 결과가 나왔습니다 — 특정 설비(F02)는 rolling 재학습에서 오히려 1등으로 뒤집혔고, 특정 설비(E07)는 어떤 방식으로도 계속 약했으며, 조기경보 피처는 한 설비(F08)에서만 뚜렷한 효과가 있었습니다.
6. 첨부 이미지 보는 법
16_17_성능요약_시각자료.png (전체 요약, 4분할)
- ① 피처 조합 × 알고리즘별 AUROC 히트맵 — 어떤 조합이 가장 좋았는지
- ② 설비별 AUROC — 설비 간 편차 확인
- ③ 레짐(4단계)별 AUROC와 F1 착시 여부 — 착시가 특정 시기만의 문제가 아니라는 것
- ④ Rolling 재학습 AUROC 추이 — 시간에 따라 성능이 어떻게 움직였는지, 레짐 전환 경계에서 급락하는 지점 표시
17_stepH_설비별_성능비교_시각자료.png (설비별 심화)
- ① 고정 분할 vs Rolling 재학습 AUROC 비교 — 파란 막대(고정) vs 빨간 막대(rolling), F02의 반전과 E07의 지속적 약세를 강조
- ② 조기경보 피처의 설비별 순증 효과 — F08만 확실히 도움이 됐다는 것
7. 정리 및 한계
AUROC 기준으로는 실질적인 개선(0.716 → 0.785 → 0.82 이상)이 있었습니다. 다만 F1은 데이터 자체의 시간적 편중 문제로 신뢰할 수 없어 별도로 걸러야 했고, 설비 간 성능 편차가 커서 "전체적으로 다 잘 됐다"고 말하기보다는 "설비마다 사정이 다르고, 일부(E07 등)는 아직 못 풀었다"는 게 정직한 결론입니다. "설비 재정비" 가설은 확정되지 않은 참고 정보로 남아있어, 실제 정비 이력을 확인하면 다음 단계 설계가 더 명확해질 것입니다.
'내일배움캠프(본캠프)' 카테고리의 다른 글
| [내일배움캠프] 본캠프 7/27 (0) | 2026.07.27 |
|---|---|
| [내일배움캠프] 본캠프 7/24 (1) | 2026.07.24 |
| [내일배움캠프] 본캠프 7/22 (0) | 2026.07.22 |
| [내일배움캠프] 본캠프 7/21 (0) | 2026.07.21 |
| [내일배움캠프] 본캠프 7/20 (1) | 2026.07.20 |