[2024-1 프로젝트] 농산물 가격 변동이 생활물가에 미치는 영향
[2024-1 프로젝트] 농산물 가격 변동이 생활물가에 미치는 영향
농산물 가격 변동이 생활물가에 미치는 영향
[프로젝트 기본]
- Project Title: 농산물 가격 변동이 생활물가에 미치는 영향
- One-line summary: 날씨 데이터(기온·습도·풍속·강수량)만으로 사과·양파·고구마 소매가격을 예측할 수 있는지 검증하여, 비용 효율적인 수급 조절 의사결정을 지원한다.
- Project Type: ML/DL + Statistics (Data Mining/Science)
- My Role / Key Contribution:
- 공공데이터(KAMIS 가격, 농촌진흥청 날씨, 통계청 물가) 수집 및 품종별·지역별 데이터 통합 전처리
- EDA(상관계수 히트맵, 분포 시각화, 카이제곱 독립성 검정)를 통한 날씨-가격 관계 분석
- RandomForest · XGBoost(GridSearchCV) · LSTM(Keras) 모델 구현 및 성능 비교 보조
[TL;DR]
- Problem: 농산물 가격은 변동성이 커 소비자·생산자 모두 불확실성에 노출되어 있다. 다양한 변수를 모두 수집하면 예측 정확도가 높아지지만, 시간·비용이 과도하게 소요된다.
- Approach: 가격 변동의 주요 원인인 날씨 데이터(기온, 습도, 풍속, 강수량)와 물가상승률(inflation)을 핵심 피처로 설정하고, 생산지 날씨와 인근 도매시장 가격을 지역 단위로 매핑하여 Random Forest / XGBoost / LSTM 모델로 일별 소매가격을 예측한다.
- Main Result: 사과 데이터에서 Random Forest가 RMSE 69.40원, R² 0.9997을 기록하며 날씨 피처만으로도 높은 설명력을 보였다 (단, 무작위 분할 평가이므로 과적합 가능성 주의).
- Keywords: 농산물 가격 예측, 날씨 기반 예측, Random Forest, XGBoost, LSTM, 시계열, EDA, 공공데이터
[Motivation & Background]
- Background: 농산물 가격은 기상 이변, 계절성, 수급 불균형에 의해 급격히 변동하며 소비자물가(CPI)에 직접적인 영향을 미친다. 한국의 사과·양파·고구마는 대표적인 가격 변동 고위험 품목이다.
- Why this problem matters: 가격 예측이 가능하면 생산자는 출하 시기를 조절하고, 유통업체는 재고를 관리하며, 정부는 수급 정책을 선제적으로 수립할 수 있다. 특히 저비용 날씨 데이터만으로 예측이 가능하다면 실용성이 크게 높아진다.
- Gap in existing work: 기존 가격 예측 연구는 생산량·재고·수출입 등 다변수를 포함하는 경우가 많아 데이터 수집 비용이 크다. 날씨 단일 요소군(기온·습도·풍속·강수량)의 예측력만을 체계적으로 평가한 사례는 제한적이다.
- Related work:
- KAMIS 농산물 소매가격 공공 API 기반 가격 분석 연구
- 기상청/농촌진흥청 농업 기상 데이터를 활용한 작황 예측 연구
- 시계열 LSTM 모델 기반 식품 가격 예측 (Keras/PyTorch)
- 인플레이션 조정을 통한 실질 가격 트렌드 분석
[Approach]
(ML/DL)
- Model/Architecture:
- Random Forest Regressor (sklearn): 앙상블 결정 트리, 입력: 날씨 4종 + inflation + 지역(one-hot) + year/month/day, 출력: 일별 소매 평균가격(원)
- XGBoost Regressor (GridSearchCV, 5-fold CV): 그래디언트 부스팅, 동일 피처셋, 최적 하이퍼파라미터 탐색
- LSTM v1 (Keras, 2-layer): 순수 날씨 피처(temp/hum/wind/rain/inflation)만 사용, seq_length=7, LSTM(64, relu, return_seq=True)→LSTM(32, relu)→Dense(1), 100 epochs, Adam, 훈련 데이터 R²=0.70
- LSTM v2 (Keras, 2-layer): 전체 피처 사용(inflation + 수원 가격 + 날씨 + year/month/day), seq_length=10, LSTM(50)+Dense(1), 50 epochs, Adam optimizer
- Loss & Optimization:
- RF/XGBoost: MSE 기반 내부 손실
- LSTM: MSE loss, Adam optimizer
- Training strategy / key mechanisms:
- 지역별로 생산지 날씨 ↔ 인근 도매시장 가격을 하나의 DataFrame으로 결합
- 물가상승률로 실질가격 조정(
adjusted_price = 평균 / (inflation/100)) 후 보정 효과 비교 - 지역 컬럼 one-hot encoding, MinMaxScaler 정규화 적용
- XGBoost GridSearchCV:
n_estimators=[100,200,300],lr=[0.01,0.05,0.1],max_depth=[3,5,7],colsample_bytree=[0.7,0.8],subsample=[0.7,0.8]
- Inference/Serving path: 해당 없음 (실험적 분석 목적)
- Ablation/Design choices:
- VIF(분산팽창인수) 계산 후 다중공선성 높은
수원지역가격 컬럼 제거(RF/XGBoost 모델) - EDA에서 기온이 가격과 상관계수 최대 0.32로 가장 높아 핵심 피처로 확인
- VIF(분산팽창인수) 계산 후 다중공선성 높은
(Algorithm/Statistics)
- 카이제곱 독립성 검정(chi2_contingency)으로 날씨 변수와 가격 간 독립성 검정
- 피어슨 상관계수 기반 features간 / 가격-날씨 간 관계 정량화
- 왜도(skewness), 첨도(kurtosis) 산출 및 Q-Q plot으로 가격 분포 정규성 확인
- 물가상승률 조정 실질가격 계산
(Data Mining/Science)
- Problem framing: 시계열 회귀 예측 (일별 농산물 소매가격)
- Feature/Signal design: 생산지 기상 관측값(기온·습도·풍속·강수량) + inflation + 지역 더미 + 날짜 분해(year/month/day)
- Modeling choices: RF(해석 용이), XGBoost(성능 우수), LSTM(시계열 패턴 포착)
- Validation strategy: RF/XGBoost는 random split(80/20), LSTM v2는 temporal split(test=2023년 12월)
- Interpretability & debugging: 상관계수 히트맵, 변수 분포 시각화, 히스토그램, 박스플롯, 바이올린플롯으로 EDA 수행
- Business/Product integration: 가격 예측 결과를 수급 조절·소비자 가이드 등 정책 보조 수단으로 활용 가능
(System/Pipeline)
해당 없음
[Data & Experiment]
- Dataset type: 정형 데이터 (일별 시계열)
- Source:
- 농산물 소매가격: KAMIS 농산물유통정보
- 농업 기상 데이터: 농촌진흥청 농업기상정보
- 소비자물가지수(inflation): 통계청 KOSIS
- Size:
- 가격 데이터: 2014~2024년 (10개년치 CSV), 모델링은 2021~2023년 3개년 사용
- 날씨 데이터: 품종별 주산지 5개 지역 × 3년 = 약 5,475행/품종 (일별)
- 사과(apple) 최종 결합 데이터: 15개 region-year 조합 × ~365행
- Label/Target definition: 일별 농산물 소매 평균가격(원, KAMIS 전국 평균
평균컬럼) - Preprocessing:
- 가격 데이터:
-→ 0 치환, ffill 결측치 보정, transpose 후 컬럼명 재설정,,제거 후 float 변환 - 날씨 데이터: 연도 및 지역별 슬라이싱(365행 단위), date 인덱스 설정
- 피처 선택:
temp,hum,wind,rain,inflation(+ 지역가격, 지역 더미, year/month/day) - 지역 컬럼 one-hot encoding (
pd.get_dummies) - MinMaxScaler(0~1) 정규화 (LSTM 입력용)
- 물가상승률 조정 실질가격 파생변수 생성
수원컬럼 제거 (VIF 기반 다중공선성 처리)
- 가격 데이터:
- Leakage checks: 추가 필요: RF/XGBoost에서 무작위 분할(random_state=42)을 사용했으므로 시간 순서 기반 누수 방지 점검 미완료
- Split:
- RF/XGBoost: 무작위 Train 80% / Test 20% (random_state=42)
- LSTM v2: 2021.01~2023.11 Train / 2023.12 Test (temporal split)
- Evaluation protocol: Hold-out 평가 (교차검증은 XGBoost GridSearchCV에서 5-fold 내부 사용)
- Metrics:
- RMSE (Root Mean Squared Error): 가격 예측 오차를 원(KRW) 단위로 해석 가능
- R² (결정계수): 분산 설명력 측정
- Environment: Google Colab (Python 3.10, GPU 미확인)
- Frameworks/Libraries:
1 2 3 4 5 6 7 8
pandas, numpy, matplotlib, seaborn scikit-learn (RandomForestRegressor, XGBRegressor, MinMaxScaler, GridSearchCV, StandardScaler) xgboost tensorflow / keras (LSTM, Dense, Sequential) torch (PyTorch, LSTM 실험적 사용) scipy.stats (chi2_contingency, linregress, probplot, norm) statsmodels (variance_inflation_factor) holidays
- Reproducibility:
random_state=42고정 사용 (RF, train/test split). LSTM epoch/seed 미고정으로 완전 재현 불보장.
[Results]
아래 수치는 사과(apple) 데이터 기준, 무작위 80/20 분할 평가 결과
| Model | RMSE (원) | R² | 평가 방식 | 비고 |
|---|---|---|---|---|
| Random Forest | 69.40 | 0.9997 | random split 80/20 | random_state=42, default params |
| XGBoost | 106.10 | 0.9993 | random split 80/20 | GridSearchCV 최적 파라미터 (lr=0.01, max_depth=3, n_estimators=100, colsample=0.7, subsample=0.7) |
| LSTM v1 (날씨만) | — | 0.70 (Train) | train-only 평가 | seq=7, 2L-LSTM×[64,32], 100 epochs, 피처: temp/hum/wind/rain/inflation |
| LSTM v2 (전체 피처) | 1773.56 | -24.31 | temporal split (test=2023년 12월) | seq=10, 1L-LSTM×50, 50 epochs, 피처: inflation + 수원 + 날씨 + year/month/day |
⚠️ LSTM v2 해석 주의: R² = -24.31은 예측이 평균값 예측보다도 나쁨을 의미한다. test set이 2023년 12월 데이터 단 31일로 극히 적어 MinMaxScaler의 역변환 과정에서 scaler 범위 불일치(훈련-테스트 간 스케일 차이)가 발생했을 가능성이 높다. RMSE 1773.56원은 실용적 예측 불가 수준.
⚠️ RFRαnd XGBoost의 R²가 0.999대로 매우 높은 것은 무작위 분할로 인한 시간적 data leakage 가능성이 있어 해석에 주의 필요
- EDA 상관계수 요약 (사과):
| 날씨 변수 | 전국 평균가격 상관계수 | 안동 기준 |
|---|---|---|
| 기온(temp) | 0.26 | 0.25 |
| 습도(hum) | 0.10 | 0.13 |
| 풍속(wind) | -0.00 | 0.26 |
| 강수량(rain) | 0.01 | -0.01 |
- 고구마 지역별 기온-가격 상관계수: 영암↔광주 0.32, 여주↔수원 0.28, 당진↔대전 0.07, 익산&고창↔전주 0.25
양파 상관계수 (지역별 날씨-가격):
지역 기온(temp) 습도(hum) 풍속(wind) 강수량(rain) 창원 (양파 창원/합천/함양 산지) -0.28 -0.18 +0.04 -0.08 광주 (양파 무안/함평 산지) -0.26 -0.09 +0.10 -0.08 → 양파는 기온이 높을수록 가격이 하락하는 음의 상관관계(사과와 방향 반대). 풍속만 유일하게 약한 양의 상관.
Statistical significance (카이제곱 독립성 검정, 양파 가격 vs 기온):
지역 χ² 통계량 p-value dof 결론 광주 (OnionG) 11,685.90 2.76e-110 8,450 귀무가설 기각 — 가격과 기온 비독립 창원 (OnionC) 20,777.55 1.85e-155 15,609 귀무가설 기각 — 가격과 기온 비독립 p < 0.001 → 양파 가격과 기온 간의 관계가 통계적으로 유의미함 확인
- Visualization notes:
- 품종별 상관계수 히트맵 (지역별·연도별 15개/품종)
- 가격 분포 히스토그램 및 KDE + 정규분포 곡선 비교
- 연도별/월별 박스플롯 · 바이올린플롯
- 온도/습도/풍속/강수량별 평균가격 산점도 + 회귀직선
- LSTM 학습곡선 및 실제 vs 예측 가격 시계열 그래프
[Discussion]
- Key observations:
- 날씨 변수 중 기온(temp)이 공통적으로 가장 강한 상관성을 보였으며, 사과는 양의 상관(겨울 저온 → 출하 감소 → 가격 상승), 양파는 음의 상관(여름 고온 → 작황 부진 후 재고 소진 패턴)을 나타냈다.
- 고구마는 날씨-가격 상관계수가 비교적 낮아(0.07~0.32) 지역 요인 또는 저장성으로 인한 복잡한 가격 형성 메커니즘이 작용할 가능성이 있다.
- 물가상승률 조정 후에도 가격의 계절적 등락 패턴이 유지되어 날씨가 단순 인플레이션 외의 독립적 가격 요인임을 시사한다.
- RF가 XGBoost보다 낮은 RMSE를 기록했으나, XGBoost의 GridSearchCV 구현 시 파라미터 Prefix 오류(
model__접두어 관련 Warning)가 발생해 하이퍼파라미터가 실제 적용되지 않았을 가능성 있음. - 날씨 데이터 간에도 기온-습도, 기온-풍속 사이에 상당한 상관성이 존재해 다중공선성 문제가 관찰되었다.
- Interpretation: 날씨만으로도 R² 0.999 수준의 설명력이 나온 것은 인상적이나, 시간 순서를 무시한 random split의 특성상 실제 미래 예측 성능과 괴리가 있을 수 있다. Temporal split 기반의 LSTM v2 결과(R²=-24.31)가 이를 뒷받침한다 — temporal split 적용 시 날씨 단일 피처군만으로는 충분하지 않을 수 있음.
- Trade-offs: 날씨 단일 피처군 사용 시 데이터 수집 비용은 낮지만, 공급량·수출입·저장량 등 구조적 변수 누락으로 급격한 외생 충격 예측에는 한계가 있다.
- Failure cases / surprising results:
- 2023년 사과 데이터에서 기온이 아닌 습도와 가격이 강한 상관관계를 보이는 예외적 패턴 발견 (2021~2022년과 상이).
- LSTM v2 temporal split 평가: R² = -24.31, RMSE = 1,773.56원 — 평균값 예측보다도 나쁜 결과. MinMaxScaler를 훈련 데이터(2021~2023.11)로 fit한 후 test(2023.12, 31행)에 적용 시 역변환 범위 불일치로 인한 심각한 오차로 추정.
- LSTM v1은 훈련 데이터 R² = 0.70에 그쳐, 날씨 단일 피처군만으로 LSTM을 학습시키는 것의 한계를 보여줌.
- What I learned:
- 공공 API 데이터는 형식이 연도마다 다를 수 있어 연도별 반복 전처리 로직이 필수적이다.
- 날씨와 가격의 관계는 품종·지역·연도별로 불균일하며 단순 일반화가 어렵다.
- 시계열 데이터에서 random split은 과적합 위험이 있으므로, 반드시 temporal split으로 검증해야 한다.
[Limitations & Future Work]
- Limitations:
- RF/XGBoost 평가에 random split(무작위 80/20) 사용 → 시간 순서 기반 leakage 가능성, 실제 미래 예측 성능 과장 우려
- 모델링에 사용된 기간이 최근 3개년(2021~2023)에 국한 → 이상 기후 연도 포함 여부에 따라 편향 발생 가능
- 양파·고구마에 대한 모델 학습 미완료 (EDA 단계에서 중단) → 품종 간 비교 불가
- LSTM v2의 temporal split 평가 결과 R² = -24.31, RMSE = 1773.56 → MinMaxScaler를 훈련 데이터로만 fit하면서 31일짜리 test set의 가격 범위가 scaler 범위를 벗어나 역변환 오류 발생 가능. 실질적으로 예측 불가 수준.
- 생산량·재고·수출입 등 농산물 수급 변수 미사용 → 외생 충격(이상 기후, 정책 개입) 예측 불가
- Future directions:
- Temporal split(연도별 순차 분할)으로 교체하여 실제 미래 예측 성능 재평가
- 양파·고구마에도 동일 모델 파이프라인 적용하여 품종 간 일반화 가능성 비교
- 생산량, 재고량, 수출입 데이터를 추가 피처로 통합하는 멀티소스 모델 구현
- SARIMA 또는 Prophet 등 통계 기반 시계열 모델과 DL 모델 성능 비교
- 인플레이션(year)과 가격의 시계열 분해 분석(decomposition) 추가
- If I had more time:
- 10개년 전체 데이터를 사용한 장기 시계열 학습 및 검증
- Shap values 기반 feature importance 해석
- 품종별 최적 모델 자동 선택 파이프라인 구현
[Project Structure]
1
2
3
4
5
6
7
농산물 가격 예측/
├── 품종전처리_+_EDA_+_Modeling_합본.ipynb # 전체 파이프라인 (전처리 → EDA → 모델링)
│ ├── [Section 1] 데이터 정제 # KAMIS 가격 + 농촌진흥청 날씨 + 통계청 inflation 로드 및 통합
│ ├── [Section 2] EDA # 상관계수 히트맵, 분포 시각화, 카이제곱 검정 (사과/고구마/양파)
│ └── [Section 3] Modeling # RandomForest / XGBoost(GridSearch) / LSTM(Keras)
├── 농산물가격예측.pdf # 발표 자료
└── README.md
데이터 파일 위치: Google Drive (
/content/drive/MyDrive/DARTB 2024-1/토이프로젝트/data/)
포함 파일:고구마_{year}.csv,사과_{year}.csv,양파_{year}.csv,사과날씨.csv,양파날씨.csv,고구마날씨.csv,물가상승률.csv,apple_data_with_index.csv(중간 저장 파일)
[PDF/Slides Mapping]
- Main slide deck:
농산물가격예측.pdf(버전/날짜 추가 필요:) - Slide-to-README mapping:
- Problem statement slide(s): 추가 필요: (PDF는 ipynb 분석 범위 외 — 직접 열람 필요)
- Method/Architecture slide(s): 추가 필요:
- Experiment setup slide(s): 추가 필요:
- Results/Comparison slide(s): 추가 필요:
- Ablation/Analysis slide(s): 추가 필요:
- Conclusion/Future work slide(s): 추가 필요:
- Numbers provenance (ipynb에서 직접 추출된 수치):
- RF RMSE 69.40 / R² 0.9997 → 노트북 RandomForest 출력 셀
- XGBoost RMSE 106.10 / R² 0.9993 → 노트북 XGBoost 출력 셀
- LSTM v1 Train R² 0.70 → 노트북 Keras LSTM v1 출력 셀 (100 epochs 후)
- LSTM v2 R² -24.31 / RMSE 1773.56 → 노트북 Keras LSTM v2 출력 셀 (temporal split)
- 양파 기온-가격 상관계수 창원 -0.28 / 광주 -0.26 → 노트북 상관계수 출력 셀
- 카이제곱 p-value 광주 2.76e-110 / 창원 1.85e-155 → 노트북 chi2 검정 출력 셀
- Any missing slides / gaps: PDF(
농산물가격예측.pdf) 내용은 ipynb에 포함되지 않아 직접 열람 필요. 발표자료에서 Problem/Method/Conclusion 슬라이드 내용을 확인 후 해당 섹션 보완 권장.
[Citation & License]
- Citation info: 추가 필요: (과제 보고서 형식, 작성자/제출일 확인 필요)
- License: 공공데이터 활용
- KAMIS: 농림축산식품부 공공데이터 (출처 표기 조건)
- 농촌진흥청 농업기상: 공공데이터 포털 조건 준수
- 통계청 KOSIS: 공공데이터 포털 조건 준수
- Papers/links:
- KAMIS 농산물유통정보 : “https://www.kamis.or.kr/customer/price/agricultureRetail/bizcondition/period.do”
- 농촌진흥청 농업기상정보서비스 : “https://weather.rda.go.kr/w/index.do”
- 통계청 KOSIS 소비자물가지수 : “https://kosis.kr/statHtml/statHtml.do?orgId=101&tblId=DT_2KAA601_02&conn_path=I2”
This post is licensed under CC BY 4.0 by the author.