150만 행의 기상-축산 데이터를 결합하여 폐사 분류 모델(AUC 0.774)을 개발하고,
전국 17개 시도별 위험도를 인터랙티브 지도로 시각화한 프로젝트
My Role — 대시보드 설계 · 풀스택 개발 · 데이터-시각화 파이프라인 구축 · 배포
4인 팀에서 웹 개발 및 데이터 시각화 파이프라인 전체를 단독 담당했습니다. 모델 결과를 현장에서 쓸 수 있는 형태로 전달하는 것이 제 역할이었습니다.
팀원들이 R로 만든 150만 행 모델링 데이터를 Python 스크립트(extract_dashboard_data.py)로 17개 시도별 집계 JSON으로 변환. 계절별 폐사율, 월별 추이, 질병 비율, 기상 통계를 구조화
Leaflet.js + Chart.js + Vanilla JS로 외부 프레임워크 없이 단일 HTML 파일로 구현. Choropleth 지도, 계절/질병 필터, 지역 상세 패널, 반응형 레이아웃까지 직접 설계
Cloudflare Pages에 배포하여 무중단 서비스. 팀원 모델 업데이트 시 Python 재실행 → JSON 갱신 → 재배포로 연결되는 워크플로우 구축
발표 당일 라이브 데모를 통해 모델 결과의 실용성을 직접 시연. "모델 → 현장 적용"까지의 전체 흐름을 보여주는 역할 수행
동원 — 모델 설계, 하이퍼파라미터 튜닝, 변수 중요도 분석
서우 — 원시 데이터 정제, 피처 엔지니어링, 논문 근거 조사
세영 — 연구 방향 기획, PPT 설계, EDA 분석
지환 (나) — 대시보드 풀스택 개발, 데이터 파이프라인, 배포
송아지 폐사의 85%가 기상 환경과 관련된 질병(설사·폐렴)에서 비롯되지만, 기존에는 사후 대응만 가능했습니다. 기상 데이터로 사전 예측이 가능한지가 핵심 질문이었습니다.
소화기 질환(설사) 65~69% + 호흡기 질환(폐렴) 17~21%.
두 질환 모두 추위, 일교차, 습도 등 기상 조건과 직결
한우 평균 도체중 702.5kg 기준, 평균 등급 경매가로 환산 시 최소 387만 ~ 최대 1,781만 원의 기대수익 증발
송아지는 체온조절 능력이 약해 일교차 10℃+, THI 70+ 환경에서 면역력 저하 → 질병 발생률 급증. 논문 다수에서 확인
"기상 데이터만으로 송아지 폐사 위험을 사전에 예측할 수 있는가?"
그리고 예측 결과를 현장에서 즉시 활용할 수 있는 형태로 어떻게 전달할 것인가?
4종의 이질적 데이터를 지역-일 단위로 정합하여 모델링 데이터셋을 구축했습니다.
기상청 ASOS
축산물이력제
농장 메타데이터
지역-일 집계
결측치 처리
농장-관측소 매핑
THI 산출
스트레스 지표 생성
3/7일 롤링 통계
3모델 중요도 비교
통합 랭킹 산출
12개 최종 선정
시간 기반 분할
파라미터 튜닝
3모델 비교 평가
| 데이터 | 출처 | 내용 | 규모 |
|---|---|---|---|
| 기상 관측 | 기상청 기상자료개방포털 (data.kma.go.kr) | ASOS 일별 기온, 습도, 풍속, 강수량 | 3년 x 95개 관측소 |
| 축산 폐사 | 축산물이력제 (aunit.mtrace.go.kr) | 농장별 일별 폐사 기록 | 202,987두 |
| 농장 정보 | 대회 제공 (hanwoo_train.csv) | 농장 위치, 사육두수, 도체 성적 | ~7,000 농장 |
| 지역 축산 | 통계청 KOSIS | 시도별 연간 한우 사육두수 | 17개 시도 x 3년 |
| 카테고리 | 변수 | 설명 |
|---|---|---|
| 기온 | ta_max, ta_min, ta_mean, ta_range | 최고/최저/평균 기온, 일교차 |
| 복합지수 | thi | 온습도지수 (Temperature-Humidity Index) |
| 환경 | rhm_avg, ws_davg, rn_day | 평균 습도, 평균 풍속, 일강수량 |
| 스트레스 | cold_stress, heat_stress, severe_* | 한랭/고온 스트레스 이진 지표 |
| 누적 | *_roll3_sum, *_roll7_sum | 3일/7일 누적 스트레스·강수 |
| 파생 | high_daily_range, cold_degree | 큰 일교차 여부, 한랭 강도 |
"폭염이 위험하다"는 초기 가설과 달리, EDA 결과 저온·일교차가 더 위험하다는 반직관적 발견이 모델링 방향을 결정했습니다.
고온보다 저온·한랭 스트레스 변수가 폐사율과 더 높은 상관. THI < 45 구간 폐사율 0.0888로 최고 → 폭염 중심 가설을 기각
계절별 평균 폐사율: 겨울(0.086) > 봄(0.084) > 여름(0.074) > 가을(0.071). 저온 환경에서의 설사 발생이 핵심 원인
Spearman 상관계수 1위(0.029). 15℃ 이상 구간에서 폐사율 최고. 체온 조절 능력이 약한 송아지에게 급격한 온도 변화가 치명적
처음에는 "여름 폭염 = 위험"이라고 팀 전체가 가정했습니다. 하지만 상관분석과 구간별 폐사율 분석을 해보니 cold_stress, ta_range(일교차), ta_min(최저기온)이 상위를 차지했습니다. 논문을 다시 찾아보니 국립축산과학원 10년 데이터에서도 동일한 패턴이 확인되어, 모델링 방향을 저온/일교차 중심으로 전환했습니다.
프로젝트 진행 중 내린 핵심 판단들과 그 이유를 정리했습니다. "왜 이렇게 했는가"가 결과만큼 중요하다고 생각합니다.
Logistic/RF/XGBoost 3개 모델의 변수 중요도를 각각 구한 뒤, 2개 이상 모델에서 공통 상위에 오른 변수만 선정. 한 모델에서만 높은 변수는 과적합 위험이 있다고 판단했습니다.
XGBoost가 AUC는 0.780으로 더 높았지만, RF가 F1(0.323)과 Accuracy(0.789) 모두 최고였습니다. 불균형 데이터(양성 9.2%)에서는 AUC보다 F1이 실전 성능을 더 잘 반영한다고 판단했습니다. 또한 RF가 Specificity(0.815)도 높아 불필요한 경보(False Positive)를 줄이는 데 유리했습니다.
랜덤 분할은 미래 데이터가 학습에 섞이는 Data Leakage를 유발합니다. 실제 운용 환경을 반영하기 위해 2023~2024 학습 → 2025 테스트로 분할했습니다.
React/Vue를 쓰면 빌드 파이프라인이 필요하고, 팀원들이 수정하기 어려워집니다. 단일 HTML + Vanilla JS로 구현하면 누구나 JSON만 교체하면 데이터를 업데이트할 수 있어, 팀 전체의 효율을 극대화했습니다.
| 모델 | AUC | F1 | Accuracy | Specificity | 선정 |
|---|---|---|---|---|---|
| Logistic Regression | 0.783 | 0.299 | 0.730 | 0.752 | |
| Random Forest | 0.774 | 0.323 | 0.789 | 0.815 | ✓ 채택 |
| XGBoost | 0.780 | 0.312 | 0.771 | 0.800 |
| 모델 | 기상변수 없음 (AUC) | 기상변수 포함 (AUC) | 향상 |
|---|---|---|---|
| Logistic | 0.757 | 0.783 | +0.026 |
| Random Forest | 0.749 | 0.774 | +0.025 |
| XGBoost | 0.756 | 0.780 | +0.024 |
모든 모델에서 기상 변수 추가 시 AUC 2~3%p 일관 향상. 기상 데이터가 축산 컨텍스트(계절, 지역, 사육두수) 위에 추가적인 예측력을 가진다는 것을 정량적으로 입증했습니다. 이는 "기상 데이터로 폐사를 예측할 수 있는가?"라는 핵심 질문에 대한 답입니다.
모델 결과를 "보고서 PDF"가 아니라 누구나 브라우저에서 즉시 탐색할 수 있는 인터랙티브 도구로 만드는 것이 제 역할이었습니다.
GeoJSON 기반 17개 시도 경계 렌더링. 위험도 점수에 따라 초록→빨강 색상 스케일 자동 매핑. 마우스 오버 시 지역명, 위험도, 사육두수 툴팁 표시
봄/여름/가을/겨울 계절 전환 + 소화기/호흡기/전체 질병 필터. 필터 변경 시 위험도 점수, 예측 폐사 두수, 색상이 실시간 재계산
지역 클릭 시 슬라이드인 패널 활성화. 기상 정보 4종 + 월별 폐사 추이(Chart.js 라인) + 질병 원인 비율(도넛 차트) 동시 표시
Vanilla JS 단일 HTML 파일(958줄)로 구현. React 등 프레임워크를 쓰지 않은 이유: (1) 빌드 없이 JSON만 교체하면 데이터 갱신 가능, (2) 팀원 누구나 수정 가능, (3) Cloudflare Pages에 정적 파일 하나만 배포하면 되어 인프라 비용 0원. 단점은 코드가 길어지면 유지보수가 어려워진다는 것이나, 이 규모에서는 충분히 관리 가능했습니다.
단순히 AUC 수치를 보여주는 것이 아니라, 실제로 어떤 가치를 만들 수 있는지를 계산했습니다.
모델의 Recall이 54.2%이므로, 위험 경보를 받은 농가가 선제 조치(보온, 환기, 백신)를 통해
경보 대상 중 10%의 폐사만 예방해도:
연간 약 36억 원(= 67,662두/년 x 54.2% x 10% x 1,315만 원)의 손실 절감 효과.
기상청 SSP2-4.5 시나리오(2050년) 적용 시 기온 상승으로 일교차·한랭 스트레스 패턴이 변화하며,
사전 경보 시스템의 가치는 더 커질 것으로 예상됩니다.
잘 된 것만 보여주는 포트폴리오보다, 어디서 막혔고 어떻게 판단했는지가 더 중요하다고 생각합니다.
양성 비율이 9.2%인 극도의 불균형 데이터. 폐사는 "매일 일어나지 않는 희귀 사건"이기 때문에 Precision-Recall 트레이드오프에서 F1이 낮아질 수밖에 없습니다. 단, AUC 0.774와 Specificity 81.5%는 경보 시스템으로서 충분히 의미 있는 수준입니다.
SMOTE나 Borderline-SMOTE를 적용하면 Recall을 높일 수 있지만, 시간 기반 분할 환경에서 합성 데이터가 미래 패턴을 오염시킬 위험이 있어 보수적으로 미적용. 향후 시계열 인식 오버샘플링(예: 같은 계절 내에서만 합성) 방법을 시도할 수 있습니다.
대시보드 개발 시 시도명이 GeoJSON("충청남도")과 데이터("충남")에서 달라 지도가 안 그려지는 문제 발생. 시도 코드 → 정식 명칭 매핑 테이블을 만들어 해결. 데이터 결합 시 키 불일치는 흔한 문제지만, 실수하면 "데이터는 있는데 지도에 안 보이는" 치명적 버그가 됩니다.
현재는 당일 기상 데이터만 사용하는 정적 분류 모델. LSTM이나 Temporal Fusion Transformer로 시계열 패턴(연속 한파 3일차 등)을 학습하면 성능 향상 가능. 또한 lag 변수(1/3일 전 기상)는 이미 생성해두었으므로 확장이 용이합니다.
아무리 좋은 모델이라도 현장에서 쓸 수 없으면 의미 없습니다. 모델 결과를 "비전문가도 이해할 수 있는 시각화"로 바꾸는 과정이 프로젝트의 실질적 가치를 만들었습니다.
"폭염이 위험하다"는 직관을 EDA가 뒤집었습니다. 도메인 지식은 중요하지만, 데이터가 반대를 말하면 가설을 수정할 수 있어야 합니다.
R을 쓰는 팀원과 JS를 쓰는 제가 JSON이라는 "계약"을 정해두니 서로 독립적으로 작업할 수 있었습니다. 좋은 인터페이스가 팀 생산성을 결정합니다.
김의형 외 (2015). "대규모 한우 번식 목장에서의 10년간 송아지 폐사 원인". 대한수의학회지.
류일선. "겨울철에 발생하기 쉬운 송아지 설사병의 예방 및 관리요령". 국립축산과학원.
홀스타인 입식 송아지 폐사 원인에 대한 조사 (2024). KCI.
문진산. "송아지 호흡기 질병의 예방 및 치료방법". 한우자조금관리위원회.
권두중. "한우 사육 시설 및 환경관리". 국립축산과학원 축산환경과.
기상청 기상자료개방포털 — data.kma.go.kr | 날씨 빅데이터 콘테스트 — bd.kma.go.kr/contest