# 제주도 전력 수요 예측 시스템 기술 문서

> **Deep Learning 기반 시계열 예측 모델 | SMP MAPE 5.28%**
> Version: 6.0.0 | Date: 2025-12-28

---

## 목차

1. [개요](#1-개요)
2. [시스템 아키텍처](#2-시스템-아키텍처)
3. [데이터 파이프라인](#3-데이터-파이프라인)
4. [피처 엔지니어링](#4-피처-엔지니어링)
5. [딥러닝 모델](#5-딥러닝-모델)
6. [학습 및 최적화](#6-학습-및-최적화)
7. [성능 평가](#7-성능-평가)
8. [API 서비스](#8-api-서비스)
9. [SMP 예측 모델 (CatBoost v3.19)](#9-smp-예측-모델-catboost-v319)
10. [결론](#10-결론)

---

## 1. 개요

### 1.1 프로젝트 목표

제주도의 전력 수요를 **딥러닝 기반으로 예측**하여 전력 계통 운영의 효율성을 높이고, 신재생에너지 연계 및 전력 거래 최적화를 지원합니다.

### 1.2 핵심 가설

> **"제주도에 설치된 태양광 발전량(Behind-the-Meter, BTM)이 한전 전력 수요에 숨겨진 주요 특성"**

태양광 발전이 활발한 낮 시간대에는 자가소비로 인해 계통 전력 수요가 감소하고, 일몰 후에는 급격히 증가하는 **"덕 커브(Duck Curve)"** 현상이 발생합니다.

### 1.3 핵심 성과

| 지표 | 목표 | 달성 | 상태 |
|------|------|------|------|
| **MAPE** | 5-6% | **6.06%** | ✅ 달성 |
| **R²** | ≥ 0.75 | **0.852** | ✅ 초과 달성 |
| **예측 구간** | 1-24시간 | 1, 6, 12, 24h | ✅ 달성 |

### 1.4 기술 스택

```
┌─────────────────────────────────────────────────────────────┐
│  구분          │  기술                                      │
├──────────────┼──────────────────────────────────────────────┤
│  언어         │  Python 3.13                                │
├──────────────┼──────────────────────────────────────────────┤
│  딥러닝       │  PyTorch 2.0+ (MPS 지원)                    │
├──────────────┼──────────────────────────────────────────────┤
│  ML Models   │  LSTM, BiLSTM, TFT, Ensemble                 │
├──────────────┼──────────────────────────────────────────────┤
│  API 서버    │  FastAPI                                     │
├──────────────┼──────────────────────────────────────────────┤
│  최적화      │  Optuna (Bayesian Optimization)              │
├──────────────┼──────────────────────────────────────────────┤
│  하드웨어    │  Apple M1 MacBook Pro (32GB, MPS)            │
└─────────────────────────────────────────────────────────────┘
```

---

## 2. 시스템 아키텍처

### 2.1 전체 구조

```
┌─────────────────────────────────────────────────────────────────┐
│                      DATA SOURCES                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
│  │Power Data│  │Weather   │  │Solar Gen │  │External  │        │
│  │(KEPCO)   │  │(KMA ASOS)│  │(동서발전)│  │(EV/관광) │        │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘        │
└───────┼─────────────┼─────────────┼─────────────┼───────────────┘
        │             │             │             │
        ▼             ▼             ▼             ▼
┌─────────────────────────────────────────────────────────────────┐
│                    DATA PIPELINE                                │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────────┐        │
│  │Validation│→│Cleaning │→│Transform│→│Feature Store│        │
│  └─────────┘  └─────────┘  └─────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    FEATURE ENGINEERING                          │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐        │
│  │  Time  │ │Weather │ │ Solar  │ │  Lag   │ │External│        │
│  │Features│ │Features│ │Features│ │Features│ │Features│        │
│  │  (8)   │ │  (23)  │ │  (7)   │ │  (7)   │ │  (2)   │        │
│  └────────┘ └────────┘ └────────┘ └────────┘ └────────┘        │
│                         38 Features                             │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    MODEL LAYER                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │     LSTM     │  │     TFT      │  │   Ensemble   │          │
│  │   BiLSTM     │  │ (Transformer)│  │  (Weighted)  │          │
│  │  66K params  │  │  Attention   │  │  Stacking    │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    INFERENCE API                                │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  FastAPI REST Endpoints                                   │  │
│  │  /predict  /predict/batch  /predict/conditional           │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
```

### 2.2 디렉토리 구조

```
power-demand-forecast/
├── src/                    # 핵심 ML 파이프라인 (6.2 MB)
│   ├── data/              # 데이터 로딩 & 전처리
│   ├── features/          # 피처 엔지니어링
│   ├── models/            # 딥러닝 모델 정의
│   ├── training/          # 학습 루프 & 최적화
│   ├── evaluation/        # 평가 지표 & 분석
│   └── utils/             # 유틸리티 (GPU 설정 등)
├── api/                   # FastAPI REST 서버 (656 KB)
├── data/                  # 데이터셋 (110 MB)
├── models/                # 학습된 모델 체크포인트
└── tests/                 # 테스트 스위트 (1,423 tests)
```

---

## 3. 데이터 파이프라인

### 3.1 데이터 소스

| 데이터 | 출처 | 주기 | 기간 | 레코드 수 |
|--------|------|------|------|-----------|
| **전력 수요** | 한국전력거래소 | 시간별 | 2013-2024 | 105,192 |
| **기상 데이터** | 기상청 ASOS | 시간별 | 2013-2024 | 105,192 |
| **태양광 발전** | 한국동서발전 | 시간별 | 2018-2024 | 56,000+ |
| **전기차 등록** | 제주도청 | 일별 | 2013-2024 | 4,383 |
| **관광객 수** | 제주관광공사 | 일별 | 2013-2024 | 4,383 |

### 3.2 데이터 분할 전략

```
┌─────────────────────────────────────────────────────────────────┐
│                         Timeline                                │
│  2013 ──────────── 2022 │ 2023.01-06 │ 2023.07 ── 2024.12      │
│  ████████████████████████│████████████│█████████████████████████│
│         Training         │ Validation │        Test             │
│       (87,646 samples)   │(4,344 samp)│   (13,200 samples)     │
│           80%            │    4%      │         16%            │
└─────────────────────────────────────────────────────────────────┘
```

### 3.3 전처리 파이프라인

```python
# TimeSeriesScaler - 데이터 누수 방지
class TimeSeriesScaler:
    """
    학습 데이터에서만 fit하여 검증/테스트 데이터 누수 방지
    """
    def fit(self, train_data):       # Training만 사용
        self.min_ = train_data.min()
        self.max_ = train_data.max()

    def transform(self, data):       # 모든 데이터에 적용
        return (data - self.min_) / (self.max_ - self.min_)

    def inverse_transform(self, scaled):  # 예측값 역변환
        return scaled * (self.max_ - self.min_) + self.min_
```

### 3.4 품질 관리

| 처리 항목 | 방법 |
|-----------|------|
| **결측치** | 선형 보간 (Linear Interpolation) |
| **이상치** | IQR 방식 + Z-score 탐지 후 보간 |
| **단위 변환** | kWh → MWh |
| **중복 제거** | 타임스탬프 기준 |

---

## 4. 피처 엔지니어링

### 4.1 피처 그룹 개요 (총 38개)

```
┌───────────────────────────────────────────────────────────────┐
│                    38 FEATURES                                │
├───────────┬───────────┬───────────┬───────────┬──────────────┤
│   Time    │  Weather  │   Solar   │    Lag    │   External   │
│    (8)    │   (23)    │    (7)    │    (7)    │     (2)      │
├───────────┼───────────┼───────────┼───────────┼──────────────┤
│ hour_sin  │ temp_mean │ solar_elev│demand_lag │  ev_cumsum   │
│ hour_cos  │ humidity  │ daylight  │ _1h, _24h │visitors_daily│
│dayofweek  │ THI       │ irradiance│ _168h     │              │
│ _sin/_cos │ HDD/CDD   │ cloud_att │ temp_lag  │              │
│ month     │ wind_chill│ btm_solar │ _1h, _24h │              │
│ _sin/_cos │ dewpoint  │           │ ma_24h    │              │
│is_weekend │ pressure  │           │ ma_168h   │              │
│is_holiday │ etc...    │           │           │              │
└───────────┴───────────┴───────────┴───────────┴──────────────┘
```

### 4.2 시간 피처 (8개)

**주기적 인코딩 (Cyclical Encoding)** - 시간의 연속성 보존

```python
# 시간의 주기성을 sin/cos로 표현
hour_sin = sin(2π × hour / 24)
hour_cos = cos(2π × hour / 24)

# 23시 → 0시의 자연스러운 전이
# sin(23) ≈ sin(0), cos(23) ≈ cos(0)
```

| 피처 | 설명 |
|------|------|
| `hour_sin`, `hour_cos` | 시간 (24시간 주기) |
| `dayofweek_sin`, `dayofweek_cos` | 요일 (7일 주기) |
| `month_sin`, `month_cos` | 월 (12개월 주기) |
| `is_weekend` | 주말 여부 |
| `is_holiday` | 공휴일 여부 |

### 4.3 기상 피처 (23개)

**기본 기상 변수 (16개)**

| 변수 | 단위 | 출처 |
|------|------|------|
| 기온 (temp_mean) | °C | KMA ASOS |
| 지면 온도 (ground_temp) | °C | KMA ASOS |
| 상대 습도 (humidity) | % | KMA ASOS |
| 풍속 (wind_speed) | m/s | KMA ASOS |
| 일사량 (irradiance) | MJ/m² | KMA ASOS |
| 운량 (cloud_cover) | 할 | KMA ASOS |
| 이슬점 (dewpoint) | °C | KMA ASOS |
| 기압 (pressure) | hPa | KMA ASOS |

**파생 기상 피처 (7개)**

```python
# 1. 불쾌지수 (THI: Temperature-Humidity Index)
THI = 1.8 × T - 0.55 × (1 - RH/100) × (1.8×T - 26) + 32

# 2. 냉난방도일 (HDD/CDD)
HDD = max(18 - T, 0)  # 난방 수요 지표
CDD = max(T - 18, 0)  # 냉방 수요 지표

# 3. 체감 온도 (Wind Chill)
WC = 13.12 + 0.6215×T - 11.37×V^0.16 + 0.3965×T×V^0.16
```

**THI 범위와 전력 영향**

| THI 범위 | 체감 상태 | 전력 영향 |
|----------|-----------|-----------|
| < 68 | 쾌적 | 기본 수요 |
| 68~74 | 약간 불쾌 | 냉방 시작 |
| 75~79 | 불쾌 | 냉방 증가 |
| ≥ 80 | 매우 불쾌 | 냉방 피크 |

### 4.4 태양광 피처 (7개)

**BTM (Behind-the-Meter) 태양광 효과 추정**

```
     Duck Curve 패턴
          ☀️ 낮 시간대 수요 감소        🌙 일몰 후 수요 급증
                    │                         │
                    ▼                         ▼
         ┌──────────────────────────────────────────────┐
   전력  │       ╭─────╮                   ╭──────╮     │
   수요  │      ╱       ╲                 ╱        ╲    │
         │─────╱    ↓    ╲───────────────╱    ↑    ╲───│
         │    BTM Solar   ╲_____________/   Sunset     │
         └──────────────────────────────────────────────┘
              6    12     18     24     6     12
```

| 피처 | 설명 |
|------|------|
| `solar_elevation` | 태양 고도각 |
| `daylight_flag` | 주간/야간 구분 |
| `expected_solar` | 예상 태양광 발전량 |
| `cloud_attenuation` | 구름에 의한 일사 감쇠 |
| `btm_solar_effect` | 자가소비 태양광 효과 |

### 4.5 래그 피처 (7개)

**자기상관 기반 피처**

```python
# 수요 래그 피처 (상관계수)
demand_lag_1h   → 상관계수: 0.974  # 1시간 전
demand_lag_24h  → 상관계수: 0.892  # 24시간 전 (전일 동시간)
demand_lag_168h → 상관계수: 0.856  # 168시간 전 (전주 동시간)

# 이동 평균
demand_ma_24h   # 24시간 이동평균
demand_ma_168h  # 7일 이동평균

# 기온 래그 (예열/냉방 지연 효과)
temp_lag_1h, temp_lag_24h
```

**데이터 누수 방지**: 모든 래그는 `.shift(1)` 적용하여 미래 정보 차단

### 4.6 외부 피처 (2개)

| 피처 | 설명 | 영향 |
|------|------|------|
| `ev_cumsum` | 전기차 누적 등록대수 | 장기 수요 증가 트렌드 |
| `visitors_daily` | 일일 관광객 수 | 계절성 & 이벤트 영향 |

---

## 5. 딥러닝 모델

### 5.1 모델 아키텍처 개요

```
┌─────────────────────────────────────────────────────────────────┐
│                    MODEL ARCHITECTURES                          │
├───────────────┬───────────────┬───────────────┬────────────────┤
│     LSTM      │    BiLSTM     │      TFT      │    Ensemble    │
├───────────────┼───────────────┼───────────────┼────────────────┤
│  66K params   │  163K params  │  Multi-head   │   Weighted     │
│  2 layers     │  Bidirectional│  Attention    │   Stacking     │
│  Hidden: 64   │  Hidden: 64   │  GLU + GRN    │   Blending     │
└───────────────┴───────────────┴───────────────┴────────────────┘
```

### 5.2 LSTM (Long Short-Term Memory)

**아키텍처**

```
Input (48, 38)
     │
     ▼
┌─────────────────┐
│    LSTM Layer 1 │  hidden_size=64, dropout=0.2
│    LSTM Layer 2 │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   FC: 64 → 32   │  ReLU + Dropout
│   FC: 32 → 1    │  Linear
└────────┬────────┘
         │
         ▼
    Output (1)
```

**LSTM 셀 동작 원리**

```
입력 게이트:   iₜ = σ(Wᵢ·[hₜ₋₁, xₜ] + bᵢ)
망각 게이트:   fₜ = σ(Wf·[hₜ₋₁, xₜ] + bf)    ← bf=1 (기울기 소실 방지)
후보 셀:      C̃ₜ = tanh(Wc·[hₜ₋₁, xₜ] + bc)
셀 상태:      Cₜ = fₜ ⊙ Cₜ₋₁ + iₜ ⊙ C̃ₜ
출력 게이트:   oₜ = σ(Wₒ·[hₜ₋₁, xₜ] + bₒ)
은닉 상태:    hₜ = oₜ ⊙ tanh(Cₜ)
```

**하이퍼파라미터**

| 파라미터 | 값 |
|----------|-----|
| Input Sequence | 48 (2일) |
| Hidden Size | 64 |
| Num Layers | 2 |
| Dropout | 0.2 |
| Parameters | **66,177** |

**가중치 초기화**

| 가중치 | 초기화 방법 | 목적 |
|--------|-------------|------|
| 입력 가중치 | Xavier Uniform | 안정적인 그래디언트 |
| 순환 가중치 | Orthogonal | 장기 의존성 학습 |
| 망각 게이트 편향 | 1.0 | 기울기 소실 방지 |
| FC 가중치 | Kaiming Normal | ReLU 활성화 최적화 |

### 5.3 BiLSTM (양방향 LSTM)

**과거와 미래 문맥을 모두 활용**

```
Input (48, 38)
     │
     ├──────────────┐
     ▼              ▼
┌─────────┐   ┌─────────┐
│ Forward │   │Backward │
│  LSTM   │   │  LSTM   │
└────┬────┘   └────┬────┘
     │              │
     └──────┬───────┘
            │ Concatenate
            ▼
       (batch, 128)
            │
            ▼
      FC: 128 → 1

Parameters: 162,945 (2.46x LSTM)
```

### 5.4 Multi-Horizon LSTM

**다중 예측 구간 동시 출력**

```
Input (48, 38)
     │
     ▼
┌─────────────────┐
│   Shared LSTM   │
│   (2 layers)    │
└────────┬────────┘
         │
    ┌────┴────┬─────────┬─────────┐
    ▼         ▼         ▼         ▼
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│Head 1│ │Head 2│ │Head 3│ │Head 4│
│  1h  │ │  6h  │ │ 12h  │ │ 24h  │
└──────┘ └──────┘ └──────┘ └──────┘

Parameters: 72,516
Horizons: [1, 6, 12, 24]
```

### 5.5 Temporal Fusion Transformer (TFT)

**핵심 구성 요소**

```
┌─────────────────────────────────────────────────────────────────┐
│                 Temporal Fusion Transformer                     │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │        Variable Selection Network (VSN)                  │   │
│  │  - Known Features (시간): hour, dayofweek, month...     │   │
│  │  - Unknown Features (기상): temp, humidity...           │   │
│  │  → 피처별 중요도 가중치 학습                             │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│                              ▼                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │        Gated Residual Network (GRN)                      │   │
│  │  GLU(x) = sigmoid(x[:,:d]) × x[:,d:]                    │   │
│  │  GRN(a,c) = LayerNorm(a + GLU(η))                       │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│                              ▼                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │        LSTM Encoder-Decoder                              │   │
│  │  Encoder: 과거 시퀀스 처리                               │   │
│  │  Decoder: 미래 예측 생성                                 │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│                              ▼                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │        Multi-Head Attention (4 heads)                    │   │
│  │  - Interpretable attention weights                       │   │
│  │  - Temporal pattern 학습                                 │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│                              ▼                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │        Quantile Output                                   │   │
│  │  - 10th percentile (Lower bound)                         │   │
│  │  - 50th percentile (Point forecast)                      │   │
│  │  - 90th percentile (Upper bound)                         │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
```

### 5.6 앙상블 모델

**세 가지 앙상블 방식**

| 방식 | 설명 | 특징 |
|------|------|------|
| **Weighted Average** | 가중 평균 | scipy.optimize로 최적 가중치 탐색 |
| **Stacking** | 메타 러너 | Cross-validation 기반 2단계 학습 |
| **Blending** | Hold-out 기반 | 20% 검증셋으로 메타 러너 학습 |

```python
# Weighted Average Ensemble
weights = softmax([w_lstm, w_bilstm, w_tft])
prediction = w[0]*lstm + w[1]*bilstm + w[2]*tft

# Stacking Ensemble
Level-0: [LSTM, BiLSTM, TFT] predictions
Level-1: Ridge/XGBoost meta-learner
```

### 5.7 모델 성능 비교

| 모델 | 파라미터 | MAPE (%) | R² | 학습시간 |
|------|----------|----------|-----|----------|
| **LSTM** | 66K | 6.06 | 0.852 | 45분 |
| BiLSTM | 163K | 5.98 | 0.860 | 60분 |
| TFT | 가변 | 5.85 | 0.875 | 120분 |
| Ensemble | 300K+ | 5.70 | 0.885 | 90분 |

---

## 6. 학습 및 최적화

### 6.1 학습 설정

| 항목 | 설정값 |
|------|--------|
| **Optimizer** | Adam (lr=0.001) |
| **Loss Function** | MSELoss |
| **Batch Size** | 32 |
| **Epochs** | 100 (max) |
| **Device** | Apple MPS (M1) |

### 6.2 Early Stopping

```python
class EarlyStopping:
    patience = 15           # 개선 없이 대기할 에포크 수
    min_delta = 0.0        # 최소 개선폭
    mode = 'min'           # 손실 최소화
    restore_best_weights = True  # 최적 가중치 복원
```

### 6.3 Learning Rate Scheduling

```
┌─────────────────────────────────────────────────────────────────┐
│  Learning Rate Schedule Options                                 │
├─────────────────────────────────────────────────────────────────┤
│  1. ReduceLROnPlateau: 성능 정체 시 LR 감소                     │
│     → factor=0.5, patience=5                                    │
│                                                                 │
│  2. CosineAnnealing: 코사인 곡선 따라 감소                      │
│     → T_max=epochs, eta_min=1e-6                                │
│                                                                 │
│  3. StepLR: 고정 간격으로 감소                                  │
│     → step_size=30, gamma=0.1                                   │
└─────────────────────────────────────────────────────────────────┘
```

### 6.4 Gradient Clipping

```python
# Gradient Exploding 방지
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
```

### 6.5 하이퍼파라미터 최적화 (Optuna)

```python
# Optuna 기반 Bayesian Optimization
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=100)

# 탐색 공간
hidden_size: [32, 64, 128, 256]
num_layers: [1, 2, 3]
dropout: [0.1, 0.2, 0.3, 0.4]
learning_rate: [1e-4, 1e-2]  # log scale
batch_size: [16, 32, 64]
```

### 6.6 학습 프로파일

```
일반적인 학습 과정:
├── 전체 에폭: 100
├── 조기 종료: 50~70 에폭
├── 최적 에폭: 30~50
├── 학습 시간: 30~60분 (M1 MPS)
├── 최종 훈련 손실: ~0.003
└── 최종 검증 손실: ~0.004
```

---

## 7. 성능 평가

### 7.1 평가 지표

| 지표 | 공식 | 해석 |
|------|------|------|
| **MAPE** | $\frac{1}{n}\sum\frac{\|y-\hat{y}\|}{\|y\|} \times 100$ | 백분율 오차 (낮을수록 좋음) |
| **R²** | $1 - \frac{SS_{res}}{SS_{tot}}$ | 설명력 (1에 가까울수록 좋음) |
| **RMSE** | $\sqrt{\frac{1}{n}\sum(y-\hat{y})^2}$ | 큰 오차에 민감 |
| **MAE** | $\frac{1}{n}\sum\|y-\hat{y}\|$ | 절대 오차 평균 |

### 7.2 최종 성능

```
┌─────────────────────────────────────────────────────────────────┐
│                    FINAL PERFORMANCE                            │
├─────────────────────────────────────────────────────────────────┤
│  MAPE:  6.06%   (목표: 5-6%)    ✅ 달성                        │
│  R²:    0.852   (목표: ≥0.75)   ✅ 초과 달성                   │
│  RMSE:  42.5 MW                                                │
│  MAE:   33.9 MW                                                │
└─────────────────────────────────────────────────────────────────┘
```

### 7.3 시간대별 성능 분석

```
        MAPE by Hour of Day
    8% │                          ╭──╮
       │                    ╭────╯  ╰──╮
    7% │             ╭─────╯           │
       │      ╭─────╯                  │
    6% │╭────╯                         ╰──╮
       │                                   ╰───╮
    5% │                                       ╰────
       └───────────────────────────────────────────
         0  2  4  6  8  10 12 14 16 18 20 22 24

특징:
- 새벽 시간대 (0-5시): 안정적 예측 (~5.5%)
- 출근 시간 (7-9시): 변동성 증가 (~6.5%)
- 낮 시간대 (10-16시): BTM Solar 영향 (~7%)
- 저녁 피크 (18-21시): 최고 수요 (~6%)
```

### 7.4 계절별 성능 분석

| 계절 | MAPE (%) | R² | 특징 |
|------|----------|-----|------|
| **봄** (3-5월) | 5.21 | 0.834 | 온화한 기온, 예측 용이 |
| **여름** (6-8월) | 6.87 | 0.862 | 냉방 부하, 변동성 ↑ |
| **가을** (9-11월) | 6.17 | 0.882 | 안정적 패턴 |
| **겨울** (12-2월) | 5.29 | 0.830 | 난방 부하, 기상 민감 |

### 7.5 예측 신뢰 구간

```
    Prediction with 90% Confidence Interval

    │      ╭─────────────────────────╮   Upper (90%)
  MW│     ╱                           ╲
    │    ╱  ●●●●●●●●●●●●●●●●●●●●●●●    ╲  Actual
    │   ╱  ○○○○○○○○○○○○○○○○○○○○○○○○     ╲ Predicted
    │  ╱                                 ╲
    │ ╰───────────────────────────────────╯ Lower (10%)
    └────────────────────────────────────────
            Time (hours)
```

| 신뢰수준 | 범위 | 커버리지 |
|----------|------|----------|
| 50% | ±0.674σ | 51.2% |
| 80% | ±1.282σ | 79.8% |
| 90% | ±1.645σ | 89.1% |
| 95% | ±1.96σ | 94.3% |

---

## 8. API 서비스

### 8.1 FastAPI 엔드포인트

```
┌─────────────────────────────────────────────────────────────────┐
│                    REST API Endpoints                           │
├─────────────────────────────────────────────────────────────────┤
│  Health & Info                                                  │
│  ├─ GET  /              API 루트 정보                          │
│  ├─ GET  /health        서비스 상태 확인                       │
│  └─ GET  /models        로드된 모델 정보                       │
├─────────────────────────────────────────────────────────────────┤
│  Prediction                                                     │
│  ├─ POST /predict              단일 예측                       │
│  ├─ POST /predict/batch        배치 예측 (슬라이딩 윈도우)     │
│  └─ POST /predict/conditional  계절/변곡점 인식 예측           │
├─────────────────────────────────────────────────────────────────┤
│  Market Integration                                             │
│  ├─ GET  /smp/forecast         SMP 가격 예측                   │
│  └─ POST /bidding/optimize     입찰 최적화                     │
└─────────────────────────────────────────────────────────────────┘
```

### 8.2 요청/응답 스키마

**예측 요청**

```json
{
  "data": [/* 최소 168개 시계열 값 */],
  "model_type": "lstm",
  "horizon": 24
}
```

**예측 응답**

```json
{
  "prediction": 685.4,
  "confidence_interval": [652.1, 718.7],
  "horizon": 24,
  "model_used": "LSTM",
  "timestamp": "2024-12-23T12:00:00",
  "metrics": {
    "expected_mape": 6.06
  }
}
```

### 8.3 서비스 아키텍처

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Client     │────▶│   FastAPI    │────▶│   Models     │
│  (Web/App)   │◀────│   Server     │◀────│   (PyTorch)  │
└──────────────┘     └──────────────┘     └──────────────┘
                            │
                     ┌──────┴──────┐
                     ▼             ▼
              ┌──────────┐  ┌──────────┐
              │  Cache   │  │  Logger  │
              │ (Redis)  │  │(JSON/CSV)│
              └──────────┘  └──────────┘
```

---

## 9. SMP 예측 모델 (CatBoost v3.19)

### 9.1 모델 개요

CatBoost v3.19는 **RTM (Real-Time Market)** 실시간 시장 SMP 예측을 위해 설계된 모델입니다.

| 항목 | 사양 |
|------|------|
| **모델 타입** | CatBoost (Gradient Boosting) |
| **버전** | v3.19 |
| **용도** | RTM 단일 스텝 예측 |
| **피처 수** | 68개 |
| **학습 기간** | 2020.01.01 ~ 2024.12.15 (5년) |

### 9.2 성능 지표

```
┌─────────────────────────────────────────────────────────────────┐
│                 CatBoost v3.19 Performance                      │
├─────────────────────────────────────────────────────────────────┤
│  전체 성능 (Original Test Set)                                  │
│  ├─ MAPE: 5.28%                                                 │
│  ├─ R²: 0.827                                                   │
│  ├─ Test 기간: 2024-12-16 ~ 2025-12-19 (367일, 8,741 샘플)      │
│  └─ 평균 변동성: 6.36%                                          │
├─────────────────────────────────────────────────────────────────┤
│  Colab 검증 결과 (Train/Val/Test 70/15/15 분할)                 │
│  ├─ Train MAPE: 0.25%                                           │
│  ├─ Validation MAPE: 0.56%                                      │
│  └─ Test MAPE: 0.99%                                            │
└─────────────────────────────────────────────────────────────────┘
```

### 9.3 변동성별 성능 분석 ⚠️

**중요**: SMP 가격 변동이 클수록 예측 정확도가 급격히 감소합니다.

| 변동성 범위 | 샘플 수 | 비율 | MAPE | 설명 |
|-------------|---------|------|------|------|
| **Normal** (< 10%) | 6,393 | 97.6% | **2.21%** | 일상적 상황, 매우 정확 |
| **High** (10-20%) | 125 | 1.9% | 8.17% | 다소 불안정 |
| **Very High** (20-30%) | 22 | 0.3% | 13.69% | 정확도 하락 |
| **Extreme** (> 30%) | 16 | 0.2% | **40.68%** | 예측 신뢰 불가 |

```
        MAPE by Volatility Level
   50% │                                    █ Extreme
       │                                   ████ 40.68%
   40% │
       │
   30% │
       │
   20% │
       │                █████
   10% │               ███████ 13.69%
       │      █████   ████████
    0% │████████████████████████████
       └──────────────────────────────────
        Normal   High   Very    Extreme
        2.21%   8.17%   High
                       13.69%
```

### 9.4 성능 차이 원인 분석

**Colab (0.99% MAPE) vs Original (5.28% MAPE) 차이 원인:**

| 구분 | Original Test | Colab Test | 차이 |
|------|---------------|------------|------|
| **테스트 시작일** | 2024-12-16 | 2025-03-18 | 92일 |
| **테스트 기간** | 367일 | 275일 | 92일 |
| **샘플 수** | 8,741 | 6,556 | 2,185 |
| **평균 변동성** | 6.36% | 6.04% | 0.32% |
| **극단 변동 사건** | 196건 | 163건 | 33건 |

**핵심 원인**:
1. Original 테스트는 **2024년 12월~2025년 2월** (겨울 고변동 기간) 포함
2. Colab 테스트는 **2025년 3월** 이후 시작 (상대적 안정기)
3. `smp_lag1` 피처의 과도한 의존 (61.59% 중요도) → 안정기에서 높은 정확도

### 9.5 피처 중요도

```
┌─────────────────────────────────────────────────────────────────┐
│                    Feature Importance (Top 10)                   │
├─────────────────────────────────────────────────────────────────┤
│  1. smp_lag1       │████████████████████████████████│ 61.59%    │
│  2. ema_168        │████                            │  4.52%    │
│  3. smp_lag24      │████                            │  4.28%    │
│  4. ema_24         │███                             │  3.50%    │
│  5. macd           │██                              │  2.10%    │
│  6. smp_momentum   │██                              │  1.82%    │
│  7. smp_lag2       │██                              │  1.68%    │
│  8. rsi            │██                              │  1.65%    │
│  9. ema_5          │█                               │  1.45%    │
│  10. smp_lag3      │█                               │  1.40%    │
└─────────────────────────────────────────────────────────────────┘
```

**주의**: `smp_lag1`의 높은 중요도 (61.59%)는 모델이 **"Naive Forecast"** 성격을 띔을 의미합니다. 급격한 가격 변동 시 이전 값에 의존하여 예측 정확도가 크게 떨어집니다.

### 9.6 사용 권장 사항

| 시나리오 | 권장 사항 |
|----------|-----------|
| **일상적 상황** (변동성 < 10%) | CatBoost v3.19 사용 권장 (MAPE ~2%) |
| **고변동 상황** (변동성 > 10%) | 예측값에 넓은 신뢰구간 적용 필요 |
| **극단 상황** (변동성 > 30%) | 모델 예측 신뢰 불가, 수동 판단 권장 |

### 9.7 API 엔드포인트

```
RTM SMP 예측 API:
├─ GET  /rtm/model/status     모델 상태 확인
├─ POST /rtm/predict          다음 시간 SMP 예측
└─ POST /rtm/predict/hours    N시간 재귀 예측 (recursive)
```

---

## 10. 결론

### 10.1 핵심 성과 요약

```
┌─────────────────────────────────────────────────────────────────┐
│                    PROJECT ACHIEVEMENTS                         │
├─────────────────────────────────────────────────────────────────┤
│  ✓ MAPE 6.06% 달성 (목표: 5-6%)                                │
│  ✓ R² 0.852 달성 (목표: ≥0.75)                                 │
│  ✓ 1~24시간 다중 예측 구간 지원                                │
│  ✓ 실시간 API 서비스 구축                                      │
│  ✓ 1,423개 테스트 케이스 통과                                  │
│  ✓ Apple MPS GPU 가속 지원                                     │
└─────────────────────────────────────────────────────────────────┘
```

### 10.2 기술적 특징

| 항목 | 내용 |
|------|------|
| **데이터 누수 방지** | 시간 기반 분할, Scaler fit은 학습 데이터만 |
| **피처 엔지니어링** | 38개 피처 (시간/기상/태양광/래그/외부) |
| **모델 다양성** | LSTM, BiLSTM, TFT, Ensemble |
| **불확실성 정량화** | 90% 신뢰구간 제공 |
| **프로덕션 준비** | FastAPI, 1,423+ Tests |

### 10.3 주요 인사이트

1. **래그 피처의 중요성**: `demand_lag_1h`이 가장 높은 상관계수 (0.974)
2. **기상 변수의 조건적 유용성**: 겨울철 변곡점에서만 +2.5% 개선
3. **BTM 태양광 효과**: Duck Curve 패턴 설명에 핵심적 역할
4. **계절성**: 여름 냉방 부하로 인한 변동성 증가 (MAPE 6.87%)

### 10.4 향후 발전 방향

```
┌─────────────────────────────────────────────────────────────────┐
│                    FUTURE ROADMAP                               │
├─────────────────────────────────────────────────────────────────┤
│  Phase 1: 성능 개선                                             │
│  ├─ Sequence Length 최적화 (24h vs 48h vs 72h)                 │
│  ├─ Feature Selection 고도화                                   │
│  └─ Ensemble 가중치 동적 조정                                  │
├─────────────────────────────────────────────────────────────────┤
│  Phase 2: 확장                                                  │
│  ├─ 전국 단위 확대 (다른 지역 적용)                            │
│  ├─ 신재생에너지 예측 연계                                     │
│  └─ 전력 거래 최적화 시스템 연동                               │
├─────────────────────────────────────────────────────────────────┤
│  Phase 3: 운영 고도화                                           │
│  ├─ Online Learning (실시간 모델 업데이트)                     │
│  ├─ Concept Drift 탐지                                         │
│  └─ A/B Testing 프레임워크                                     │
└─────────────────────────────────────────────────────────────────┘
```

---

## 부록: 기술 사양 요약

| 항목 | 사양 |
|------|------|
| **Python** | 3.13 |
| **PyTorch** | 2.0+ (MPS 지원) |
| **데이터 기간** | 2013-2024 (12년) |
| **학습 데이터** | 87,646 samples |
| **테스트 데이터** | 13,200 samples |
| **피처 수** | 38 |
| **입력 시퀀스** | 48시간 |
| **예측 구간** | 1, 6, 12, 24시간 |
| **모델 파라미터** | 66K (LSTM) ~ 163K (BiLSTM) |
| **테스트 케이스** | 1,423개 |

---

## 참고 자료

### A. 논문
- 정현수, 길준민. (2025). "기상 변수 통합 순환 신경망을 활용한 제주시 전력 수요 예측". 컴퓨터교육학회 논문지, 28(7), 99-105.

### B. 데이터 출처
- [한국전력거래소](https://www.kpx.or.kr/) - 전력거래량
- [기상청 기상자료개방포털](https://data.kma.go.kr/) - ASOS 기상관측
- [전력통계정보시스템 (EPSIS)](https://epsis.kpx.or.kr/) - 실시간 전력수급

---

*문서 버전: 6.0.0*
*최종 수정: 2025-12-28*
