클립보드에 복사되었습니다
Post

[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로 가장 높아 핵심 피처로 확인

(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:
  • Size:
    • 가격 데이터: 2014~2024년 (10개년치 CSV), 모델링은 2021~2023년 3개년 사용
    • 날씨 데이터: 품종별 주산지 5개 지역 × 3년 = 약 5,475행/품종 (일별)
    • 사과(apple) 최종 결합 데이터: 15개 region-year 조합 × ~365행
  • Label/Target definition: 일별 농산물 소매 평균가격(원, KAMIS 전국 평균 평균 컬럼)
  • Preprocessing:
    1. 가격 데이터: - → 0 치환, ffill 결측치 보정, transpose 후 컬럼명 재설정, , 제거 후 float 변환
    2. 날씨 데이터: 연도 및 지역별 슬라이싱(365행 단위), date 인덱스 설정
    3. 피처 선택: temp, hum, wind, rain, inflation (+ 지역가격, 지역 더미, year/month/day)
    4. 지역 컬럼 one-hot encoding (pd.get_dummies)
    5. MinMaxScaler(0~1) 정규화 (LSTM 입력용)
    6. 물가상승률 조정 실질가격 파생변수 생성
    7. 수원 컬럼 제거 (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 분할 평가 결과

ModelRMSE (원)평가 방식비고
Random Forest69.400.9997random split 80/20random_state=42, default params
XGBoost106.100.9993random split 80/20GridSearchCV 최적 파라미터 (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.31temporal 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.260.25
습도(hum)0.100.13
풍속(wind)-0.000.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-valuedof결론
    광주 (OnionG)11,685.902.76e-1108,450귀무가설 기각 — 가격과 기온 비독립
    창원 (OnionC)20,777.551.85e-15515,609귀무가설 기각 — 가격과 기온 비독립

    p < 0.001 → 양파 가격과 기온 간의 관계가 통계적으로 유의미함 확인

  • Visualization notes:
    • 품종별 상관계수 히트맵 (지역별·연도별 15개/품종)
    • 가격 분포 히스토그램 및 KDE + 정규분포 곡선 비교
    • 연도별/월별 박스플롯 · 바이올린플롯
    • 온도/습도/풍속/강수량별 평균가격 산점도 + 회귀직선
    • LSTM 학습곡선 및 실제 vs 예측 가격 시계열 그래프

[Discussion]

  • Key observations:
    1. 날씨 변수 중 기온(temp)이 공통적으로 가장 강한 상관성을 보였으며, 사과는 양의 상관(겨울 저온 → 출하 감소 → 가격 상승), 양파는 음의 상관(여름 고온 → 작황 부진 후 재고 소진 패턴)을 나타냈다.
    2. 고구마는 날씨-가격 상관계수가 비교적 낮아(0.07~0.32) 지역 요인 또는 저장성으로 인한 복잡한 가격 형성 메커니즘이 작용할 가능성이 있다.
    3. 물가상승률 조정 후에도 가격의 계절적 등락 패턴이 유지되어 날씨가 단순 인플레이션 외의 독립적 가격 요인임을 시사한다.
    4. RF가 XGBoost보다 낮은 RMSE를 기록했으나, XGBoost의 GridSearchCV 구현 시 파라미터 Prefix 오류(model__ 접두어 관련 Warning)가 발생해 하이퍼파라미터가 실제 적용되지 않았을 가능성 있음.
    5. 날씨 데이터 간에도 기온-습도, 기온-풍속 사이에 상당한 상관성이 존재해 다중공선성 문제가 관찰되었다.
  • 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:
    1. 공공 API 데이터는 형식이 연도마다 다를 수 있어 연도별 반복 전처리 로직이 필수적이다.
    2. 날씨와 가격의 관계는 품종·지역·연도별로 불균일하며 단순 일반화가 어렵다.
    3. 시계열 데이터에서 random split은 과적합 위험이 있으므로, 반드시 temporal split으로 검증해야 한다.

[Limitations & Future Work]

  • Limitations:
    1. RF/XGBoost 평가에 random split(무작위 80/20) 사용 → 시간 순서 기반 leakage 가능성, 실제 미래 예측 성능 과장 우려
    2. 모델링에 사용된 기간이 최근 3개년(2021~2023)에 국한 → 이상 기후 연도 포함 여부에 따라 편향 발생 가능
    3. 양파·고구마에 대한 모델 학습 미완료 (EDA 단계에서 중단) → 품종 간 비교 불가
    4. LSTM v2의 temporal split 평가 결과 R² = -24.31, RMSE = 1773.56 → MinMaxScaler를 훈련 데이터로만 fit하면서 31일짜리 test set의 가격 범위가 scaler 범위를 벗어나 역변환 오류 발생 가능. 실질적으로 예측 불가 수준.
    5. 생산량·재고·수출입 등 농산물 수급 변수 미사용 → 외생 충격(이상 기후, 정책 개입) 예측 불가
  • Future directions:
    1. Temporal split(연도별 순차 분할)으로 교체하여 실제 미래 예측 성능 재평가
    2. 양파·고구마에도 동일 모델 파이프라인 적용하여 품종 간 일반화 가능성 비교
    3. 생산량, 재고량, 수출입 데이터를 추가 피처로 통합하는 멀티소스 모델 구현
    4. SARIMA 또는 Prophet 등 통계 기반 시계열 모델과 DL 모델 성능 비교
    5. 인플레이션(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.