【机器学习应用】基于集成学习的电力负荷预测系统实战案例
基于集成学习的电力负荷预测系统实战案例
- 一、系统概述
- 二、系统架构
- 2.1 整体架构图
- 2.2 架构分层说明
- 2.3 系统各个模块之间的调用流程
- 三、系统功能
- 3.1 功能模块图
- 3.2 核心功能说明
- 3.2.1 用户认证模块
- 3.2.2 数据管理模块
- 3.2.3 预测任务模块
- 3.2.4 模型服务模块
- 四、重点技术解析
- 4.1 Flask框架
- 4.2 Celery异步任务
- 4.3 机器学习模型
- 五、构建与部署步骤
- 5.1 环境准备
- 5.2 代码获取
- 5.3 配置修改
- 5.4 依赖安装
- 5.5 数据库初始化
- 5.6 模型训练(可选)
- 5.7 启动服务
- 5.7.1 启动Flask应用
- 5.7.2 启动Celery Worker
- 六、前端运行与系统演示
- 6.1 运行前端
- 6.2 系统演示
- 七、附录:接口清单
- 八、其他注意事项
一、系统概述
本系统是一个基于Python3.11.9+机器学习算法+Celery异步
队列调度模型的电力负荷预测系统实战案例,支持用户认证、电力数据管理、异步负荷预测任务调度及模型预测结果查询。系统通过整合Flask框架、Celery异步任务队列及机器学习模型,实现了高可用、可扩展的电力负荷预测服务
。读者可以自行扩展成其他的预测系统,只需要将数据源修改即可。
二、系统架构
2.1 整体架构图
2.2 架构分层说明
层次 | 组件/技术 | 功能描述 |
---|---|---|
接口层 | Flask路由/蓝图 | 处理HTTP请求(用户认证、数据操作、任务提交等),返回JSON响应。 |
服务层 | 各Service类(如ForecastService) | 封装业务逻辑(任务创建、数据导入导出、模型调用等),协调仓库层与任务队列。 |
数据层 | SQLAlchemy ORM + MySQL | 存储用户数据、电力历史数据、预测任务状态及结果,通过Repository类封装数据库操作。 |
任务队列 | Celery + Redis | 处理异步预测任务(如async_forecast_task ),解耦Web服务与耗时计算。 |
模型层 | Scikit-learn模型 | 提供负荷预测能力(随机森林、梯度提升树等),通过predict_api 接口调用。 |
2.3 系统各个模块之间的调用流程
这个流程图展示了一个电力负荷预测系统的完整交互过程,主要包含三个阶段:任务提交
、异步处理
和结果查询
。下面详细解释各阶段的流程和涉及的组件:
-
第一阶段:任务提交流程
- 用户请求:前端用户通过POST请求/api/forecast/submit提交预测任务,携带JWT认证信息。
- 请求传递:请求经WSGI服务器转发到Flask应用。
- 路由匹配:Flask应用通过蓝图机制将请求路由到submit_forecast视图函数。
- 身份验证:视图函数解析JWT获取用户ID。
- 业务处理:调用服务层的create_task方法,传入用户ID和预测时间参数。
- 数据持久化:服务层调用仓库层创建任务记录,初始状态为PENDING。
- 异步任务触发:服务层调用Celery发送异步任务,任务ID作为参数。
- 任务入队:Celery将任务发送到Redis队列,返回任务确认。
- 响应返回:视图立即返回任务ID给用户,告知任务已创建。
-
第二阶段:异步处理流程
- 任务执行:Celery从Redis队列拉取任务。
- 状态更新:更新任务状态为RUNNING。
- 数据读取:服务层从上传目录读取历史电力数据(power_data.csv)。
- 模型预测:调用预测模型执行负荷预测。
- 结果保存:将预测结果存入数据库,更新任务状态为COMPLETED。
-
第三阶段:结果查询流程
- 轮询请求:前端用户通过GET请求/api/forecast/result/task_id查询结果。
- 结果获取:视图函数调用服务层和仓库层查询任务状态和结果。
- 结果返回:将任务状态和预测结果以JSON格式返回给用户。
-
系统组件说明
- 前端用户:发起HTTP请求的客户端。
- WSGI服务器:作为Web服务器和应用程序之间的接口,处理HTTP请求。
- Flask应用:核心Web框架,处理路由和请求分发。
- 蓝图系统:组织和管理路由的模块化机制。
- 视图函数:处理业务逻辑的入口点。
- 服务层:封装核心业务逻辑,协调领域对象完成业务操作。
- 仓库层:负责与数据库交互,实现数据持久化。
- 数据库:存储任务信息和预测结果。
- Celery Worker:执行异步任务的工作进程。
- Redis:作为消息队列存储异步任务,同时存储任务结果。
-
技术要点
- JWT认证:通过解析JWT令牌实现用户身份验证。
- 异步处理:使用Celery和Redis实现任务队列,避免长时间同步等待。
- 状态管理:任务状态从PENDING→RUNNING→COMPLETED的流转。
- 数据流向:数据从CSV文件读取,经模型处理,最终存入数据库。
- 结果获取:采用轮询机制查询异步任务结果。
这个系统设计遵循了领域驱动设计(DDD)的分层架构思想,将业务逻辑与数据访问分离,通过异步处理提升系统吞吐量和用户体验。
三、系统功能
3.1 功能模块图
3.2 核心功能说明
3.2.1 用户认证模块
- 注册:用户通过用户名、密码、邮箱注册,密码经PBKDF2-SHA256哈希存储。
- 登录:验证用户名密码后返回JWT令牌(有效期2小时),后续请求需携带
Authorization: Bearer <token>
头。 - 鉴权:通过
get_current_user_id
函数从JWT解析用户ID,确保数据隔离(如用户仅能操作自己的电力数据)。
3.2.2 数据管理模块
- 数据导入:支持上传Excel文件(仅
.xlsx
),自动解析并存储到power_data
表(包含温度、湿度、负荷值等字段)。 - 数据导出:根据时间范围、分页参数查询数据,生成Excel文件供下载。
- 数据列表:分页查询用户历史电力数据,支持时间范围过滤。
3.2.3 预测任务模块
- 提交任务:用户指定预测年份、月份及模型类型(默认随机森林),系统生成唯一任务ID并异步执行。
- 状态跟踪:任务状态包括
PENDING
(等待)、RUNNING
(执行中)、COMPLETED
(完成)、FAILED
(失败),支持轮询查询。 - 结果查询:返回预测结果(前10高负荷日期及预测值),结果存储为JSON格式。
3.2.4 模型服务模块
- 模型训练:通过
Integrate_model_train.py
脚本完成,支持随机森林、梯度提升树,包含特征工程(滞后特征、日期特征)、超参数调优(GridSearchCV)及模型评估(RMSE、MAE、R²)。 - 实时预测:提供
/api/predict
接口,接收数据路径和模型类型,返回预测结果并存储到数据库及本地CSV。
四、重点技术解析
4.1 Flask框架
- 作用:作为Web服务器处理HTTP请求,通过蓝图(Blueprint)组织路由(如
auth_bp
、data_bp
),支持模块化开发。 - 关键设计:
- 配置管理:通过
config.py
统一管理数据库、路径、JWT等配置,支持开发/生产环境切换。 - 上下文管理:在Celery任务中通过
with app.app_context()
绑定Flask上下文,确保能访问current_app.config
及数据库。 - 异常处理:使用
handle_errors
装饰器统一捕获异常,返回标准化JSON错误信息(400业务错误、500服务器错误)。
- 配置管理:通过
4.2 Celery异步任务
- 作用:将耗时的预测任务(可能30分钟以上)从Web请求中解耦,避免阻塞前端响应。
- 关键配置:
- Broker/Backend:使用Redis(
redis://localhost:6379/0
)作为消息代理(任务队列)和结果存储。 - 任务重试:
async_forecast_task
任务配置max_retries=3
、retry_backoff=2
,失败后自动重试。 - 任务跟踪:通过
CELERY_TASK_TRACK_STARTED
启用任务启动状态跟踪,前端可实时获取RUNNING
状态。
- Broker/Backend:使用Redis(
4.3 机器学习模型
- 算法选择:支持随机森林(RandomForestRegressor)和梯度提升树(GradientBoostingRegressor),通过交叉验证选择最优模型。
- 特征工程:
- 日期特征:年、月、日、周几、年中第几天等。
- 滞后特征:前1-3天的负荷值(
load_lag1
-load_lag3
)。 - 统计特征:7天移动平均负荷(
load_7d_avg
)、温度差(temp_diff
)。
- 模型评估:使用时间序列分割(TimeSeriesSplit)保证数据时序性,评估指标包括RMSE(均方根误差)、MAE(平均绝对误差)、R²(决定系数)。
五、构建与部署步骤
5.1 环境准备
组件 | 版本要求 | 说明 |
---|---|---|
Python | 3.9+ | 需安装pip和venv(建议虚拟环境) |
MySQL | 5.7+或8.0+ | 需创建数据库powerdb (字符集utf8mb4) |
Redis | 6.0+ | 用于Celery的Broker和Backend |
依赖库 | 见requirements.txt | 包括Flask、Celery、pandas、scikit-learn等 |
5.2 代码获取
- 代码下载:代码及文档下载
5.3 配置修改
编辑config.py
调整以下参数(根据实际环境修改):
# 数据库配置
DB_USER = 'your_mysql_user'
DB_PASSWORD = 'your_mysql_password'
DB_HOST = 'your_mysql_host' # 如远程数据库需开放端口# Redis配置(默认本地)
CELERY_BROKER_URL = "redis://your_redis_host:6379/0"
CELERY_RESULT_BACKEND = "redis://your_redis_host:6379/0"
5.4 依赖安装
# 创建并激活虚拟环境(可选)
python -m venv venv
source venv/bin/activate # Linux/macOS
# 或 venv\Scripts\activate # Windows# 安装依赖
pip install -r requirements.txt
5.5 数据库初始化
python run.py # 首次运行会自动创建所有表(需确保MySQL服务已启动)
5.6 模型训练(可选)
# 进入模型目录
cd predict_model
# 运行训练脚本(需先准备训练数据data/power_data.csv)
python Integrate_model_train.py
训练完成后,模型文件将保存到predict_model/model_train_result
目录。
5.7 启动服务
5.7.1 启动Flask应用
python run.py # 监听0.0.0.0:8080,调试模式
启动后,在Pycharm控制台可以看到如下信息:
Flask 传递给 Celery 的 Broker URL: redis://localhost:6379/0
已注册的Flask路由:- /static/<path:filename> → static- /api/auth/login → auth.login- /api/auth/register → auth.register- /api/data/fetchData → data.fetch_data_list- /api/data/export → data.export_data- /api/data/import → data.import_data- /api/data/forecast/fetch → data.fetch_forecast_data- /api/data/forecast/export → data.export_forecast_data- /api/forecast/submit → forecast.submit_forecast- /api/forecast/result/<task_id> → forecast.get_forecast_result- /api/predict/ → predict.predict* Serving Flask app 'app'* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.* Running on all addresses (0.0.0.0)* Running on http://127.0.0.1:8080* Running on http://10.67.20.174:8080
5.7.2 启动Celery Worker
# 新终端窗口,激活虚拟环境后:
python celery_worker.py
# 输出应显示Celery连接的Broker URL(如redis://localhost:6379/0)
启动后,在Pycharm控制台可以看到如下信息:
Flask 传递给 Celery 的 Broker URL: redis://localhost:6379/0
Celery 实际使用的 Broker URL: redis://localhost:6379/0-------------- celery@sujiangming v5.3.6 (emerald-rush)
--- ***** -----
-- ******* ---- Windows-10-10.0.26100-SP0 2025-07-11 17:54:08
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: __main__:0x17c52339990
- ** ---------- .> transport: redis://localhost:6379/0
- ** ---------- .> results: redis://localhost:6379/0
- *** --- * --- .> concurrency: 16 (solo)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- -------------- [queues].> celery exchange=celery(direct) key=celery
[tasks]. async_forecast_task
[2025-07-11 17:54:08,451: WARNING/MainProcess] D:\PycharmProjects\power-forecast-backend\.venv\Lib\site-packages\celery\app\utils.py:203: CDeprecationWarning: The 'CELERY_RESULT_BACKEND' setting is deprecated and scheduled for removal inversion 6.0.0. Use the result_backend insteaddeprecated.warn(description=f'The {setting!r} setting',
[2025-07-11 17:54:08,451: WARNING/MainProcess] Please run `celery upgrade settings path/to/settings.py` to avoid these warnings and to allow a smoother upgrade to Celery 6.0.
[2025-07-11 17:54:08,452: WARNING/MainProcess] D:\PycharmProjects\power-forecast-backend\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.warnings.warn(
[2025-07-11 17:54:08,457: INFO/MainProcess] Connected to redis://localhost:6379/0
[2025-07-11 17:54:08,457: WARNING/MainProcess] D:\PycharmProjects\power-forecast-backend\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.warnings.warn([2025-07-11 17:54:08,460: INFO/MainProcess] mingle: searching for neighbors
[2025-07-11 17:54:09,466: INFO/MainProcess] mingle: all alone
[2025-07-11 17:54:09,472: INFO/MainProcess] celery@desktop-legion ready.
六、前端运行与系统演示
6.1 运行前端
- 将下载下来的源代码中的
power-forecast-frontend
文件夹导入到VSCode或者直接在该文件夹所在路径下打开cmd执行安装和启动服务命令。本文采用是的在VSCode中进行相关操作。 - 在VSCode终端中执行:
npm install
命令进行安装依赖。 - 依赖安装完成后,执行:
npm run serve
命令启动服务。
6.2 系统演示
-
在浏览器中输入:
http://localhost:8081
,首次启动后会进入到系统登录页面,如下图所示:
-
注册账户
-
进入系统首页(即负荷预测页面),选择
月份
-> 选择模型
-> 点击开始预测
按钮进行预测:
如果此时进入到Pycharm控制台下,切换到Celery界面下会看到如下日志,说明异步任务已经正在执行:…… [2025-07-11 18:16:20,409: INFO/MainProcess] Task async_forecast_task[5b06dacb-092a-4e62-b7d6-831efbc0996e] received [2025-07-11 18:16:20,424: INFO/MainProcess] 预测数据路径:D:\PycharmProjects\power-forecast-backend\uploads\power_data.csv [2025-07-11 18:16:21,292: WARNING/MainProcess] D:\PycharmProjects\power-forecast-backend\predict_model\predict_api.py:21: FutureWarning: Series.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead.df['rainfall'] = df['rainfall'].fillna(method='ffill')
-
查看数据管理,可查看当前数据库中电力负荷原始数据,也支持数据的导入和导出:
由于admin01是新用户,默认是没有数据的,上图所示是我点击【导入Excel数据】按钮完成数据导入后的结果。 -
切换预测结果,查看当前用户预测任务的结果:
七、附录:接口清单
路径 | 方法 | 功能 | 参数示例 |
---|---|---|---|
/api/auth/register | POST | 用户注册 | {"username": "test", "password": "123456", "email": "test@example.com"} |
/api/auth/login | POST | 用户登录 | {"username": "test", "password": "123456"} |
/api/data/import | POST | 导入电力数据(Excel) | 表单文件file (.xlsx) |
/api/data/export | GET | 导出电力数据(Excel) | page=1&per_page=10&start_date=2023-01-01&end_date=2023-12-31 |
/api/forecast/submit | POST | 提交预测任务 | {"year": 2024, "month": 5, "modelType": "RandomForestRegressor"} |
/api/forecast/result/<task_id> | GET | 查询任务结果 | - |
/api/predict | POST | 实时预测接口 | {"new_data_path": "/uploads/power_data.csv", "model_type": "RandomForestRegressor"} |
八、其他注意事项
- 依赖检查:确保
requirements.txt
中包含Celery依赖(用户提供的requirements.txt
已包含celery==5.3.6
)。 - 启动顺序:需先启动Redis服务,再启动Flask应用(
run.py
)和Celery Worker(celery_worker.py
)。 - 日志监控:Celery Worker的日志会输出任务执行状态(如
PENDING
→RUNNING
→COMPLETED/FAILED
),可通过日志排查任务异常。
如本文对大家有所帮助,麻烦您动动您发财之手,点赞+收藏,谢谢了!