콘텐츠로 이동
Data Prep
상세

농업/AgTech 데이터 분석

스마트팜과 정밀농업 시대의 데이터 분석 가이드. 기상, 토양, 위성, IoT 센서 데이터를 활용한 수확량 예측, 병충해 탐지, 관개 최적화 등 농업 전반의 데이터 기반 의사결정을 다룬다.


개요

정밀농업(Precision Agriculture)은 데이터를 기반으로 농업 투입물(물, 비료, 농약)을 최적화하고 수확량을 극대화하는 접근이다. 센서, 위성, 드론 기술의 발전으로 농업 데이터의 양과 질이 급격히 향상되었다.

농업 데이터 분석의 가치

영역 기존 방식 데이터 기반 방식 개선 효과
관개 일정 기반 살수 토양 수분 센서 기반 물 사용량 20-30% 절감
비료 균일 살포 구역별 가변 살포 비료 15-20% 절감
병충해 예방 살포 조기 탐지 후 선택적 처리 농약 30-50% 절감
수확 경험 기반 시기 결정 예측 모델 기반 최적 시기 수확량 5-15% 증가
가격 시장 관행 시계열 예측 기반 출하 전략 수익 10-20% 증가

핵심 데이터 소스

데이터 유형별 정리

데이터 유형 소스 수집 주기 형식 활용
기상 기상청 API, 자체 기상대 시간별 시계열 수확량 예측, 병충해
토양 IoT 센서, 정밀 토양 분석 분 단위 / 연 1회 센서값, 성분표 관개, 비료
위성 영상 Sentinel-2, Landsat 5-16일 GeoTIFF NDVI, 생육 모니터링
드론 영상 RGB, 멀티스펙트럴 주 1회 정사영상 병충해, 생육 상태
생육 데이터 수동 조사, 카메라 주 1회 정형 성장 단계, 수확 시기
시장 데이터 aT, KAMIS 일별 시계열 가격 예측, 출하 전략

NDVI (Normalized Difference Vegetation Index)

식생의 건강 상태를 나타내는 핵심 지표:

NDVI = (NIR - Red) / (NIR + Red)

값 범위:
  -1.0 ~ 0.0  : 물, 구름, 눈
   0.0 ~ 0.2  : 나지, 건물
   0.2 ~ 0.4  : 초기 생육 / 수확 후
   0.4 ~ 0.6  : 중간 생육
   0.6 ~ 0.9  : 건강한 식생 (최성기)

한국 농업 공공데이터

데이터 제공처 접근 방법 내용
농업관측데이터 한국농촌경제연구원 API 작물별 재배면적, 생산량
농산물유통정보 aT (KAMIS) API 일별 도매/소매 가격
기상관측 기상청 API 기온, 강수, 일사량
토양환경정보 농촌진흥청 웹 다운로드 토양 성분, pH, 유기물
병충해 발생정보 농촌진흥청 API 병충해 발생 현황
농업경영체 등록 농림축산식품부 공공데이터포털 경작 면적, 작물
통계 KOSIS API/웹 농업 총조사, 생산비

분석 영역별 가이드

1. 수확량 예측

작물별 수확량을 예측하여 생산 계획과 유통을 최적화한다.

입력 변수:

변수 그룹 변수 중요도
기상 적산 온도, 강수량, 일사량, 일교차 높음
토양 pH, 유기물, 질소, 인산, 칼리 높음
생육 NDVI 시계열, 생육 단계, 개화일 높음
재배 품종, 파종일, 재식 밀도 중간
이력 전년도 수확량, 윤작 이력 중간

모델링 접근:

import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import TimeSeriesSplit

def build_yield_model(data: pd.DataFrame) -> dict:
    """수확량 예측 모델 학습

    Args:
        data: columns = [year, region, crop, gdd, precip, 
                         ndvi_max, soil_ph, ..., yield_kg_ha]
    """
    feature_cols = [
        'gdd',           # 생육도일 (Growing Degree Days)
        'precip_total',  # 총 강수량
        'precip_cv',     # 강수 변동계수
        'solar_rad',     # 일사량
        'ndvi_max',      # 최대 NDVI
        'ndvi_integral',  # NDVI 적분값
        'soil_ph',
        'soil_om',       # 유기물 함량
        'planting_doy',  # 파종 일수 (day of year)
    ]

    X = data[feature_cols]
    y = data['yield_kg_ha']

    # 시계열 교차검증
    tscv = TimeSeriesSplit(n_splits=5)
    scores = []

    model = GradientBoostingRegressor(
        n_estimators=500,
        max_depth=5,
        learning_rate=0.05,
        subsample=0.8,
    )

    for train_idx, test_idx in tscv.split(X):
        model.fit(X.iloc[train_idx], y.iloc[train_idx])
        score = model.score(X.iloc[test_idx], y.iloc[test_idx])
        scores.append(score)

    model.fit(X, y)

    return {
        "model": model,
        "cv_r2": np.mean(scores),
        "feature_importance": dict(zip(feature_cols, 
                                       model.feature_importances_)),
    }

2. 병충해 탐지

이미지 분류와 시계열 분석을 결합하여 병충해를 조기에 탐지한다.

탐지 파이프라인:

                    ┌──────────────────┐
                    │   데이터 수집     │
                    └────────┬─────────┘
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
       ┌────────────┐ ┌────────────┐ ┌────────────┐
       │ 드론 영상  │ │ NDVI 변화  │ │ 기상 조건  │
       │ (RGB/MSI)  │ │ (시계열)   │ │ (온습도)   │
       └──────┬─────┘ └──────┬─────┘ └──────┬─────┘
              │              │              │
              ▼              ▼              ▼
       ┌────────────┐ ┌────────────┐ ┌────────────┐
       │ CNN 분류   │ │ 이상 탐지  │ │ 위험 지수  │
       │ (병징 감지)│ │ (급격 변화)│ │ (발생 확률)│
       └──────┬─────┘ └──────┬─────┘ └──────┬─────┘
              │              │              │
              └──────────────┼──────────────┘
                    ┌──────────────────┐
                    │  종합 판단 + 알림 │
                    └──────────────────┘

기상 조건 기반 병충해 위험 지수:

def calculate_disease_risk(weather_df: pd.DataFrame) -> pd.Series:
    """기상 조건 기반 병해 위험 지수 (0-100)

    주요 인자: 온도, 습도, 이슬점, 강수
    """
    risk = pd.Series(0.0, index=weather_df.index)

    # 온도 적합성 (병원균 활동 최적 온도)
    temp = weather_df['temp_avg']
    temp_risk = np.where(
        (temp >= 15) & (temp <= 25), 
        30,  # 최적
        np.where((temp >= 10) & (temp <= 30), 15, 0)
    )

    # 습도 위험 (높은 습도 = 높은 위험)
    humidity = weather_df['humidity_avg']
    humid_risk = np.where(humidity >= 85, 30, 
                 np.where(humidity >= 70, 15, 0))

    # 연속 습윤 시간
    wet_hours = weather_df['wet_duration_hours']
    wet_risk = np.clip(wet_hours * 2, 0, 30)

    # 최근 강수
    precip = weather_df['precip_3day']
    precip_risk = np.where(precip > 30, 10, 
                  np.where(precip > 10, 5, 0))

    risk = temp_risk + humid_risk + wet_risk + precip_risk
    return np.clip(risk, 0, 100)

3. 관개 최적화

토양 수분 센서와 기상 데이터를 결합하여 최적 관개 시점과 양을 결정한다.

수분 수지 모델:

토양 수분(t+1) = 토양 수분(t) + 강수 + 관개 - ET - 배수

ET (증발산) = ET0 x Kc
  ET0: 기준 증발산 (Penman-Monteith)
  Kc: 작물 계수 (생육 단계별 상이)

관개 결정 로직:

def irrigation_decision(
    soil_moisture: float,    # 현재 토양 수분 (%)
    field_capacity: float,   # 포장 용수량 (%)
    wilting_point: float,    # 위조점 (%)
    crop_kc: float,          # 작물 계수
    et0_forecast: list,      # 향후 3일 ET0 예측
    rain_forecast: list,     # 향후 3일 강수 예측
) -> dict:
    """관개 의사결정"""

    # 가용 수분
    available = (soil_moisture - wilting_point) / (field_capacity - wilting_point)

    # 향후 3일 수분 소모 예측
    et_3day = sum(et0 * crop_kc for et0 in et0_forecast)
    rain_3day = sum(rain_forecast)
    net_loss = et_3day - rain_3day

    # 관개 필요량 계산
    if available < 0.4:  # 긴급 (MAD 초과)
        amount = (field_capacity - soil_moisture) * soil_depth * 10  # mm
        return {"action": "irrigate_now", "amount_mm": amount, 
                "priority": "high"}

    elif available < 0.6 and net_loss > 0:
        amount = net_loss * 1.1  # 10% 여유
        return {"action": "schedule", "amount_mm": amount, 
                "priority": "medium", "within_hours": 24}

    else:
        return {"action": "wait", "next_check_hours": 12,
                "priority": "low"}

4. 가격 예측

농산물 가격을 시계열 모델로 예측하여 출하 전략을 수립한다.

가격 예측 SQL (KAMIS 데이터 기반):

-- 농산물 일별 가격 시계열 조회
SELECT 
    p.date,
    p.item_name,
    p.market_name,
    p.avg_price,
    -- 이동평균
    AVG(p.avg_price) OVER (
        PARTITION BY p.item_code 
        ORDER BY p.date 
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS ma_7d,
    AVG(p.avg_price) OVER (
        PARTITION BY p.item_code 
        ORDER BY p.date 
        ROWS BETWEEN 29 PRECEDING AND CURRENT ROW
    ) AS ma_30d,
    -- 전년 동기 대비
    LAG(p.avg_price, 365) OVER (
        PARTITION BY p.item_code 
        ORDER BY p.date
    ) AS price_yoy,
    -- 변동률
    (p.avg_price - LAG(p.avg_price, 1) OVER (
        PARTITION BY p.item_code ORDER BY p.date
    )) / NULLIF(LAG(p.avg_price, 1) OVER (
        PARTITION BY p.item_code ORDER BY p.date
    ), 0) * 100 AS daily_change_pct
FROM prices p
WHERE p.item_code = '100'  -- 배추
    AND p.date >= DATE_SUB(CURRENT_DATE, INTERVAL 2 YEAR)
ORDER BY p.date;
-- 월별 계절성 분석
SELECT 
    MONTH(date) AS month,
    item_name,
    AVG(avg_price) AS avg_price,
    STDDEV(avg_price) AS std_price,
    MIN(avg_price) AS min_price,
    MAX(avg_price) AS max_price,
    COUNT(*) AS obs_count
FROM prices
WHERE item_code = '100'
    AND date >= DATE_SUB(CURRENT_DATE, INTERVAL 5 YEAR)
GROUP BY MONTH(date), item_name
ORDER BY month;

5. 공급망 예측

생산-유통-소비를 연결하는 공급망 최적화.

예측 대상 입력 변수 모델 활용
생산량 재배면적, 기상, NDVI GB, LSTM 수급 균형
출하량 수확량, 가격, 재고 시계열 물류 계획
수요 인구, 계절, 가격 ARIMA, Prophet 가격 안정
폐기량 유통 단계, 온도 로지스틱 손실 최소화

KPI 체계

농장 수준 KPI

KPI 산식 단위 목표
단위면적 수확량 총 수확량 / 재배면적 kg/ha 작물별 상이
용수 효율 수확량 / 관개량 kg/m3 최대화
비료 효율 수확량 / 비료 투입량 kg/kg 최대화
농약 사용량 농약 사용 / 재배면적 kg/ha 최소화
노동 생산성 수확량 / 노동 시간 kg/h 최대화
투입 대비 산출비 판매액 / 총 투입비용 ratio > 2.0
품질 등급 비율 상품 / 전체 % > 80%

스마트팜 운영 KPI

KPI 설명 모니터링 주기
센서 가동률 정상 작동 센서 비율 실시간
데이터 수집률 예정 대비 실제 수집 비율 일별
알림 정확도 알림 중 실제 조치 필요 비율 주별
자동 제어 비율 자동 관개/환기 비율 월별
에너지 효율 에너지 사용량 / 수확량 월별

사례 연구

네덜란드 스마트팜

항목 내용
특징 유리온실, 완전 환경 제어
기술 센서 네트워크, AI 기반 환경 제어, 로봇 수확
성과 토마토 수확량 세계 최고 (80kg/m2), 물 사용 90% 절감
핵심 WUR(바헤닝언 대학) 연구 기반, 데이터 공유 문화

한국 스마트팜 혁신밸리

항목 내용
위치 전북 김제, 경남 밀양, 전남 고흥, 경북 상주
목적 청년 농업인 육성, 스마트팜 기술 보급
기술 IoT 센서, 자동 환경 제어, 데이터 수집 플랫폼
데이터 농촌진흥청 스마트팜 빅데이터 플랫폼

Python 분석 예시: NDVI 시계열 + 수확량 예측

import pandas as pd
import numpy as np
from prophet import Prophet
import rasterio
from shapely.geometry import box

def extract_ndvi_timeseries(tif_paths: list, aoi: box) -> pd.DataFrame:
    """위성 영상에서 관심 영역의 평균 NDVI 추출"""
    records = []

    for path in tif_paths:
        with rasterio.open(path) as src:
            # AOI 내 픽셀 추출
            window = rasterio.windows.from_bounds(*aoi.bounds, src.transform)
            nir = src.read(4, window=window)   # Band 4: NIR
            red = src.read(3, window=window)   # Band 3: Red

            # NDVI 계산
            ndvi = (nir.astype(float) - red) / (nir + red + 1e-10)
            ndvi = np.where((ndvi >= -1) & (ndvi <= 1), ndvi, np.nan)

            records.append({
                "date": extract_date_from_path(path),
                "ndvi_mean": np.nanmean(ndvi),
                "ndvi_std": np.nanstd(ndvi),
                "ndvi_max": np.nanmax(ndvi),
                "valid_pixel_ratio": np.sum(~np.isnan(ndvi)) / ndvi.size,
            })

    return pd.DataFrame(records).sort_values("date")


def forecast_ndvi(ndvi_ts: pd.DataFrame, periods: int = 30) -> pd.DataFrame:
    """NDVI 시계열 예측 (Prophet)"""
    df = ndvi_ts.rename(columns={"date": "ds", "ndvi_mean": "y"})

    model = Prophet(
        yearly_seasonality=True,
        weekly_seasonality=False,
        daily_seasonality=False,
    )
    model.fit(df)

    future = model.make_future_dataframe(periods=periods)
    forecast = model.predict(future)

    return forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]]

참고 자료

자료 링크
농촌진흥청 스마트팜 https://www.smartfarmkorea.net/
KAMIS 농산물유통정보 https://www.kamis.or.kr/
Sentinel Hub https://www.sentinel-hub.com/
FAO GAEZ (농업 생태 구역) https://gaez.fao.org/
한국농촌경제연구원 https://www.krei.re.kr/

최종 업데이트: 2026-03-25