数据挖掘案例-电力负荷预测
今日课程
-
时间序列预测介绍
-
电力负荷预测项目开发(开发一个基于时间以及历史负荷信息,预测未来负荷的模型)
一、时间序列预测简介
1.什么是时序预测
时间序列预测是一种根据历史时间序列数据来预测未来值的方法。
任务比较好理解,但预测未来并非易事。
预测非常困难,特别是关于未来。——物理学家尼尔斯·波尔(Neils Bohr) 我可以算准天体的运行轨迹,但算不清人性的复杂。——牛顿 哲学家只是解释世界,问题在于改变世界。——卡尔·马克思
2.应用场景
-
金融
-
市场趋势预测:股票价格预测、汇率预测、利率预测
-
资金流量预测:企业资金流量预测、金融机构资金流动性预测
-
宏观经济指标预测:GDP预测、CPI预测
-
-
交通
-
交通流量预测
-
行驶速度预测
-
交通运行指数预测
-
-
能源
-
电力负荷预测
-
新能源产业发电功率预测:风力发电功率预测、光伏发电功率预测
-
能源消费预测:工业能源消费预测、居民能源消费预测
-
能源市场与交易:电力市场价格预测、能源商品交易量预测
-
-
环境
-
大气环境预测:空气质量(PM2.5、PM10、二氧化硫、氮氧化物等污染物浓度)预测、气象(气温、气压、风速、风向、湿度等)预测
-
水环境预测:水质变化(化学需氧量、生化需氧量、氨氮、溶解氧等)预测、河流水文(流量、水位、流速)预测
-
-
...
3.时序预测任务分类
-
单变量单步
根据一个时间序列变量的历史数据来预测该变量未来的一个时间步的值
-
单变量多步
根据一个变量的历史时间序列数据来预测该变量未来多个时间步的值
-
多变量单步
根据多个时间序列变量的历史数据来预测该变量未来的一个时间步的值
-
多变量多步
根据多个时间序列变量的历史数据来预测该变量未来的多个时间步的值
4.算法的选择
4.1基于统计学的经典时序预测算法【了解】
-
统计朴素法:今天的值作为明天的预测值
如果数据集在一段时间内都很稳定,我们想预测第二天的负荷或者价格,可以取前面一天的负荷或者价格,预测第二天的值。这种假设第一个预测点和上一个观察点相等的预测方法就叫朴素法。
-
简单平均法:历史上所有值的平均值作为明天的预测值
虽然在一定时期内出现小幅变动,但每个时间段的平均值确实保持不变。这种情况下,我们可以预测出第二天的价格大致和过去天数的价格平均值一致。这种将预期值等同于之前所有观测点的平均值的预测方法就叫简单平均法
-
移动平均法:历史上一段时间窗口内的平均值作为明天的预测值
我们也经常会遇到这种数据集,比如价格或销售额某段时间大幅上升或下降。如果我们这时用之前的简单平均法,就得使用所有先前数据的平均值,但在这里使用之前的所有数据是说不通的,因此,我们只取最近几个时期的价格平均值。这种这种将预期值等同于之前部分观测点的平均值的预测方法就叫简单平均法
-
简单指数平滑法:历史上的值加权平均作为明天的预测值,加权方法是指数方式(保证近期权重更大,远期权重更小)
相比更早时期内的观测值,近期的观测值赋予更大的权重。按照这种原则工作的方法就叫做简单指数平滑法。它通过加权平均值计算出预测值,其中权重随着观测值从早期到晚期的变化呈指数级下降,最小的权重和最早的观测值相关。
-
霍尔特(Holt)线性趋势法:一个水平方程(Lt),一个趋势方程(Bt),再把二者计算的结果加起来
该方法认为时间序列数据不仅有一个基本的水平值,还存在一个线性的增长或下降趋势,因此通过两个平滑方程来分别估计时间序列的水平和趋势,最后将水平方程与趋势方程组合起来
-
AR自回归模型:历史上一段时间窗口内的值预测出明天的预测值
该方法假设时间序列的当前值可以由其自身的过去值线性表示,利用过去数据中的规律来预测当前或未来的值
-
MA移动平均模型:均值加上白噪声项
假设时间序列的当前值可以由过去的白噪声(随机误差)线性表示。与自回归模型不同,移动平均模型关注的是自回归模型中的误差项的累加
-
ARIMA差分自回归移动平均模型:自回归与移动平均结果之和
较为经典的时间序列预测统计方法,包含了三个部分,即自回归、差分和移动平均。ARIMA模型记作ARIMA(p,d,q),p为自回归项数;q为滑动平均项数,d为使之成为平稳序列所做的差分阶数。
注:以上基于统计学的时序预测算法,使用时需要进行平稳性检验,模型本身进行了平稳性假设与白噪声假设,存在局限性,且通常准确性相对机器学习模型会低。
4.2经典的机器学习算法【熟悉】
-
第一步:加载数据集
-
第二步:数据分析
-
第三步:特征工程(主要工作量),处理成机器学习模型可以学习的二维结构化数据集,并进行特征工程处理
-
第四步:模型训练(回归模型均可,如线性回归、决策树、随机森林、XGBoost、LightGBM、SVM等)
-
第五步:模型评价
-
第六步:模型预测
将时序数据处理成二维的结构化数据集,训练机器学习模型进行预测。
4.3深度学习算法【了解】
时间序列预测本质上也是时序建模类任务,所以自然地想到用RNN类算法(LSTM、GRU等)进行时间序列预测,另外还有基于大模型的iTransformer等
通常使用编解码结构(也称seq2seq)
二、电力负荷预测案例介绍
1.业务背景
电力工业是国民经济发展中的重要基础性能源产业,是保证国民经济和社会持续、稳定、健康的发展的关键。电力工业的发展建设对国家各行业起到至关重要的作用。随着改革开放后中国经济的高速发展,各领域的用电需求在不断激增,推动着电力系统向数字化、智能化转型发展。
随着全球对可再生能源的日益重视以及电力系统结构的转型,传统的负荷预测和电力平衡技术面临着新的挑战和机遇。全球范围内,人们对电力系统的可靠性、经济性和环境友好性的要求日益增加,而这些要求往往受到可再生能源波动性和不确定性的影响。因此,急需解决的关键问题之一是如何准确预测负荷需求,实现电力供需的平衡,并有效整合可再生能源,满足日益增长的电力需求,同时降低碳排放并确保电网稳定运行。
2.需求分析
-
功能需求
基于历史的电力负荷数据,对未来下一个时间步的电力负荷进行预测数据源
-
数据源
包含时间、电力负荷两个字段的历史电力负荷数据
-
技术栈
pandas、matplotlib、sklearn、xgboost
3.实现方法
-
将时序数据特征以及时间特征整合成特征数据,要预测的指标作为目标数据,处理成二维的结构化数据集,训练机器学习模型进行预测。
三、模型开发
xgboost不在sklearn中,需要单独安装。
pip install xgboost==1.2.0 pip install schedule==1.2.2
1.模型基础架构搭建
├─data:保存数据源以及数据分析的图片 ├─log:保存日志 ├─model:保存模型文件 ├─src:项目主要的业务逻辑,包括模型训练文件以及模型预测文件 └─utils:项目中自定义的工具包
2.开发日志工具类(utils/log.py)
import logging
import os
class Logger(object):# 日志级别关系映射level_relations = {'debug': logging.DEBUG,'info': logging.INFO,'warning': logging.WARNING,'error': logging.ERROR,'crit': logging.CRITICAL}
def __init__(self, root_path, log_name, level='info', fmt='%(asctime)s - %(levelname)s: %(message)s'):# 指定日志保存的路径self.root_path = root_path
# 初始logger名称和格式self.log_name = log_name
# 初始格式self.fmt = fmt
# 先声明一个 Logger 对象self.logger = logging.getLogger(log_name)
# 设置日志级别self.logger.setLevel(self.level_relations.get(level))
def get_logger(self):# 指定对应的 Handler 为 FileHandler 对象, 这个可适用于多线程情况path = os.path.join(self.root_path, 'log')os.makedirs(path, exist_ok=True)file_name = os.path.join(path, self.log_name + '.log')rotate_handler = logging.FileHandler(file_name, encoding="utf-8", mode="a")
# Handler 对象 rotate_handler 的输出格式formatter = logging.Formatter(self.fmt)rotate_handler.setFormatter(formatter)
# 将rotate_handler添加到Loggerself.logger.addHandler(rotate_handler)
return self.logger
3.开发通用工具包(utils/common.py)
import pandas as pd
import numpy as np
def data_preprocessing(path):"""1.获取数据源2.时间格式化,转为2024-12-20 09:00:00这种格式3.按时间升序排序4.去重:param path::return:"""# 1.获取数据源data = pd.read_csv(path)# 2.时间格式化data['time'] = pd.to_datetime(data['time']).dt.strftime('%Y-%m-%d %H:%M:%S')# 3.按时间升序排序data.sort_values(by='time', inplace=True)# 4.去重data.drop_duplicates(inplace=True)return data
3.开发模型训练模块(src/train.py)
模型训练的重点与难点:时序数据提取特征,转为二维宽表用于模型训练,如下图所示
-
(1)导包、配置绘图字体
import os
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from utils.log import Logger
from utils.common import data_preprocessing
from xgboost import XGBRegressor
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error
import joblib
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 15
-
(2)定义电力负荷模型类,配置日志,获取数据源
# 定义电力负荷模型类,配置日志,获取数据源
class PowerLoadModel(object):def __init__(self, filename):# 配置日志记录logfile_name = "train_" + datetime.datetime.now().strftime('%Y%m%d%H%M%S')self.logfile = Logger('../', logfile_name).get_logger()# 获取数据源self.data_source = get_data(filename)
-
(3)数据分析
def ana_data(data):"""1.查看数据整体情况2.负荷整体的分布情况3.各个小时的平均负荷趋势,看一下负荷在一天中的变化情况4.各个月份的平均负荷趋势,看一下负荷在一年中的变化情况5.工作日与周末的平均负荷情况,看一下工作日的负荷与周末的负荷是否有区别:param data: 数据源:return:"""data = data.copy(deep=True)# 1.数据整体情况print(data.info())print(data.head())fig = plt.figure(figsize=(20, 32))# 2.负荷整体的分布情况ax1 = fig.add_subplot(411)ax1.hist(data['power_load'], bins=100)ax1.set_title('负荷分布直方图')# 3.各个小时的平均负荷趋势,看一下负荷在一天中的变化情况ax2 = fig.add_subplot(412)data['hour'] = data['time'].str[11:13]data_hour_avg = data.groupby(by='hour', as_index=False)['power_load'].mean()ax2.plot(data_hour_avg['hour'], data_hour_avg['power_load'], color='b', linewidth=2)ax2.set_title('各小时的平均负荷趋势图')ax2.set_xlabel('小时')ax2.set_ylabel('负荷')# 4.各个月份的平均负荷趋势,看一下负荷在一年中的变化情况ax3 = fig.add_subplot(413)data['month'] = data['time'].str[5:7]data_month_avg = data.groupby('month', as_index=False)['power_load'].mean()ax3.plot(data_month_avg['month'], data_month_avg['power_load'], color='r', linewidth=2)ax3.set_title('各月份平均负荷')ax3.set_xlabel('月份')ax3.set_ylabel('平均负荷')# 5.工作日与周末的平均负荷情况,看一下工作日的负荷与周末的负荷是否有区别ax4 = fig.add_subplot(414)data['week_day'] = data['time'].apply(lambda x: pd.to_datetime(x).weekday())data['is_workday'] = data['week_day'].apply(lambda x: 1 if x <= 4 else 0)power_load_workday_avg = data[data['is_workday'] == 1]['power_load'].mean()power_load_holiday_avg = data[data['is_workday'] == 0]['power_load'].mean()ax4.bar(x=['工作日平均负荷', '周末平均负荷'], height=[power_load_workday_avg, power_load_holiday_avg])ax4.set_ylabel('平均负荷')ax4.set_title('工作日与周末的平均负荷对比')plt.savefig('../data/fig/负荷分析图.png')
-
(4)特征工程【重点】
def feature_engineering(data, logger):"""对给定的数据源,进行特征工程处理,提取出关键的特征1.提取出时间特征:月份、小时2.提取出相近时间窗口中的负荷特征:step大小窗口的负荷3.提取昨日同时刻负荷特征4.剔除出现空值的样本5.整理时间特征,并返回:param data: 数据源:param logger: 日志:return:"""logger.info("===============开始进行特征工程处理===============")result = data.copy(deep=True)logger.info("===============开始提取时间特征===================")# 1、提取出时间特征# 1.1提取出对应的小时,用以表示短期的时间特征result['hour'] = result['time'].str[11:13]# 1.2提取出对应的月份,用以表示长期的时间特征result['month'] = result['time'].str[5:7]# 1.3 对时间特征进行one-hot编码# 1.3.1对小时数进行one-hot编码hour_encoding = pd.get_dummies(result['hour'])hour_encoding.columns = ['hour_' + str(i) for i in hour_encoding.columns]# 1.3.2对月份进行one-hot编码month_encoding = pd.get_dummies(result['month'])month_encoding.columns = ['month_' + str(i) for i in month_encoding.columns]# 1.3.3 对one-hot编码后的结果进行拼接result = pd.concat([result, hour_encoding, month_encoding], axis=1)
logger.info("==============开始提取相近时间窗口中的负荷特征====================")# 2指定window_size下的相近时间窗口负荷window_size = 3shift_list = [result['power_load'].shift(i) for i in range(1, window_size + 1)]shift_data = pd.concat(shift_list, axis=1)shift_data.columns = ['前' + str(i) + '小时' for i in range(1, window_size + 1)]result = pd.concat([result, shift_data], axis=1)logger.info("============开始提取昨日同时刻负荷特征===========================")# 3提取昨日同时刻负荷特征# 3.1时间与负荷转为字典time_load_dict = result.set_index('time')['power_load'].to_dict()# 3.2计算昨日相同的时刻result['yesterday_time'] = result['time'].apply(lambda x: (pd.to_datetime(x) - pd.to_timedelta('1d')).strftime('%Y-%m-%d %H:%M:%S'))# 3.3昨日相同的时刻的负荷result['yesterday_load'] = result['yesterday_time'].apply(lambda x: time_load_dict.get(x))# 4.剔除出现空值的样本result.dropna(axis=0, inplace=True)# 5.整理特征列,并返回time_feature_names = list(hour_encoding.columns) + list(month_encoding.columns) + list(shift_data.columns) + ['yesterday_load']logger.info(f"特征列名是:{time_feature_names}")return result, time_feature_names
-
(5)模型训练、评价与保存
def model_train(data, features, logger):"""1.数据集切分2.网格化搜索与交叉验证3.模型实例化4.模型训练5.模型评价6.模型保存:param data: 特征工程处理后的输入数据:param features: 特征名称:param logger: 日志对象:return:"""logger.info("=========开始模型训练===================")# 1.数据集切分x_data = data[features]y_data = data['power_load']# x_train:训练集特征数据# y_train:训练集目标数据# x_test:测试集特征数据# y_test:测试集目标数据x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.3, random_state=22)# # 2.网格化搜索与交叉验证# # 2.1备选的超参数# print("开始网格化搜索")# print(datetime.datetime.now()) # 2024-11-26 15:38:26.898828# param_dict = {# 'n_estimators': [50, 100, 150, 200],# 'max_depth': [3, 6, 9],# 'learning_rate': [0.1, 0.01]# }# # 2.2实例化网格化搜索,配置交叉验证# grid_cv = GridSearchCV(estimator=XGBRegressor(),# param_grid=param_dict, cv=5)# # 2.3网格化搜索与交叉验证训练# grid_cv.fit(x_train, y_train)# # 2.4输出最优的超参数组合# print(grid_cv.best_params_) # {'learning_rate': 0.1, 'max_depth': 6, 'n_estimators': 150}# print("结束网格化搜索")# print(datetime.datetime.now()) # 2024-11-26 15:39:07.216048# logger.info("网格化搜索后找到的最优的超参数组合是:learning_rate: 0.1, max_depth: 6, n_estimators: 150")# 3.模型训练xgb = XGBRegressor(n_estimators=150, max_depth=6, learning_rate=0.1)xgb.fit(x_train, y_train)# 4.模型评价# 4.1模型在训练集上的预测结果y_pred_train = xgb.predict(x_train)# 4.2模型在测试集上的预测结果y_pred_test = xgb.predict(x_test)# 4.3模型在训练集上的MSE、MAPEmse_train = mean_squared_error(y_true=y_train, y_pred=y_pred_train)mae_train = mean_absolute_error(y_true=y_train, y_pred=y_pred_train)print(f"模型在训练集上的均方误差:{mse_train}")print(f"模型在训练集上的平均绝对误差:{mae_train}")# 4.4模型在测试集上的MSE、MAPEmse_test = mean_squared_error(y_true=y_test, y_pred=y_pred_test)mae_test = mean_absolute_error(y_true=y_test, y_pred=y_pred_test)print(f"模型在测试集上的均方误差:{mse_test}")print(f"模型在测试集上的平均绝对误差:{mae_test}")logger.info("=========================模型训练完成=============================")logger.info(f"模型在训练集上的均方误差:{mse_train}")logger.info(f"模型在训练集上的平均绝对误差:{mae_train}")logger.info(f"模型在测试集上的均方误差:{mse_test}")logger.info(f"模型在测试集上的平均绝对误差:{mae_test}")# 5.模型保存joblib.dump(xgb, '../model/xgb.pkl')
-
完整代码
# -*- coding: utf-8 -*-
import os
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from utils.log import Logger
from utils.common import data_preprocessing
from xgboost import XGBRegressor
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error
import joblib
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 15
def ana_data(data):"""1.查看数据整体情况2.负荷整体的分布情况3.各个小时的平均负荷趋势,看一下负荷在一天中的变化情况4.各个月份的平均负荷趋势,看一下负荷在一年中的变化情况5.工作日与周末的平均负荷情况,看一下工作日的负荷与周末的负荷是否有区别:param data: 数据源:return:"""data = data.copy(deep=True)# 1.数据整体情况print(data.info())print(data.head())fig = plt.figure(figsize=(20, 32))# 2.负荷整体的分布情况ax1 = fig.add_subplot(411)ax1.hist(data['power_load'], bins=100)ax1.set_title('负荷分布直方图')# 3.各个小时的平均负荷趋势,看一下负荷在一天中的变化情况ax2 = fig.add_subplot(412)data['hour'] = data['time'].str[11:13]data_hour_avg = data.groupby(by='hour', as_index=False)['power_load'].mean()ax2.plot(data_hour_avg['hour'], data_hour_avg['power_load'], color='b', linewidth=2)ax2.set_title('各小时的平均负荷趋势图')ax2.set_xlabel('小时')ax2.set_ylabel('负荷')# 4.各个月份的平均负荷趋势,看一下负荷在一年中的变化情况ax3 = fig.add_subplot(413)data['month'] = data['time'].str[5:7]data_month_avg = data.groupby('month', as_index=False)['power_load'].mean()ax3.plot(data_month_avg['month'], data_month_avg['power_load'], color='r', linewidth=2)ax3.set_title('各月份平均负荷')ax3.set_xlabel('月份')ax3.set_ylabel('平均负荷')# 5.工作日与周末的平均负荷情况,看一下工作日的负荷与周末的负荷是否有区别ax4 = fig.add_subplot(414)data['week_day'] = data['time'].apply(lambda x: pd.to_datetime(x).weekday())data['is_workday'] = data['week_day'].apply(lambda x: 1 if x <= 4 else 0)power_load_workday_avg = data[data['is_workday'] == 1]['power_load'].mean()power_load_holiday_avg = data[data['is_workday'] == 0]['power_load'].mean()ax4.bar(x=['工作日平均负荷', '周末平均负荷'], height=[power_load_workday_avg, power_load_holiday_avg])ax4.set_ylabel('平均负荷')ax4.set_title('工作日与周末的平均负荷对比')plt.savefig('../data/fig/负荷分析图.png')
def feature_engineering(data, logger):"""对给定的数据源,进行特征工程处理,提取出关键的特征1.提取出时间特征:月份、小时2.提取出相近时间窗口中的负荷特征:step大小窗口的负荷3.提取昨日同时刻负荷特征4.剔除出现空值的样本5.整理时间特征,并返回:param data: 数据源:param logger: 日志:return:"""logger.info("===============开始进行特征工程处理===============")result = data.copy(deep=True)logger.info("===============开始提取时间特征===================")# 1、提取出时间特征# 1.1提取出对应的小时,用以表示短期的时间特征result['hour'] = result['time'].str[11:13]# 1.2提取出对应的月份,用以表示长期的时间特征result['month'] = result['time'].str[5:7]# 1.3 对时间特征进行one-hot编码# 1.3.1对小时数进行one-hot编码hour_encoding = pd.get_dummies(result['hour'])hour_encoding.columns = ['hour_' + str(i) for i in hour_encoding.columns]# 1.3.2对月份进行one-hot编码month_encoding = pd.get_dummies(result['month'])month_encoding.columns = ['month_' + str(i) for i in month_encoding.columns]# 1.3.3 对one-hot编码后的结果进行拼接result = pd.concat([result, hour_encoding, month_encoding], axis=1)
logger.info("==============开始提取相近时间窗口中的负荷特征====================")# 2指定window_size下的相近时间窗口负荷window_size = 3shift_list = [result['power_load'].shift(i) for i in range(1, window_size + 1)]shift_data = pd.concat(shift_list, axis=1)shift_data.columns = ['前' + str(i) + '小时' for i in range(1, window_size + 1)]result = pd.concat([result, shift_data], axis=1)logger.info("============开始提取昨日同时刻负荷特征===========================")# 3提取昨日同时刻负荷特征# 3.1时间与负荷转为字典time_load_dict = result.set_index('time')['power_load'].to_dict()# 3.2计算昨日相同的时刻result['yesterday_time'] = result['time'].apply(lambda x: (pd.to_datetime(x) - pd.to_timedelta('1d')).strftime('%Y-%m-%d %H:%M:%S'))# 3.3昨日相同的时刻的负荷result['yesterday_load'] = result['yesterday_time'].apply(lambda x: time_load_dict.get(x))# 4.剔除出现空值的样本result.dropna(axis=0, inplace=True)# 5.整理特征列,并返回time_feature_names = list(hour_encoding.columns) + list(month_encoding.columns) + list(shift_data.columns) + ['yesterday_load']logger.info(f"特征列名是:{time_feature_names}")return result, time_feature_names
def model_train(data, features, logger):"""1.数据集切分2.网格化搜索与交叉验证3.模型实例化4.模型训练5.模型评价6.模型保存:param data: 特征工程处理后的输入数据:param features: 特征名称:param logger: 日志对象:return:"""logger.info("=========开始模型训练===================")# 1.数据集切分x_data = data[features]y_data = data['power_load']# x_train:训练集特征数据# y_train:训练集目标数据# x_test:测试集特征数据# y_test:测试集目标数据x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.3, random_state=22)# # 2.网格化搜索与交叉验证# # 2.1备选的超参数# print("开始网格化搜索")# print(datetime.datetime.now()) # 2024-11-26 15:38:26.898828# param_dict = {# 'n_estimators': [50, 100, 150, 200],# 'max_depth': [3, 6, 9],# 'learning_rate': [0.1, 0.01]# }# # 2.2实例化网格化搜索,配置交叉验证# grid_cv = GridSearchCV(estimator=XGBRegressor(),# param_grid=param_dict, cv=5)# # 2.3网格化搜索与交叉验证训练# grid_cv.fit(x_train, y_train)# # 2.4输出最优的超参数组合# print(grid_cv.best_params_) # {'learning_rate': 0.1, 'max_depth': 6, 'n_estimators': 150}# print("结束网格化搜索")# print(datetime.datetime.now()) # 2024-11-26 15:39:07.216048# logger.info("网格化搜索后找到的最优的超参数组合是:learning_rate: 0.1, max_depth: 6, n_estimators: 150")# 3.模型训练xgb = XGBRegressor(n_estimators=150, max_depth=6, learning_rate=0.1)xgb.fit(x_train, y_train)# 4.模型评价# 4.1模型在训练集上的预测结果y_pred_train = xgb.predict(x_train)# 4.2模型在测试集上的预测结果y_pred_test = xgb.predict(x_test)# 4.3模型在训练集上的MSE、MAPEmse_train = mean_squared_error(y_true=y_train, y_pred=y_pred_train)mae_train = mean_absolute_error(y_true=y_train, y_pred=y_pred_train)print(f"模型在训练集上的均方误差:{mse_train}")print(f"模型在训练集上的平均绝对误差:{mae_train}")# 4.4模型在测试集上的MSE、MAPEmse_test = mean_squared_error(y_true=y_test, y_pred=y_pred_test)mae_test = mean_absolute_error(y_true=y_test, y_pred=y_pred_test)print(f"模型在测试集上的均方误差:{mse_test}")print(f"模型在测试集上的平均绝对误差:{mae_test}")logger.info("=========================模型训练完成=============================")logger.info(f"模型在训练集上的均方误差:{mse_train}")logger.info(f"模型在训练集上的平均绝对误差:{mae_train}")logger.info(f"模型在测试集上的均方误差:{mse_test}")logger.info(f"模型在测试集上的平均绝对误差:{mae_test}")# 5.模型保存joblib.dump(xgb, '../model/xgb.pkl')
class PowerLoadModel(object):def __init__(self, filename):# 配置日志记录logfile_name = "train_" + datetime.datetime.now().strftime('%Y%m%d%H%M%S')self.logfile = Logger('../', logfile_name).get_logger()# 获取数据源self.data_source = data_preprocessing(filename)
if __name__ == '__main__':# 1.加载数据集input_file = os.path.join('../data', 'train.csv')model = PowerLoadModel(input_file)# 2.分析数据ana_data(model.data_source)# 3.特征工程processed_data, feature_cols = feature_engineering(model.data_source, model.logfile)# 4.模型训练、模型评价与模型保存model_train(processed_data, feature_cols, model.logfile)
4.开发模型预测模块(src/predict.py)
-
(1)导包、配置绘图字体
import os
import pandas as pd
import datetime
from utils.log import Logger
from utils.common import data_preprocessing, mean_absolute_percentage_error
import schedule
import matplotlib.ticker as mick
import joblib
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 15
-
(2)定义电力负荷预测类,配置日志,获取数据源、历史数据转为字典(避免频繁操作dataframe,提高效率)
class PowerLoadPredict(object):def __init__(self, filename):# 配置日志记录logfile_name = "predict_" + datetime.datetime.now().strftime('%Y%m%d%H%M%S')self.logfile = Logger('../', logfile_name).get_logger()# 获取数据源self.data_source = data_preprocessing(filename)# 历史数据转为字典,key:时间,value:负荷self.data_dict = self.data_source.set_index('time')['power_load'].to_dict()
input_file = os.path.join('../data', 'test.csv')
pred_obj = PowerLoadPredict(input_file)
-
(3)加载模型
model = joblib.load('../model/xgb.pkl')
-
(4)模型预测
-
特征解析
-
def pred_feature_extract(data_dict, time, logger):"""预测数据解析特征,保持与模型训练时的特征列名一致1.解析时间特征2.解析时间窗口特征3.解析昨日同时刻特征:param data_dict:历史数据,字典格式,key:时间,value:负荷:param time:预测时间,字符串类型,格式为2024-12-20 09:00:00:param logger:日志对象:return:"""logger.info(f'=========解析预测时间为:{time}所对应的特征==============')# 特征列清单feature_names = ['hour_00', 'hour_01', 'hour_02', 'hour_03', 'hour_04', 'hour_05','hour_06', 'hour_07', 'hour_08', 'hour_09', 'hour_10', 'hour_11','hour_12', 'hour_13', 'hour_14', 'hour_15', 'hour_16', 'hour_17','hour_18', 'hour_19', 'hour_20', 'hour_21', 'hour_22', 'hour_23','month_01', 'month_02', 'month_03', 'month_04', 'month_05', 'month_06','month_07', 'month_08', 'month_09', 'month_10', 'month_11', 'month_12','前1小时', '前2小时', '前3小时', 'yesterday_load']# 小时特征数据,使用列表保存起来hour_part = []pred_hour = time[11:13]for i in range(24):if pred_hour == feature_names[i][5:7]:hour_part.append(1)else:hour_part.append(0)# 月份特征数据,使用列表保存起来month_part = []pred_month = time[5:7]for i in range(24, 36):if pred_month == feature_names[i][6:8]:month_part.append(1)else:month_part.append(0)# 历史负荷数据,使用列表保存起来his_part = []# 前1小时负荷last_1h_time = (pd.to_datetime(time) - pd.to_timedelta('1h')).strftime('%Y-%m-%d %H:%M:%S')last_1h_load = data_dict.get(last_1h_time, 600)# 前2小时负荷last_2h_time = (pd.to_datetime(time) - pd.to_timedelta('2h')).strftime('%Y-%m-%d %H:%M:%S')last_2h_load = data_dict.get(last_2h_time, 600)# 前3小时负荷last_3h_time = (pd.to_datetime(time) - pd.to_timedelta('3h')).strftime('%Y-%m-%d %H:%M:%S')last_3h_load = data_dict.get(last_3h_time, 600)
# 昨日同时刻负荷last_day_time = (pd.to_datetime(time) - pd.to_timedelta('1d')).strftime('%Y-%m-%d %H:%M:%S')last_day_load = data_dict.get(last_day_time, 600)
his_part = [last_1h_load, last_2h_load, last_3h_load, last_day_load]# 特征数据,包含小时特征数据,月份特征数据,历史负荷数据feature_list = [hour_part + month_part + his_part]# feature_list需要转成dataframe并返回,所以这里用append变成一个二维列表feature_df = pd.DataFrame(feature_list, columns=feature_names)return feature_df, feature_names
-
模型预测主逻辑
if __name__ == '__main__':"""模型预测1.导包、配置绘图字体2.定义电力负荷预测类,配置日志,获取数据源、历史数据转为字典(避免频繁操作dataframe,提高效率)3.加载模型4.模型预测4.1 确定要预测的时间段(2015-08-01 00:00:00及以后的时间)4.2 为了模拟实际场景的预测,把要预测的时间以及以后的负荷都掩盖掉,因此新建一个数据字典,只保存预测时间以前的数据字典4.3 预测负荷4.3.1 解析特征(定义解析特征方法)4.3.2 利用加载的模型预测4.4 保存预测时间对应的真实负荷4.5 结果保存到evaluate_list,三个元素分别是预测时间、真实负荷、预测负荷,方便后续进行预测结果评价4.6 循环结束后,evaluate_list转为DataFrame5.预测结果评价5.1 计算预测结果与真实结果的MAE5.2 绘制折线图(预测时间-真实负荷折线图,预测时间-预测负荷折线图),查看预测效果 """# 2.定义电力负荷预测类(PowerLoadPredict),配置日志,获取数据源、历史数据转为字典(避免频繁操作dataframe,提高效率)input_file = os.path.join('../data', 'test.csv')pred_obj = PowerLoadPredict(input_file)# 3.加载模型model = joblib.load('../model/xgb.pkl')# 4.模型预测evaluate_list = []# 4.1确定要预测的时间段:2015-08-01 00:00:00及以后的时间pred_times = pred_obj.data_source[pred_obj.data_source['time'] >= '2015-08-01 00:00:00']['time']for pred_time in pred_times:print(f"开始预测时间为:{pred_time}的负荷")pred_obj.logfile.info(f"开始预测时间为:{pred_time}的负荷")# 4.2为了模拟实际场景的预测,把要预测的时间以及以后的负荷都掩盖掉,因此新建一个数据字典,只保存预测时间以前的数据字典data_his_dict = {k: v for k, v in pred_obj.data_dict.items() if k < pred_time}# 4.3预测负荷# 4.3.1解析特征processed_data, feature_cols = pred_feature_extract(data_his_dict, pred_time, pred_obj.logfile)# 4.3.2 模型预测pred_value = model.predict(processed_data[feature_cols])# 4.4真实负荷true_value = pred_obj.data_dict.get(pred_time)pred_obj.logfile.info(f"真实负荷为:{true_value}, 预测负荷为:{pred_value}")# 4.5结果保存到evaluate_list,三个元素分别是预测时间、真实负荷、预测负荷evaluate_list.append([pred_time, true_value, pred_value[0]])# 4.6evaluate_list转为DataFrameevaluate_df = pd.DataFrame(evaluate_list, columns=['时间', '真实值', '预测值'])
-
(5)模型结果评价
def prediction_plot(data):"""绘制时间与预测负荷折线图,时间与真实负荷折线图,展示预测效果:param data: 数据一共有三列:时间、真实值、预测值:return:"""# 绘制在新数据下fig = plt.figure(figsize=(40, 20))ax = fig.add_subplot()# 绘制时间与真实负荷的折线图ax.plot(data['时间'], data['真实值'], label='真实值')# 绘制时间与预测负荷的折线图ax.plot(data['时间'], data['预测值'], label='预测值')ax.set_ylabel('负荷')ax.set_title('预测负荷以及真实负荷的折线图')# 横坐标时间若不处理太过密集,这里调大时间展示的间隔ax.xaxis.set_major_locator(mick.MultipleLocator(50))# 时间展示时旋转45度plt.xticks(rotation=45)plt.legend()plt.savefig('../data/fig/预测效果.png')
# 5.预测结果评价
# 5.1计算预测结果与真实结果的MAE
mae_score = mean_absolute_error(evaluate_df['真实值'], evaluate_df['预测值'])
print(f"模型对新数据进行预测的平均绝对误差:{mae_score}")
pred_obj.logfile.info(f"模型对新数据进行预测的平均绝对误差:{mae_score}")
# 5.2绘制折线图,查看预测效果
prediction_plot(evaluate_df)
-
完整代码
# -*- coding: utf-8 -*-
import os
import pandas as pd
import numpy as np
import datetime
from utils.log import Logger
from utils.common import data_preprocessing
from sklearn.metrics import mean_absolute_error
import matplotlib.ticker as mick
import joblib
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 15
def pred_feature_extract(data_dict, time, logger):"""预测数据解析特征,保持与模型训练时的特征列名一致1.解析时间特征2.解析时间窗口特征3.解析昨日同时刻特征:param data_dict:历史数据,字典格式,key:时间,value:负荷:param time:预测时间,字符串类型,格式为2024-12-20 09:00:00:param logger:日志对象:return:"""logger.info(f'=========解析预测时间为:{time}所对应的特征==============')# 特征列清单feature_names = ['hour_00', 'hour_01', 'hour_02', 'hour_03', 'hour_04', 'hour_05','hour_06', 'hour_07', 'hour_08', 'hour_09', 'hour_10', 'hour_11','hour_12', 'hour_13', 'hour_14', 'hour_15', 'hour_16', 'hour_17','hour_18', 'hour_19', 'hour_20', 'hour_21', 'hour_22', 'hour_23','month_01', 'month_02', 'month_03', 'month_04', 'month_05', 'month_06','month_07', 'month_08', 'month_09', 'month_10', 'month_11', 'month_12','前1小时', '前2小时', '前3小时', 'yesterday_load']# 小时特征数据,使用列表保存起来hour_part = []pred_hour = time[11:13]for i in range(24):if pred_hour == feature_names[i][5:7]:hour_part.append(1)else:hour_part.append(0)# 月份特征数据,使用列表保存起来month_part = []pred_month = time[5:7]for i in range(24, 36):if pred_month == feature_names[i][6:8]:month_part.append(1)else:month_part.append(0)# 历史负荷数据,使用列表保存起来his_part = []# 前1小时负荷last_1h_time = (pd.to_datetime(time) - pd.to_timedelta('1h')).strftime('%Y-%m-%d %H:%M:%S')last_1h_load = data_dict.get(last_1h_time, 600)# 前2小时负荷last_2h_time = (pd.to_datetime(time) - pd.to_timedelta('2h')).strftime('%Y-%m-%d %H:%M:%S')last_2h_load = data_dict.get(last_2h_time, 600)# 前3小时负荷last_3h_time = (pd.to_datetime(time) - pd.to_timedelta('3h')).strftime('%Y-%m-%d %H:%M:%S')last_3h_load = data_dict.get(last_3h_time, 600)
# 昨日同时刻负荷last_day_time = (pd.to_datetime(time) - pd.to_timedelta('1d')).strftime('%Y-%m-%d %H:%M:%S')last_day_load = data_dict.get(last_day_time, 600)
his_part=[last_1h_load, last_2h_load, last_3h_load, last_day_load]# 特征数据,包含小时特征数据,月份特征数据,历史负荷数据feature_list = [hour_part + month_part + his_part]# feature_list需要转成dataframe并返回,所以这里用append变成一个二维列表feature_df = pd.DataFrame(feature_list, columns=feature_names)return feature_df, feature_names
def prediction_plot(data):"""绘制时间与预测负荷折线图,时间与真实负荷折线图,展示预测效果:param data: 数据一共有三列:时间、真实值、预测值:return:"""# 绘制在新数据下fig = plt.figure(figsize=(40, 20))ax = fig.add_subplot()# 绘制时间与真实负荷的折线图ax.plot(data['时间'], data['真实值'], label='真实值')# 绘制时间与预测负荷的折线图ax.plot(data['时间'], data['预测值'], label='预测值')ax.set_ylabel('负荷')ax.set_title('预测负荷以及真实负荷的折线图')# 横坐标时间若不处理太过密集,这里调大时间展示的间隔ax.xaxis.set_major_locator(mick.MultipleLocator(50))# 时间展示时旋转45度plt.xticks(rotation=45)plt.legend()plt.savefig('../data/fig/预测效果.png')
class PowerLoadPredict(object):def __init__(self, filename):# 配置日志记录logfile_name = "predict_" + datetime.datetime.now().strftime('%Y%m%d%H%M%S')self.logfile = Logger('../', logfile_name).get_logger()# 获取数据源self.data_source = data_preprocessing(filename)# 历史数据转为字典,key:时间,value:负荷,目的是为了避免频繁操作dataframe,提高效率。实际开发场景中可以使用redis进行缓存self.data_dict = self.data_source.set_index('time')['power_load'].to_dict()
if __name__ == '__main__':"""模型预测1.导包、配置绘图字体2.定义电力负荷预测类,配置日志,获取数据源、历史数据转为字典(避免频繁操作dataframe,提高效率)3.加载模型4.模型预测4.1 确定要预测的时间段(2015-08-01 00:00:00及以后的时间)4.2 为了模拟实际场景的预测,把要预测的时间以及以后的负荷都掩盖掉,因此新建一个数据字典,只保存预测时间以前的数据字典4.3 预测负荷4.3.1 解析特征(定义解析特征方法)4.3.2 利用加载的模型预测4.4 保存预测时间对应的真实负荷4.5 结果保存到evaluate_list,三个元素分别是预测时间、真实负荷、预测负荷,方便后续进行预测结果评价4.6 循环结束后,evaluate_list转为DataFrame5.预测结果评价5.1 计算预测结果与真实结果的MAE5.2 绘制折线图(预测时间-真实负荷折线图,预测时间-预测负荷折线图),查看预测效果 """# 2.定义电力负荷预测类(PowerLoadPredict),配置日志,获取数据源、历史数据转为字典(避免频繁操作dataframe,提高效率)input_file = os.path.join('../data', 'test.csv')pred_obj = PowerLoadPredict(input_file)# 3.加载模型model = joblib.load('../model/xgb.pkl')# 4.模型预测evaluate_list = []# 4.1确定要预测的时间段:2015-08-01 00:00:00及以后的时间pred_times = pred_obj.data_source[pred_obj.data_source['time'] >= '2015-08-01 00:00:00']['time']for pred_time in pred_times:print(f"开始预测时间为:{pred_time}的负荷")pred_obj.logfile.info(f"开始预测时间为:{pred_time}的负荷")# 4.2为了模拟实际场景的预测,把要预测的时间以及以后的负荷都掩盖掉,因此新建一个数据字典,只保存预测时间以前的数据字典data_his_dict = {k: v for k, v in pred_obj.data_dict.items() if k < pred_time}# 4.3预测负荷# 4.3.1解析特征processed_data, feature_cols = pred_feature_extract(data_his_dict, pred_time, pred_obj.logfile)# 4.3.2 模型预测pred_value = model.predict(processed_data[feature_cols])# 4.4真实负荷true_value = pred_obj.data_dict.get(pred_time)pred_obj.logfile.info(f"真实负荷为:{true_value}, 预测负荷为:{pred_value}")# 4.5结果保存到evaluate_list,三个元素分别是预测时间、真实负荷、预测负荷evaluate_list.append([pred_time, true_value, pred_value])# 4.6evaluate_list转为DataFrameevaluate_df = pd.DataFrame(evaluate_list, columns=['时间', '真实值', '预测值'])# 5.预测结果评价# 5.1计算预测结果与真实结果的MAEmae_score = mean_absolute_error(evaluate_df['真实值'], evaluate_df['预测值'])print(f"模型对新数据进行预测的平均绝对误差:{mae_score}")pred_obj.logfile.info(f"模型对新数据进行预测的平均绝对误差:{mae_score}")# 5.2绘制折线图,查看预测效果prediction_plot(evaluate_df)
四、改进方向
1.特征工程角度
-
优化时间窗口
-
提取更有效的历史负荷特征
-
扩展外部特征,比如温度、湿度、风速、历史工业用电量、历史居民用电量等
2.算法角度
-
样本分群然后分别建模,比如分地区或者借助聚类算法先进行分群,然后针对不同分区分别训练模型,提升模型的适用性
-
寻找更优的算法,比如LightGBM、RNN类、iTransformer等算法
-
寻找更优的算法组合,比如bagging方式或stacking方式进行模型组合
3.预测(推理)速度角度
-
预测时也需要特征工程处理,历史负荷可以缓存到redis,使用时直接查询
4.扩展性角度
-
做通用的工具包,适用于各种数据源的输入输出,如mysql、pgsql、oracle、ES、redis、Hive等数据库的支持
-
项目打包成容器,适配各种服务器环境
-
预测模块与项目解耦,预测模块封装出接口,接收web传过来的参数,根据参数获取数据并进行预测
相关文章:
数据挖掘案例-电力负荷预测
今日课程 时间序列预测介绍 电力负荷预测项目开发(开发一个基于时间以及历史负荷信息,预测未来负荷的模型) 一、时间序列预测简介 1.什么是时序预测 时间序列预测是一种根据历史时间序列数据来预测未来值的方法。 任务比较好理解&#…...
SQL Server中OPENJSON + WITH 来解析JSON
一、概念 OPENJSON 是 SQL Server(2016 及更高版本) 中引入的一个表值函数,它将 JSON 文本转换为行和列的关系型数据结构。通过添加 WITH 子句,可以明确指定返回数据的结构和类型,实现 JSON 数据到表格数据的精确映射…...
在 Linux 中判断当前网络类型与网卡类型的实用方法(内外网判断 + 网卡分类)
在日常使用 Linux(例如 Jetson、树莓派、服务器)过程中,我们经常会遇到以下几个问题: 如何知道系统当前是走 有线网络还是无线网络?如何判断是连接了 公网还是内网?169.254.x.x 是什么?为什么我…...
Docker compose入门
目录 Docker Compose简介安装docker compose局限一 适合单机部署,不适合生产环境1. 架构设计目标不同2. 关键功能对比3. 生产环境的核心需求4. 适用场景总结5. 为什么 Compose 不适合生产? Docker Compose 简介 Docker Compose 是一个用于简化多容器Do…...
Docker Search 和 Docker Pull 失效解决
目录 1. Docker Search 1.1 问题描述 1.2 解决方案 1.2.1 方案1 命令行方式 1.2.2 方案2 非命令行方式 2. Docker Pull 2.1 问题描述 2.2 解决方案 2.2.1 替换镜像源 2.2.1.1 编辑镜像源(linux)版 2.2.1.2 编辑镜像源(windows版本…...
Langchain Agent封装的工具
LangChain Agent Tools 参考文档 本文档详细介绍了LangChain框架中可用的Agent工具及其使用方法。这些工具可以赋予AI智能体与外部系统和服务交互的能力,从而构建功能更强大的应用程序。 目录 工具加载方法基础工具文件和系统工具搜索和信息检索工具语言模型增强…...
Windows11删除文件时弹出提示“没有管理员权限”,怎么办?
Windows11删除文件时弹出提示“没有管理员权限”,怎么办? 原因:文件没有读取到完全控制的权限。 解决方法:点击开始-设置-账户,检查Windows是否登录管理员账户,必须登录管理员账户。然后回到电脑桌面&…...
使用HTML + CSS + JS,编写一个台球追分计分器
目录 一.代码 二.效果展示 三.该计分器的优点 一.代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...
CS5346 - CHARTS: Chart with Point / Bar / Line / Box
文章目录 Chart with Point(点图)Scatter Chart(散点图)Pictogram(图标)Connected Scatter PlotConnected Dot plot(连接点图)Bubble Chart(气泡图) Chart wi…...
CNN实现简易教程
一、CNN基础回顾与设计原则 在开始实践之前,我们先快速回顾CNN的核心组件和设计原则,这将帮助你理解后续的代码和设计决策。 1. CNN的核心组件 卷积层(Convolutional Layer):通过卷积核提取局部特征(如边缘、纹理)。主要参数包括: 输入通道数(in_channels):输入数…...
Flask(1): 在windows系统上部署项目1
1 前言 学习python也有段时间了,最近一个小项目要部署,正好把过程写下来。 在程序的结构上我选择了w/s模式,相比于c/s模式,无需考虑客户端的升级;框架我选择了flask,就是冲着轻量级去的,就是插件…...
Zookeeper 可观测性最佳实践
Zookeeper 介绍 ZooKeeper 是一个开源的分布式协调服务,用于管理和协调分布式系统中的节点。它提供了一种高效、可靠的方式来解决分布式系统中的常见问题,如数据同步、配置管理、命名服务和集群管理等。本文介绍通过 DataKit 采集 Zookeeper 指标&#…...
vs2022使用git方法
1、创建git 2、在cmd下执行 git push -f origin master ,会把本地代码全部推送到远程,同时会覆盖远程代码。 3、需要设置【Git全局设置】,修改的代码才会显示可以提交,否则是灰色的不能提交。 4、创建的分支,只要点击…...
【探商宝】跨境关税博弈下的技术破局:从头部平台现象看数字贸易体系重构
2025年4月,某头部跨境电商平台在北美市场上演了一场教科书级的技术突围战:其移动应用在72小时内从应用商店总榜300名开外飙升至第2位,单日下载量暴增近10倍。这场现象级爆发的背后,是关税政策与数字技术深度博弈的集中呈现。作为开…...
DeepSeek是否支持动态模态选择?揭秘多模态AI的智能切换能力
什么是动态模态选择? 想象一下你在和AI助手聊天: “帮我看看这张图片里有什么?”——AI切到视觉模式 “把图片内容写成300字总结”——切回文本模式 “再把它翻译成英文语音”——切到语音模式 这种根据任务需求自动切换处理模式的能力就是…...
Qwen2.5-Omni 部署框架选择指南:PyTorch vs. TensorFlow 深度对比
目录 一、核心结论:优先选择 PyTorch 方案 二、框架技术对比 1. 官方支持度 2. 性能基准测试(RTX 4090) 3. 关键功能支持 三、环境配置详解 1. PyTorch 推荐方案 系统配置 关键依赖 验证CUDA可用性 2. TensorFlow 替代方案&#x…...
全栈工程师角色介绍
全栈工程师(Full Stack Engineer)是一种综合型技术角色,具备从前端到后端、数据库、服务器运维等多领域的开发能力,并能独立完成产品全生命周期的构建与维护。其核心定义可从以下维度展开: 一、核心定义 技术广度与深…...
从零起步的Kaggle竞赛 - BirdCLEF2025
一个优秀的coder,先从CV工程开始...... 首先复制了 LB 0.804- EfficientNet B0 Pytorch Pipeline | Kaggle 这个notebook并尝试提交,ok,0.804 下载了大佬的代码试图在本地修改模型结构并训练。 以下是大佬的notebook中的代码,可…...
基于CNN+ViT的蔬果图像分类实验
本文只是做一个简单融合的实验,没有任何新颖,大家看看就行了。 1.数据集 本文所采用的数据集为Fruit-360 果蔬图像数据集,该数据集由 Horea Mureșan 等人整理并发布于 GitHub(项目地址:Horea94/Fruit-Images-Datase…...
MySQL SQL 执行顺序(理论顺序)
示例 SQL: SELECT name, COUNT(*) FROM users WHERE age > 18 GROUP BY name HAVING COUNT(*) > 1 ORDER BY name ASC LIMIT 10;虽然语句是从 SELECT 写起的,但执行顺序其实是这样的: 执行顺序SQL 子句作用说明①FROM确定查询的…...
用Allan Deviation的方式估计长时间频率偏差
在电路设计中,若需要评估OSC长时间的偏差(秒级别),观测的时间越多,低频噪声1/f上载的越厉害,如何通过PhaseNoise去有效估计长时间的偏差呢?...
无人机避障与目标识别技术分析!
一、无人机避障技术 1. 技术实现方式 传感器融合: 视觉传感(RGB/双目/红外相机):基于SLAM(同步定位与地图构建)实现环境建模,但依赖光照条件。 激光雷达(LiDAR)&…...
2025年渗透测试面试题总结-拷打题库01(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 2025年渗透测试面试题总结-拷打题库01 1. PHP爆绝对路径方法? 2. 渗透工具及最常用工具 3…...
大厂面试:六大排序
前言 本篇博客集中了冒泡,选择,二分插入,快排,归并,堆排,六大排序算法 如果觉得对你有帮助,可以点点关注,点点赞,谢谢你! 1.冒泡排序 //冒泡排序ÿ…...
Python爬虫第15节-2025今日头条街拍美图抓取实战
目录 一、项目背景与概述 二、环境准备与工具配置 2.1 开发环境要求 2.2 辅助工具配置 三、详细抓取流程解析 3.1 页面加载机制分析 3.2 关键请求识别技巧 3.3 参数规律深度分析 四、爬虫代码实现 五、实现关键 六、法律与道德规范 一、项目概述 在当今互联网时代&a…...
std::map gdb调试ok ,直接运行会crash
在使用 std::map 并且在调试模式下没有问题,但在直接运行时出现崩溃(crash)的情况,通常是由于以下几个原因引起的: 未初始化的变量使用:在调试模式下,某些变量可能因为调试工具(如 G…...
【2025年泰迪杯数据挖掘挑战赛】A题 数据分析+问题建模与求解+Python代码直接分享
目录 2025年泰迪杯数据挖掘挑战赛A题完整论文:建模与求解Python代码1问题一的思路与求解1.1 问题一的思路1.1.1对统计数据进行必要说明:1.1.2统计流程:1.1.3特殊情况的考虑: 1.2 问题一的求解1.2.1代码实现1.2.2 问题一结果代码分…...
git在分支上会退到某个指定的commit
1、在idea上先备份好分支(基于现有分支new branch) 2、在gitlab管理端删除现有分支 3、在idea中大卡terminal,执行 git log 查看commit log ,找到要会退到的commit唯一码,然后执行git reset 唯一码 4、查看本地代码状态 git st…...
Cursor入门教程-JetBrains过度向
Cursor使用笔记 **前置:**之前博主使用的是JetBrains的IDE,VSCode使用比较少,所以会尽量朝着JetBrains的使用习惯及样式去调整。 一、设置语言为中文 如果刚上手Cursor,那么肯定对Cursor中的众多选项配置项不熟悉,这…...
MySQL之text字段详细分类说明
在 MySQL 中,TEXT 是用来存储大量文本数据的数据类型。TEXT 类型可以存储非常长的字符串,比 VARCHAR 类型更适合存储大块的文本数据。TEXT 数据类型分为以下几个子类型,每个子类型用于存储不同大小范围的文本数据: TINYTEXT: 可以…...
为什么 Transformer 要使用多头注意力机制?
简而言之,多头注意力机制可以让模型从不同的在空间中并行地捕捉到不同的特征关系,从而更全面,更灵活地理解序列中的信息。 举个例子,如果要看一幅画,就不能简单地只关注例如颜色,还要关注到结构࿰…...
Python项目--基于Python的自然语言处理文本摘要系统
1. 项目概述 自然语言处理(NLP)是人工智能领域中一个重要的研究方向,而文本摘要作为NLP的一个重要应用,在信息爆炸的时代具有重要意义。本项目旨在开发一个基于Python的文本摘要系统,能够自动从长文本中提取关键信息,生成简洁而全…...
【Web APIs】JavaScript 操作多个元素 ③ ( 鼠标经过高亮显示 | onmouseover 事件设置 | onmouseout 事件设置 )
文章目录 一、核心要点解析 - 鼠标经过高亮显示1、案例需求2、获取高亮显示的 列表行3、鼠标经过 onmouseover 事件设置4、鼠标离开 onmouseout 事件设置5、设置高亮方式 二、完整代码示例1、完整代码示例2、执行结果 一、核心要点解析 - 鼠标经过高亮显示 1、案例需求 案例需求…...
金融的未来
1. DeFi的爆发式增长与核心使命 DeFi(去中心化金融)的使命是重构传统金融基础设施,通过区块链技术实现更高的透明度、可访问性、效率、便利性和互操作性。其增长数据印证了这一趋势: TVL(总锁定价值)爆炸…...
[ElasticSearch]Suggest查询建议(自动补全纠错)
概述 搜索一般都会要求具有“搜索推荐”或者叫“搜索补全”的功能,即在用户输入搜索的过程中,进行自动补全或者纠错。以此来提高搜索文档的匹配精准度,进而提升用户的搜索体验,这就是Suggest。 四种Suggester 1 Term Suggester…...
GPT-4.1 提示词使用指南
GPT-4.1 提示词使用指南 参考:https://cookbook.openai.com/examples/gpt4-1_prompting_guide 为什么要关注 GPT-4.1 提示词使用指南? GPT-4.1 比其前代模型 GPT-4o 更倾向于严格跟随指令,而不是像 GPT-4o 那样更自由地推断用户和系统提示…...
es6面试常见问题╮(╯▽╰)╭
ES6(ECMAScript 2015)的一些常见面试问题,涵盖了变量声明、箭头函数、模板字符串、解构赋值、模块化、类、Promise、生成器等关键特性。有些面试就是问问,对老程序员面试其实不问这么多╮(╯▽╰)╭ 文章目录 **1. 变量声明****1.1 `let` 和 `const` 与 `var` 的区别是什么…...
Xenomai 如何实现 <10μs 级抖动控制
1. 抖动(Jitter)的定义与重要性 1.1 什么是抖动? 在实时控制系统中,抖动(Jitter)指任务实际执行时间与预期周期时间的偏差。例如: • 设定一个任务每 100μs 运行一次,但实际运行时间…...
前端基础常见的算法
你整理的这些前端常见算法知识点挺实用的,适合复习或面试准备。下面我帮你稍微整理美化一下格式,并补充一点细节,让内容更清晰易读: 1. 排序算法 冒泡排序(Bubble Sort) 原理:通过重复比较相邻元…...
RPA机器人技术原理初探
RPA(Robotic Process Automation,机器人流程自动化)通过模拟人类操作界面元素来实现自动化任务,其技术原理可分为以下核心模块: 一、基础技术架构 界面元素识别技术 选择器(Selector)引擎&#…...
AWS CloudFront加速S3配置跨域
1、点击分配 源我们就选择S3–>选择我们要加速的S3存储桶 2、创建OAC访问方式 在我们的来源访问处–>来源访问控制设置(推荐)–>选择创建新的OAC(Create new OAC)–>自定义名字按默认选项保存–>选择刚刚新创建的OAC 3、选择查看器的配置 根据具体情况&#x…...
58.最后一个单词的长度
目录 一、问题描述 二、解题思路 三、代码 四、复杂度分析 一、问题描述 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 二、解题思…...
leetcode_344.反转字符串_java
344. 反转字符串 1、题目 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1: 输入:…...
Android --- FrameWork 入门:极速上手AOSP
文章目录 一、硬件要求二、虚拟机安装三、开发环境搭建四、下载编译源码 一、硬件要求 CPU不低于6核心,建议8核及以上 内存不低于32G,建议64G 存储空间不低于500G,建议 1TB SSD 二、虚拟机安装 1.下载ubuntu,官网网址如下: releases.ubuntu.com/focal…...
“大湾区珠宝艺境花园”璀璨绽放第五届消博会
2025年4月13日,第五届中国国际消费品博览会(以下简称"消博会")重要主题活动——《大湾区珠宝艺境花园》启动仪式在海南国际会展中心2号馆隆重举行。由广东省金银珠宝玉器业厂商会组织带领粤港澳大湾区优秀珠宝品牌,以“…...
Spring Boot系列之使用Arthas Tunnel Server 进行远程调试实践
Spring Boot系列之使用Arthas Tunnel Server 进行远程调试实践 前言 在开发和运维 Java 应用的过程中,远程诊断和调试是一个不可或缺的需求。尤其是当生产环境出现问题时,能够快速定位并解决这些问题至关重要。Arthas 是阿里巴巴开源的一款强大的 Java…...
ILGPU的核心功能使用详解
什么是ILGPU? ILGPU 是一种用于高性能 GPU 程序的新型 JIT(即时)编译器 (也称为 kernels)编写的 .基于 Net 的语言。ILGPU 完全 用 C# 编写,没有任何原生依赖项,允许您编写 GPU 真正可移植的程序。…...
Ubuntu服务器日志满audit:backlog limit exceeded了会报错解决方案-Linux 审计系统 (auditd) 工具
auditd 是 Linux 系统中的审计守护进程,负责收集、记录和监控系统安全相关事件。以下是相关工具及其功能: 核心组件 auditd - 审计守护进程 系统的审计服务主程序 收集系统调用信息并写入日志文件 通常存储在 /var/log/audit/audit.log auditctl - 审计控…...
数据加载与保存
通用方式 SparkSQL提供了通用的数据加载方式,使用spark.read.loa方法,并可通过format指定数据类型(如csv、jdbc、json、orc、parquet、textFile)。 load方法后需传入数据路径(针对csv、jdbc、json、orc、parquet、…...
TODO!! IM项目2
感觉似乎部署好了 真不容易 mysql、redis、 rocketmq(nameserver、broker)、nginx 看代码里是mybatisplus、netty->protobuf协议 现在还发不出去消息 每个密码都要改对 现在可以发消息了但不能at 房间成员也没有 broker内存不够? 从…...