2026 기상청 날씨 빅데이터 콘테스트 · 4인 팀 프로젝트

기상 데이터 기반
송아지 폐사 위험도 예측

150만 행의 기상-축산 데이터를 결합하여 폐사 분류 모델(AUC 0.774)을 개발하고,
전국 17개 시도별 위험도를 인터랙티브 지도로 시각화한 프로젝트

My Role — 대시보드 설계 · 풀스택 개발 · 데이터-시각화 파이프라인 구축 · 배포

라이브 대시보드 보기 내가 한 일 ↓
My Contribution

이 프로젝트에서 내가 한 일

4인 팀에서 웹 개발 및 데이터 시각화 파이프라인 전체를 단독 담당했습니다. 모델 결과를 현장에서 쓸 수 있는 형태로 전달하는 것이 제 역할이었습니다.

100%
대시보드 설계·개발·배포
958줄
단일 HTML 풀스택 코드
17개 시도
GeoJSON 지도 시각화
Python→JSON
데이터 추출 파이프라인

구체적으로 뭘 했는가

1. 데이터 → 시각화 파이프라인

팀원들이 R로 만든 150만 행 모델링 데이터를 Python 스크립트(extract_dashboard_data.py)로 17개 시도별 집계 JSON으로 변환. 계절별 폐사율, 월별 추이, 질병 비율, 기상 통계를 구조화

2. 인터랙티브 대시보드 설계·개발

Leaflet.js + Chart.js + Vanilla JS로 외부 프레임워크 없이 단일 HTML 파일로 구현. Choropleth 지도, 계절/질병 필터, 지역 상세 패널, 반응형 레이아웃까지 직접 설계

3. 배포 및 운영

Cloudflare Pages에 배포하여 무중단 서비스. 팀원 모델 업데이트 시 Python 재실행 → JSON 갱신 → 재배포로 연결되는 워크플로우 구축

4. 발표 지원

발표 당일 라이브 데모를 통해 모델 결과의 실용성을 직접 시연. "모델 → 현장 적용"까지의 전체 흐름을 보여주는 역할 수행

팀 구성

동원 — 모델 설계, 하이퍼파라미터 튜닝, 변수 중요도 분석
서우 — 원시 데이터 정제, 피처 엔지니어링, 논문 근거 조사
세영 — 연구 방향 기획, PPT 설계, EDA 분석
지환 (나) — 대시보드 풀스택 개발, 데이터 파이프라인, 배포

문제 정의: 왜 송아지 폐사인가?

송아지 폐사의 85%가 기상 환경과 관련된 질병(설사·폐렴)에서 비롯되지만, 기존에는 사후 대응만 가능했습니다. 기상 데이터로 사전 예측이 가능한지가 핵심 질문이었습니다.

폐사 원인의 85%

소화기 질환(설사) 65~69% + 호흡기 질환(폐렴) 17~21%.
두 질환 모두 추위, 일교차, 습도 등 기상 조건과 직결

마리당 1,315만 원 손실

한우 평균 도체중 702.5kg 기준, 평균 등급 경매가로 환산 시 최소 387만 ~ 최대 1,781만 원의 기대수익 증발

기상 조건 민감도

송아지는 체온조절 능력이 약해 일교차 10℃+, THI 70+ 환경에서 면역력 저하 → 질병 발생률 급증. 논문 다수에서 확인

핵심 질문

"기상 데이터만으로 송아지 폐사 위험을 사전에 예측할 수 있는가?"
그리고 예측 결과를 현장에서 즉시 활용할 수 있는 형태로 어떻게 전달할 것인가?

Data Pipeline

데이터 수집 및 전처리

4종의 이질적 데이터를 지역-일 단위로 정합하여 모델링 데이터셋을 구축했습니다.

STEP 1

원시 데이터

기상청 ASOS
축산물이력제
농장 메타데이터

STEP 2

전처리

지역-일 집계
결측치 처리
농장-관측소 매핑

STEP 3

피처 엔지니어링

THI 산출
스트레스 지표 생성
3/7일 롤링 통계

STEP 4

변수 선정

3모델 중요도 비교
통합 랭킹 산출
12개 최종 선정

STEP 5

모델 학습

시간 기반 분할
파라미터 튜닝
3모델 비교 평가

데이터 소스

데이터출처내용규모
기상 관측기상청 기상자료개방포털 (data.kma.go.kr)ASOS 일별 기온, 습도, 풍속, 강수량3년 x 95개 관측소
축산 폐사축산물이력제 (aunit.mtrace.go.kr)농장별 일별 폐사 기록202,987두
농장 정보대회 제공 (hanwoo_train.csv)농장 위치, 사육두수, 도체 성적~7,000 농장
지역 축산통계청 KOSIS시도별 연간 한우 사육두수17개 시도 x 3년

파생 변수 (총 30+개)

카테고리변수설명
기온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_sum3일/7일 누적 스트레스·강수
파생high_daily_range, cold_degree큰 일교차 여부, 한랭 강도

데이터가 말해준 것

"폭염이 위험하다"는 초기 가설과 달리, EDA 결과 저온·일교차가 더 위험하다는 반직관적 발견이 모델링 방향을 결정했습니다.

저온이 더 위험하다

고온보다 저온·한랭 스트레스 변수가 폐사율과 더 높은 상관. THI < 45 구간 폐사율 0.0888로 최고 → 폭염 중심 가설을 기각

겨울 > 봄 > 여름 > 가을

계절별 평균 폐사율: 겨울(0.086) > 봄(0.084) > 여름(0.074) > 가을(0.071). 저온 환경에서의 설사 발생이 핵심 원인

일교차 = 1순위 변수

Spearman 상관계수 1위(0.029). 15℃ 이상 구간에서 폐사율 최고. 체온 조절 능력이 약한 송아지에게 급격한 온도 변화가 치명적

사고 과정

처음에는 "여름 폭염 = 위험"이라고 팀 전체가 가정했습니다. 하지만 상관분석과 구간별 폐사율 분석을 해보니 cold_stress, ta_range(일교차), ta_min(최저기온)이 상위를 차지했습니다. 논문을 다시 찾아보니 국립축산과학원 10년 데이터에서도 동일한 패턴이 확인되어, 모델링 방향을 저온/일교차 중심으로 전환했습니다.

분석 시각화

계절별 폐사율
계절별 1,000마리당 평균 폐사 두수
상관계수 순위
기상 변수-폐사율 Spearman 상관계수 순위
일교차별 폐사율
일교차 구간별 평균 폐사율
THI별 폐사율
THI 구간별 평균 폐사율 — 저온 구간이 최고
최저기온별 폐사율
최저기온 구간별 평균 폐사율
습도별 폐사율
평균 습도 구간별 평균 폐사율
Decision Log

주요 의사결정과 근거

프로젝트 진행 중 내린 핵심 판단들과 그 이유를 정리했습니다. "왜 이렇게 했는가"가 결과만큼 중요하다고 생각합니다.

변수 30+개 중 12개만 선정한 이유

의사결정

Logistic/RF/XGBoost 3개 모델의 변수 중요도를 각각 구한 뒤, 2개 이상 모델에서 공통 상위에 오른 변수만 선정. 한 모델에서만 높은 변수는 과적합 위험이 있다고 판단했습니다.

Random Forest를 최종 모델로 선택한 이유

의사결정

XGBoost가 AUC는 0.780으로 더 높았지만, RF가 F1(0.323)과 Accuracy(0.789) 모두 최고였습니다. 불균형 데이터(양성 9.2%)에서는 AUC보다 F1이 실전 성능을 더 잘 반영한다고 판단했습니다. 또한 RF가 Specificity(0.815)도 높아 불필요한 경보(False Positive)를 줄이는 데 유리했습니다.

시간 기반 분할(Time-based Split)을 사용한 이유

의사결정

랜덤 분할은 미래 데이터가 학습에 섞이는 Data Leakage를 유발합니다. 실제 운용 환경을 반영하기 위해 2023~2024 학습 → 2025 테스트로 분할했습니다.

대시보드를 프레임워크 없이 만든 이유

의사결정내 판단

React/Vue를 쓰면 빌드 파이프라인이 필요하고, 팀원들이 수정하기 어려워집니다. 단일 HTML + Vanilla JS로 구현하면 누구나 JSON만 교체하면 데이터를 업데이트할 수 있어, 팀 전체의 효율을 극대화했습니다.

변수 중요도 3모델 비교

로지스틱 중요도
Logistic Regression — Z-score 기준
RF 중요도
Random Forest — Permutation Importance
XGB 중요도
XGBoost — Gain Importance

모델 비교

모델AUCF1AccuracySpecificity선정
Logistic Regression0.7830.2990.7300.752
Random Forest0.7740.3230.7890.815✓ 채택
XGBoost0.7800.3120.7710.800

최종 모델 성능

0.774
AUC-ROC
78.9%
Accuracy
0.323
F1 Score
54.2%
Recall
81.5%
Specificity
ROC Curve
ROC Curve — 3모델 비교 (기상변수 포함 vs 미포함)
Confusion Matrix
최종 Random Forest 혼동 행렬
Metric Compare
모델별 주요 성능 지표 비교
Top Importance
최종 모델 변수 중요도 Top 10

기상 변수를 추가하면 얼마나 좋아지는가?

모델기상변수 없음 (AUC)기상변수 포함 (AUC)향상
Logistic0.7570.783+0.026
Random Forest0.7490.774+0.025
XGBoost0.7560.780+0.024
핵심 결론

모든 모델에서 기상 변수 추가 시 AUC 2~3%p 일관 향상. 기상 데이터가 축산 컨텍스트(계절, 지역, 사육두수) 위에 추가적인 예측력을 가진다는 것을 정량적으로 입증했습니다. 이는 "기상 데이터로 폐사를 예측할 수 있는가?"라는 핵심 질문에 대한 답입니다.

Live Product

내가 만든 대시보드

모델 결과를 "보고서 PDF"가 아니라 누구나 브라우저에서 즉시 탐색할 수 있는 인터랙티브 도구로 만드는 것이 제 역할이었습니다.

전체 화면으로 보기

구현 기능

Choropleth 지도

GeoJSON 기반 17개 시도 경계 렌더링. 위험도 점수에 따라 초록→빨강 색상 스케일 자동 매핑. 마우스 오버 시 지역명, 위험도, 사육두수 툴팁 표시

계절/질병 필터

봄/여름/가을/겨울 계절 전환 + 소화기/호흡기/전체 질병 필터. 필터 변경 시 위험도 점수, 예측 폐사 두수, 색상이 실시간 재계산

지역 상세 패널

지역 클릭 시 슬라이드인 패널 활성화. 기상 정보 4종 + 월별 폐사 추이(Chart.js 라인) + 질병 원인 비율(도넛 차트) 동시 표시

기술적 결정

Vanilla JS 단일 HTML 파일(958줄)로 구현. React 등 프레임워크를 쓰지 않은 이유: (1) 빌드 없이 JSON만 교체하면 데이터 갱신 가능, (2) 팀원 누구나 수정 가능, (3) Cloudflare Pages에 정적 파일 하나만 배포하면 되어 인프라 비용 0원. 단점은 코드가 길어지면 유지보수가 어려워진다는 것이나, 이 규모에서는 충분히 관리 가능했습니다.

이 모델이 현장에 적용되면?

단순히 AUC 수치를 보여주는 것이 아니라, 실제로 어떤 가치를 만들 수 있는지를 계산했습니다.

202,987두
3년간 전국 폐사 두수
1,315만 원
마리당 평균 손실
~8,900억 원
3년 총 경제적 손실 추정
시나리오 추산

모델의 Recall이 54.2%이므로, 위험 경보를 받은 농가가 선제 조치(보온, 환기, 백신)를 통해 경보 대상 중 10%의 폐사만 예방해도:
연간 약 36억 원(= 67,662두/년 x 54.2% x 10% x 1,315만 원)의 손실 절감 효과.

기상청 SSP2-4.5 시나리오(2050년) 적용 시 기온 상승으로 일교차·한랭 스트레스 패턴이 변화하며, 사전 경보 시스템의 가치는 더 커질 것으로 예상됩니다.

Challenges & Limitations

한계점과 시행착오

잘 된 것만 보여주는 포트폴리오보다, 어디서 막혔고 어떻게 판단했는지가 더 중요하다고 생각합니다.

F1 Score가 0.32로 낮은 이유

한계

양성 비율이 9.2%인 극도의 불균형 데이터. 폐사는 "매일 일어나지 않는 희귀 사건"이기 때문에 Precision-Recall 트레이드오프에서 F1이 낮아질 수밖에 없습니다. 단, AUC 0.774와 Specificity 81.5%는 경보 시스템으로서 충분히 의미 있는 수준입니다.

개선 가능성: 오버샘플링 미적용

한계개선 방향

SMOTE나 Borderline-SMOTE를 적용하면 Recall을 높일 수 있지만, 시간 기반 분할 환경에서 합성 데이터가 미래 패턴을 오염시킬 위험이 있어 보수적으로 미적용. 향후 시계열 인식 오버샘플링(예: 같은 계절 내에서만 합성) 방법을 시도할 수 있습니다.

GeoJSON 매칭 문제

시행착오해결

대시보드 개발 시 시도명이 GeoJSON("충청남도")과 데이터("충남")에서 달라 지도가 안 그려지는 문제 발생. 시도 코드 → 정식 명칭 매핑 테이블을 만들어 해결. 데이터 결합 시 키 불일치는 흔한 문제지만, 실수하면 "데이터는 있는데 지도에 안 보이는" 치명적 버그가 됩니다.

시계열 모델 미시도

한계향후 과제

현재는 당일 기상 데이터만 사용하는 정적 분류 모델. LSTM이나 Temporal Fusion Transformer로 시계열 패턴(연속 한파 3일차 등)을 학습하면 성능 향상 가능. 또한 lag 변수(1/3일 전 기상)는 이미 생성해두었으므로 확장이 용이합니다.

기술 스택

내가 사용한 기술 (대시보드 & 파이프라인)

HTML / CSS / JavaScript
Leaflet.js
Chart.js
GeoJSON
Python
Cloudflare Pages

팀에서 사용한 기술 (분석 & 모델링)

R / RStudio
tidyverse
ranger (Random Forest)
xgboost
glmnet
caret
pROC
ggplot2

코드 구조

# 프로젝트 파일 구조 mining_contest/ +-- 00_weather_mortality_utils.R # 공통 유틸리티 (전처리, 변수 정의) +-- 01_weather_evidence_eda.R # 탐색적 데이터 분석 +-- 02_weather_variable_importance.R # 3모델 변수 중요도 비교 +-- 03_weather_prediction_models.R # 모델 학습, 튜닝, 평가 +-- 04_weather_model_evaluation_plots.R # 결과 시각화 +-- extract_dashboard_data.py # R 결과 -> 대시보드 JSON 변환 (내가 작성) +-- calf-mortality-map.html # 대시보드 전체 코드 958줄 (내가 작성) +-- processed/ # 전처리된 CSV (10개) +-- models/ # 학습된 모델 .rds (10개) +-- tables/ # 결과 테이블 CSV (33개) +-- figures/ # 시각화 PNG (25+개)
Lessons Learned

이 프로젝트에서 배운 것

데이터 ≠ 모델이 전부가 아니다

아무리 좋은 모델이라도 현장에서 쓸 수 없으면 의미 없습니다. 모델 결과를 "비전문가도 이해할 수 있는 시각화"로 바꾸는 과정이 프로젝트의 실질적 가치를 만들었습니다.

가설을 데이터로 검증하는 습관

"폭염이 위험하다"는 직관을 EDA가 뒤집었습니다. 도메인 지식은 중요하지만, 데이터가 반대를 말하면 가설을 수정할 수 있어야 합니다.

팀 프로젝트에서의 인터페이스 설계

R을 쓰는 팀원과 JS를 쓰는 제가 JSON이라는 "계약"을 정해두니 서로 독립적으로 작업할 수 있었습니다. 좋은 인터페이스가 팀 생산성을 결정합니다.

참고문헌 및 데이터 출처

김의형 외 (2015). "대규모 한우 번식 목장에서의 10년간 송아지 폐사 원인". 대한수의학회지.

류일선. "겨울철에 발생하기 쉬운 송아지 설사병의 예방 및 관리요령". 국립축산과학원.

홀스타인 입식 송아지 폐사 원인에 대한 조사 (2024). KCI.

문진산. "송아지 호흡기 질병의 예방 및 치료방법". 한우자조금관리위원회.

권두중. "한우 사육 시설 및 환경관리". 국립축산과학원 축산환경과.

기상청 기상자료개방포털 — data.kma.go.kr  |  날씨 빅데이터 콘테스트 — bd.kma.go.kr/contest