File size: 8,396 Bytes
04cc18f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | # -*- coding: utf-8 -*-
"""
=============================================================================
BẢNG TỔNG HỢP SO SÁNH TOÀN DIỆN CÁC MÔ HÌNH DỰ BÁO PHỤ TẢI ĐIỆN 30 PHÚT
(PHIÊN BẢN CHUẨN MỰC HỌC THUẬT CHO LUẬN VĂN THẠC SĨ)
=============================================================================
Đặc điểm hiệu chỉnh:
1. Đồng nhất mốc thời gian chính xác theo preprocessing_summary.json:
- Tập kiểm thử: 02/11/2024 15:30:00 -> 30/08/2025 23:30:00 (14,440 mẫu, lọc 14,385 mẫu hợp lệ).
2. Chuẩn hóa diễn đạt tính liên tục:
- "14.385 mẫu hợp lệ, được phân thành 16 đoạn thời gian liên tục; bootstrap không vượt qua các khoảng đứt gãy."
3. Minh bạch phương pháp Ensemble:
- Sử dụng Trung bình đều cố định (Uniform Simple Average, trọng số w_i = 1/5 cho cả 5 seeds),
hoàn toàn không dùng bất kỳ thông tin nào từ tập test để tối ưu trọng số (Zero Data Leakage).
4. Công thức cải thiện:
Improvement (%) = (Metric_Baseline - Metric_Model) / Metric_Baseline * 100%
=============================================================================
"""
import os
import sys
import json
from pathlib import Path
if sys.platform.startswith("win"):
try:
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
except Exception:
pass
import pandas as pd
import numpy as np
def generate_master_benchmark_table():
reports_dir = Path("output_preprocessing/reports")
# 1. Đọc kết quả baseline
df_base = pd.read_csv(reports_dir / "baseline_models_comparison.csv")
# 2. Đọc kết quả KAN 5 seed
with open(reports_dir / "kan_multi_seed_stability.json", "r", encoding="utf-8") as f:
kan_data = json.load(f)
stats = kan_data["summary_statistics"]
ens = kan_data["ensemble_5_seeds"]["metrics"]
master_rows = []
for _, row in df_base.iterrows():
master_rows.append({
"Phân nhóm": "Baseline / ML Truyền thống",
"Mô hình": row["model_name"],
"MAE (kW)": f"{row['MAE_kW']:.2f}",
"RMSE (kW)": f"{row['RMSE_kW']:.2f}",
"MAE (MW)": f"{row['MAE_MW']:.4f}",
"RMSE (MW)": f"{row['RMSE_MW']:.4f}",
"sMAPE (%)": f"{row['sMAPE_pct']:.2f}%",
"R2 Score": f"{row['R2_score']:.4f}",
"ΔMAE vs Persistence (%)": f"{((598.36 - row['MAE_kW']) / 598.36 * 100):+.2f}%" if "Persistence" not in row["model_name"] else "Baseline (0.00%)",
"ΔRMSE vs Persistence (%)": f"{((1160.44 - row['RMSE_kW']) / 1160.44 * 100):+.2f}%" if "Persistence" not in row["model_name"] else "Baseline (0.00%)",
})
# Dòng 8: Đánh giá độ ổn định của mô hình đơn KAN qua 5 seed (Mean ± Std)
master_rows.append({
"Phân nhóm": "Thống kê độ ổn định (5 Seed)",
"Mô hình": "8. Residual KAN đơn lẻ (Mean ± Std qua 5 Seed)*",
"MAE (kW)": f"{stats['MAE_kW_mean']:.2f} ± {stats['MAE_kW_std']:.2f}",
"RMSE (kW)": f"{stats['RMSE_kW_mean']:.2f} ± {stats['RMSE_kW_std']:.2f}",
"MAE (MW)": f"{stats['MAE_kW_mean']/1000:.4f}",
"RMSE (MW)": f"{stats['RMSE_kW_mean']/1000:.4f}",
"sMAPE (%)": f"{stats['sMAPE_pct_mean']:.2f}% ± {stats['sMAPE_pct_std']:.2f}%",
"R2 Score": f"{stats['R2_score_mean']:.4f} ± {stats['R2_score_std']:.4f}",
"ΔMAE vs Persistence (%)": f"+{stats['Improvement_MAE_pct_mean']:.2f}%",
"ΔRMSE vs Persistence (%)": f"+{stats['Improvement_RMSE_pct_mean']:.2f}%"
})
# Dòng 9: Mô hình kết hợp trung bình đều (Uniform Ensemble)
master_rows.append({
"Phân nhóm": "Mô hình đề xuất (Deep Learning)",
"Mô hình": "9. Residual KAN Ensemble (Trung bình đều 5 Seed)**",
"MAE (kW)": f"{ens['MAE_kW']:.2f}",
"RMSE (kW)": f"{ens['RMSE_kW']:.2f}",
"MAE (MW)": f"{ens['MAE_MW']:.4f}",
"RMSE (MW)": f"{ens['RMSE_MW']:.4f}",
"sMAPE (%)": f"{ens['sMAPE_pct']:.2f}%",
"R2 Score": f"{ens['R2_score']:.4f}",
"ΔMAE vs Persistence (%)": f"+{ens['Improvement_MAE_pct']:.2f}%",
"ΔRMSE vs Persistence (%)": f"+{ens['Improvement_RMSE_pct']:.2f}%"
})
df_master = pd.DataFrame(master_rows)
df_master.to_csv(reports_dir / "master_model_comparison_benchmark.csv", index=False, encoding="utf-8-sig")
headers = list(df_master.columns)
lines = [
"| " + " | ".join(headers) + " |",
"| " + " | ".join(["---"] * len(headers)) + " |"
]
for _, r in df_master.iterrows():
lines.append("| " + " | ".join([str(r[c]) for c in headers]) + " |")
md_table = "\n".join(lines)
notes = """
### Ghi chú phương pháp và phạm vi áp dụng (Dành cho Luận văn Thạc sĩ):
1. **Phạm vi dữ liệu thực nghiệm:**
- Tập kiểm thử gồm **14.385 mẫu hợp lệ**, được phân thành **16 phân đoạn thời gian liên tục**; quy trình bootstrap kiểm định không vượt qua các khoảng đứt gãy dữ liệu.
- Khoảng thời gian kiểm thử chính xác: **02/11/2024 15:30:00 đến 30/08/2025 23:30:00**.
- Đối tượng kiểm định: **Lộ 480 Trạm biến áp 224 Tân Hưng** (Công ty Điện lực Tây Ninh).
- *Lưu ý học thuật:* Kết quả phản ánh hiệu năng trên tập kiểm định cụ thể này; việc mở rộng sang các xuất tuyến khác (như trạm Suối Ngô hoặc các năm khác) cần có thực nghiệm tái thẩm định riêng biệt.
2. **Công thức tính tỷ lệ cải thiện:**
$$\\text{Improvement (\\%)} = \\frac{\\text{Metric}_{\\text{Persistence}} - \\text{Metric}_{\\text{Model}}}{\\text{Metric}_{\\text{Persistence}}} \\times 100\\%$$
- Giá trị **dương (+)**: Mô hình giảm sai số (tốt hơn Persistence).
- Giá trị **âm (-)**: Mô hình có sai số lớn hơn Persistence (kém hơn).
3. **Phân biệt hai dòng kết quả KAN:**
- `(*)` **Dòng 8 (Mean ± Std):** Thống kê độ ổn định của mô hình đơn qua 5 lần khởi tạo ngẫu nhiên khác nhau (`seeds = [42, 101, 2024, 7, 999]`), thể hiện tính hội tụ vững chắc của mạng.
- `(**)` **Dòng 9 (Ensemble):** Mô hình kết hợp bằng **trung bình đều cố định** $(\\hat{y}_{\\text{ens}} = \\frac{1}{5}\\sum_{i=1}^5 \\hat{y}_i)$, tuyệt đối không tối ưu hóa trọng số trên tập kiểm thử nhằm đảm bảo khách quan (Zero Data Leakage).
4. **Đánh giá toàn diện:**
- **Residual KAN** đạt ưu thế rõ rệt và vượt trội về **MAE, RMSE và R²**.
- **Persistence Naive** vẫn giữ vị trí dẫn đầu về **sMAPE (13.35%)** và là mốc baseline bắt buộc phải có để đối chiếu trong bài toán dự báo phụ tải ngắn hạn 30 phút.
5. **Kiểm soát rò rỉ dữ liệu (Data Leakage Control):**
- Bộ điền khuyết thiếu (`SimpleImputer`) và bộ chuẩn hóa (`StandardScaler`) được tính toán (`fit`) **nghiêm ngặt chỉ trên tập Train** (giai đoạn 03/2020 đến 01/2024), sau đó chỉ áp dụng phép chuyển đổi (`transform`) sang tập Validation và Test.
- Các siêu tham số dừng sớm (Early Stopping) được theo dõi độc lập trên tập Validation (01/2024 đến 11/2024). Tập Test tuyệt đối không tham gia vào bất kỳ khâu huấn luyện hay điều chỉnh ngưỡng nào.
"""
with open(reports_dir / "master_model_comparison_benchmark.md", "w", encoding="utf-8") as f:
f.write("# BẢNG TỔNG HỢP ĐỐI CHIẾU MÔ HÌNH DỰ BÁO PHỤ TẢI (TRẠM 224 TÂN HƯNG)\n\n")
f.write(md_table)
f.write("\n\n" + notes.strip() + "\n")
print("✅ Đã cập nhật bảng tổng hợp chuẩn mực học thuật hoàn thiện tại:")
print(f" - {reports_dir / 'master_model_comparison_benchmark.csv'}")
print(f" - {reports_dir / 'master_model_comparison_benchmark.md'}")
if __name__ == "__main__":
generate_master_benchmark_table()
|