Download code/generate_master_benchmark.py from neitpm/power-load-forecasting: direct link, hf CLI and curl.
- Browser
- Download file 8.4 kB
-
https://huggingface.co/neitpm/power-load-forecasting/resolve/main/code/generate_master_benchmark.py
- Command line
-
hf download hf://neitpm/power-load-forecasting/code/generate_master_benchmark.py
-
curl -L -o generate_master_benchmark.py https://huggingface.co/neitpm/power-load-forecasting/resolve/main/code/generate_master_benchmark.py
8.4 kB
| # -*- 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() | |