LabHub
배우기 러닝패스 코스

先週のモデルの方が良かった。誰も見つけられない

同じ名前のCSVが昨日と違う

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

학습 데이터에 지문을 찍어 버전으로 삼고, 무엇이 정상인지를 선언한 계약으로 새 수집분을 검사하고, 학습·평가 분할이 겹쳤을 때 지표가 실제로 얼마나 움직이는지를 재 봅니다.

왜 중요한가

재현이 깨지는 자리는 대개 코드가 아니라 데이터입니다. train.csv 라는 이름은 그대로인데 안의 행이 바뀌어도 아무 경고가 없고, 지표만 조금 달라집니다. 그래서 데이터에는 이름이 아니라 내용의 해시를 버전으로 붙이고, 정상 범위를 미리 선언해 두었다가 새로 들어온 수집분을 기계로 대 봅니다. 계약을 어긴 행을 조용히 버리지 않고 격리해 두는 것도 같은 이유입니다 — 조용히 줄어든 표본은 몇 달 뒤 "왜 성능이 떨어졌지" 로 돌아옵니다. 마지막 두 단계는 흔한 오해 하나를 실측으로 깹니다. 누수가 있으면 지표가 눈에 띄게 오를 것 같지만, 기억력이 약한 모델에서는 거의 움직이지 않습니다.

단계

  1. 세 분할의 지문(해시·크기·행 수·머리글)을 뜹니다.
  2. 업무 규칙으로 데이터 계약을 선언하고 학습 데이터가 그 안에 드는지 확인합니다.
  3. 새 수집분을 계약에 대 보고 위반을 목록으로 만듭니다.
  4. 위반 행을 격리하고 학습에 쓸 행만 따로 남깁니다.
  5. 망가진 분할에서 겹치는 고객을 찾아냅니다.
  6. 겹침을 걷어 내고 두 번 학습시켜 지표 차이를 잽니다.
  7. 지금까지의 사실과 한계를 데이터 카드로 묶습니다.

참고

같은 이름의 파일이 같은 파일인지 확인한다

/root/datacontract/dataset.json 에 files 객체를 만들고 train.csv·valid.csv·test.csv 각각에 대해 sha256·bytes·rows(머리글을 뺀 데이터 행 수)·columns(머리글 목록)를 저장하세요. 재료는 /opt/fixtures/mlops 아래에 있습니다.

파일 이름은 버전이 아닙니다. 내용의 해시가 버전입니다. 행 수는 csv 모듈로 머리글을 건너뛴 뒤 세세요.

무엇이 정상인지 선언한다

/root/datacontract/contract.json 에 source·source_sha256·row_count·required·ranges·observed 를 저장하세요. source 는 /opt/fixtures/mlops/train.csv, required 는 머리글에 적힌 순서 그대로의 열 이름 목록, ranges 는 업무 규칙(tenure_months 0..120, monthly_fee 0..200, support_tickets 0..20, late_payments 0..12, usage_hours 0..400, churn 0..1)을 [최소, 최대] 로 적은 것, observed 는 train.csv 에서 실제로 관찰되는 [최소, 최대] 입니다.

계약은 데이터에서 추론하는 것이 아니라 업무에서 선언하는 것입니다. 다만 학습 데이터가 그 선언 안에 드는지는 반드시 확인해야 합니다.

새로 들어온 수집분을 계약에 대 본다

/opt/fixtures/mlops/week2.csv 를 /root/datacontract/contract.json 으로 검사해 /root/datacontract/validation.json 에 source·total_rows·violations·violation_count·passed 를 저장하세요. violations 의 각 항목은 row(머리글을 뺀 1부터의 행 번호)·column·rule 세 키만 가지며, rule 은 빈 값이면 required, 숫자로 읽히지 않으면 type, 범위를 벗어나면 range 입니다. 정렬은 행 번호 오름차순, 같은 행 안에서는 파일에 적힌 열 순서입니다.

검사 규칙을 코드 한 곳에 모아 두면 다음 주 수집분에도 그대로 돌릴 수 있습니다. 빈 문자열과 0 을 같은 것으로 다루지 않도록 조심하세요.

버린 행도 남긴다

계약을 어긴 행이 하나라도 있는 행은 /root/datacontract/quarantine.csv 로, 나머지는 /root/datacontract/clean_week2.csv 로 나눠 저장하세요. 두 파일 모두 원본과 같은 머리글을 첫 줄에 두고 원본 순서를 유지합니다.

조용히 버린 행은 다음 달에 '데이터가 왜 줄었지' 로 돌아옵니다. 격리 파일이 있으면 무엇을 왜 버렸는지 나중에 다시 볼 수 있습니다.

분할이 겹쳤는지 구조로 확인한다

/opt/fixtures/mlops/bad_train.csv 와 /opt/fixtures/mlops/bad_valid.csv 의 customer_id 를 비교해 /root/datacontract/leakage.json 에 train·valid(두 파일 경로)·overlap_count·overlap_ratio(겹친 수 ÷ 평가 행 수, 소수점 넷째 자리 반올림)·overlapping_ids(사전순 앞 5개)·split_valid 를 저장하세요.

겹침은 행이 아니라 개체로 셉니다. 같은 고객이 양쪽에 있으면 그 고객에 대해서는 모델이 답을 이미 본 셈입니다.

누수를 걷어 내고 지표가 얼마나 움직이는지 잰다

/opt/fixtures/mlops/bad_valid.csv 에서 학습 쪽 고객을 뺀 행만 남겨 /root/datacontract/fixed_valid.csv 를 만드세요(머리글과 순서 유지). 그다음 bad_train.csv 로 lr 0.1, epochs 40, seed 7 을 두 번 학습시켜 /root/datacontract/split_effect.json 에 leaky_accuracy(bad_valid.csv 로 잰 값)·clean_accuracy(fixed_valid.csv 로 잰 값)·delta(clean − leaky, 소수점 넷째 자리 반올림)·threshold(0.05)·visible_in_metric(|delta| 가 threshold 이상인가)을 저장하세요.

결과를 예상해 보고 재세요. 예상과 다르면 그 차이가 이 단계에서 배울 것입니다.

이 데이터로 무엇을 말할 수 있는지 적는다

/root/datacontract/datacard.json 에 train_sha256·contract_sha256(/root/datacontract/contract.json 의 해시)·clean_week2_sha256·violation_count·leakage_overlap_count·approved_for_training·limitations(40자 이상)을 저장하세요. 앞 단계의 산출물에서 값을 가져와 맞춥니다.

데이터 카드는 자랑이 아니라 한계를 적는 곳입니다. 합성 데이터로 말할 수 없는 것을 적어 두면 다음 사람이 잘못 쓰지 않습니다.