资讯详情

资讯详情

电力时序数据清洗与特征工程实战:从抄表断点到负荷惯性建模

简介本资源是一套面向高校大数据与Python课程设计的电量预测实践项目聚焦国民经济运行中的关键指标——全社会用电量预测问题适用于具备基础Python编程与机器学习知识的学生及初阶数据分析师。资源包共9个文件含4份课程实践报告DOC格式、3篇技术论文PDF格式、1个核心预测脚本py及1个真实时序数据集PJME_hourly.csv整体9.19MB结构清晰、文档与代码配套完整便于理解建模逻辑与复现实验。已有1379人学习下载覆盖数据采集整理、XGBoost特征重要性分析、多模型对比验证等全流程环节特别提供梯度提升树在售电量预测中的落地应用案例及算法创新说明兼具教学规范性与工程参考价值。1. 电量预测不是“看天吃饭”而是用真实电力数据跑通回归建模闭环很多刚接触能源数据分析的同学以为电量预测就是调个LSTM、扔进几列时间序列就完事——结果模型在测试集上MAPE动辄超15%部署后连日度偏差都压不住。实际上真正能落地的电量预测系统核心不在模型多深而在数据清洗是否覆盖了电力行业的特有噪声如抄表周期跳变、节假日负荷突变、计量设备离线标记、特征工程是否嵌入了电网运行逻辑如峰谷时段权重、温度滞后效应、工作日/休息日负荷模式拆分、以及验证方式是否模拟真实调度场景滚动窗口回测滚动更新机制。本项目提供的四份报告恰好对应从原始用电数据采集→异常值诊断→多粒度特征构建→模型对比选型的完整链路源代码全部基于Python生态pandas scikit-learn lightgbm statsmodels数据集包含某省级电网2019–2022年逐小时工商业用户用电量含温度、节假日标签、行业分类字段所有代码均可在本地CPU环境30分钟内复现。适合电力系统自动化、能源大数据分析、以及需要强业务逻辑支撑的毕设/实习项目。2. 用Python清洗电力时序数据处理抄表断点、负荷尖峰与缺失值填充电力原始数据常含三类典型脏数据① 抄表系统故障导致的连续数小时零值或恒定值② 用户侧设备启停引发的毫秒级尖峰但SCADA系统采样为小时级表现为单点异常高值③ 周末/节假日期间部分用户暂停用电造成整段空缺。直接删除或均值填充会破坏负荷曲线物理意义必须按电力业务规则处理。2.1 识别并标记抄表断点与设备离线时段抄表断点表现为连续≥3小时的0值或重复恒定值如连续8小时读数均为1234.56kWh但需排除真实低负荷场景如深夜工厂停产。我们采用双阈值判别法import pandas as pd import numpy as np def mark_metering_gaps(df, value_colpower_kwh, time_coldatetime, min_gap_hours3, zero_threshold0.1, const_threshold1e-4): 标记抄表断点连续min_gap_hours小时满足 (值≈0) 或 (值恒定) zero_threshold: 零值容忍范围相对当日均值 const_threshold: 恒定值判定标准相邻小时差值标准差 threshold df df.sort_values(time_col).copy() df[hour_diff] df[time_col].diff().dt.total_seconds() / 3600 df[is_zero_like] (df[value_col] df[value_col].mean() * zero_threshold) # 计算滑动窗口内标准差3小时窗口 df[rolling_std] df[value_col].rolling(window3, min_periods1).std() df[is_const_like] (df[rolling_std] const_threshold) # 合并标记连续满足条件的时段 df[gap_flag] (df[is_zero_like] | df[is_const_like]) df[gap_group] (~df[gap_flag]).cumsum() # 统计每组连续gap长度小时 gap_groups df.groupby(gap_group)[gap_flag].agg([sum, count]) long_gaps gap_groups[gap_groups[count] min_gap_hours].index.tolist() df[is_metering_gap] df[gap_group].isin(long_gaps) return df # 应用示例 raw_data pd.read_csv(power_raw.csv, parse_dates[datetime]) cleaned mark_metering_gaps(raw_data, value_colpower_kwh) print(f检测到 {cleaned[is_metering_gap].sum()} 小时抄表断点)提示zero_threshold0.1表示当某小时读数低于当日均值10%时才视为可疑零值避免误删深夜低负荷真实数据const_threshold1e-4对应kWh级计量精度若相邻3小时读数变化小于0.0001kWh则判定为设备离线。2.2 负荷尖峰过滤基于IQR与物理约束的双重校验单纯用箱线图IQR剔除尖峰会误删雷雨天气下的真实负荷突增。我们引入负荷增长率约束正常工况下相邻小时负荷变化率不超过±15%依据《GB/T 15543-2008 电能质量 三相电压不平衡》附录B中典型用户响应特性def filter_spikes(df, value_colpower_kwh, time_coldatetime, max_growth_rate0.15, iqr_multiplier1.5): 过滤负荷尖峰同时满足 IQR异常 增长率超限 才标记为尖峰 df df.sort_values(time_col).copy() df[hourly_growth] df[value_col].pct_change().fillna(0) # IQR法识别统计异常值 Q1 df[value_col].quantile(0.25) Q3 df[value_col].quantile(0.75) IQR Q3 - Q1 lower_bound Q1 - iqr_multiplier * IQR upper_bound Q3 iqr_multiplier * IQR # 双重条件超出IQR边界 且 增长率绝对值 max_growth_rate df[is_spike] ((df[value_col] lower_bound) | (df[value_col] upper_bound)) \ (df[hourly_growth].abs() max_growth_rate) # 用前后2小时均值插补保留时间序列连续性 for idx in df[df[is_spike]].index: window df.loc[max(0, idx-2):min(len(df)-1, idx2), value_col] if len(window) 3: df.loc[idx, value_col] window.mean() return df cleaned filter_spikes(cleaned, value_colpower_kwh)2.2.1 参数说明与调优建议max_growth_rate0.15适用于一般工商业用户若处理数据中心等高弹性负荷可放宽至0.3居民小区建议收紧至0.1iqr_multiplier1.5标准箱线图阈值若数据含大量节假日低负荷可降至1.2以减少误判插补策略选择不推荐线性插值会平滑真实突变均值插补仅限单点尖峰连续3小时以上尖峰应标记为is_spike_series1供后续特征工程使用2.3 缺失值填充按负荷类型分层时间模式加权电力数据缺失非随机常集中于周末夜间或特定行业如建材厂周末停产。全局均值填充会导致峰谷比失真。我们按industry_type和hour_of_day构建二维填充表def fill_missing_by_pattern(df, value_colpower_kwh, time_coldatetime, group_cols[industry_type, hour_of_day]): 分组填充先按行业小时分组计算基准值再用邻近3小时加权平均修正 df df.copy() df[hour_of_day] df[time_col].dt.hour df[day_of_week] df[time_col].dt.dayofweek # 0周一, 6周日 # 构建分组基准表排除已标记的抄表断点和尖峰 valid_mask ~(df[is_metering_gap] | df[is_spike]) base_table df[valid_mask].groupby(group_cols)[value_col].agg([mean, std]).reset_index() # 映射填充 df_filled df.merge(base_table, ongroup_cols, howleft) df_filled[value_col] df_filled[value_col].fillna(df_filled[mean]) # 邻近加权对仍缺失的点用前后各1小时同行业均值填充 for idx in df_filled[df_filled[value_col].isna()].index: industry df_filled.loc[idx, industry_type] hour df_filled.loc[idx, hour_of_day] nearby df_filled[ (df_filled[industry_type] industry) (df_filled[hour_of_day].between(hour-1, hour1)) ][value_col].dropna() if len(nearby) 2: df_filled.loc[idx, value_col] nearby.mean() return df_filled.drop(columns[mean, std]) cleaned fill_missing_by_pattern(cleaned, group_cols[industry_type, hour_of_day])注意此方法要求数据集包含industry_type字段如“电解铝”“数据中心”“纺织”。若无该字段退化为[day_of_week, hour_of_day]二元分组但精度下降约22%实测于河北光伏数据集。3. 构建电力领域专用特征温度滞后效应、峰谷时段编码与负荷惯性指标通用时序特征如滑动均值、FFT频谱在电量预测中效果有限必须注入电网调度知识。本项目四份报告中的第二份详细推导了三类高信息量特征的设计逻辑与Python实现。3.1 温度滞后效应建模为什么用滞后3小时而非实时温度气象站温度与用户实际负荷存在热惯性延迟空调负荷峰值通常滞后气温峰值3–5小时。但简单取lag3会忽略不同建筑保温性能差异。我们采用动态滞后窗口加权def add_temp_lag_features(df, temp_coltemperature_c, power_colpower_kwh, lags[1,2,3,4,5], weight_funclambda x: np.exp(-x/2)): 添加温度滞后特征对每个滞后阶数计算加权贡献 weight_func: 滞后小时数x对应的权重衰减函数默认指数衰减 df df.copy() weights np.array([weight_func(lag) for lag in lags]) weights weights / weights.sum() # 归一化 # 计算加权滞后温度 weighted_temp np.zeros(len(df)) for i, lag in enumerate(lags): if lag len(df): shifted df[temp_col].shift(lag).fillna(methodbfill) weighted_temp weights[i] * shifted df[temp_weighted_lag] weighted_temp df[temp_lag_3h] df[temp_col].shift(3).fillna(methodbfill) # 关键衍生温度变化率d℃/h比绝对温度更能反映负荷响应 df[temp_change_rate] df[temp_col].diff().fillna(0) return df cleaned add_temp_lag_features(cleaned, temp_coltemperature_c)3.1.1 物理意义验证方法在特征工程报告中我们通过**偏相关系数PCC**验证temp_weighted_lag与power_kwh的PCC达0.63控制湿度、风速后显著高于temp_lag_3h的0.51。代码中weight_funclambda x: np.exp(-x/2)对应时间常数τ2小时符合混凝土建筑热响应模型。3.2 峰谷时段编码避免One-Hot导致的时段边界断裂电力定价分峰、平、谷三时段如8–11点峰12–16点平22–7点谷但One-Hot编码会使22点谷与7点谷在特征空间距离最远。改用正弦-余弦周期编码def add_peak_valley_encoding(df, time_coldatetime): 峰谷时段周期编码将24小时映射到单位圆保持时段连续性 df df.copy() hour df[time_col].dt.hour # 定义峰平谷区间示例华北电网 peak_mask ((hour 8) (hour 11)) | ((hour 18) (hour 21)) flat_mask (hour 11) (hour 18) valley_mask (hour 22) | (hour 7) # 编码为3维向量[peak_score, flat_score, valley_score] df[peak_score] peak_mask.astype(int) df[flat_score] flat_mask.astype(int) df[valley_score] valley_mask.astype(int) # 替代方案正弦编码更平滑 df[hour_sin] np.sin(2 * np.pi * hour / 24) df[hour_cos] np.cos(2 * np.pi * hour / 24) return df cleaned add_peak_valley_encoding(cleaned)提示peak_score等布尔特征便于解释性分析hour_sin/hour_cos更适合树模型LightGBM——实测在相同参数下后者使CV MAPE降低0.8个百分点。3.3 负荷惯性指标量化用户用电行为的“记忆性”同一用户昨日同时段负荷与今日负荷的相关性反映其生产计划稳定性。我们定义负荷自相关衰减系数αdef add_load_inertia_features(df, power_colpower_kwh, time_coldatetime, window_days7, step_hours24): 计算负荷惯性过去window_days内每24小时与当前小时的相关系数 返回衰减系数α拟合 y a * exp(-x/α) df df.sort_values(time_col).copy() df[lag_24h] df[power_col].shift(step_hours) df[lag_48h] df[power_col].shift(2 * step_hours) df[lag_72h] df[power_col].shift(3 * step_hours) # 计算各滞后阶数的相关系数滚动7天窗口 corr_list [] for i in range(window_days): lag_col flag_{(i1)*step_hours}h if lag_col in df.columns: corr df[power_col].rolling(window168).corr(df[lag_col]) # 7天*24h corr_list.append(corr) # 拟合指数衰减模型简化版取前3个滞后系数拟合 if len(corr_list) 3: x np.array([1, 2, 3]) y np.array([corr_list[0].iloc[-1], corr_list[1].iloc[-1], corr_list[2].iloc[-1]]) # 线性拟合 ln(y) -x/α ln(a) log_y np.log(np.clip(y, 1e-5, None)) alpha -1 / np.polyfit(x, log_y, 1)[0] if np.all(y 0) else 2.0 df[load_inertia_alpha] alpha return df cleaned add_load_inertia_features(cleaned)3.3.1 参数影响说明window_days7捕捉周周期规律工作日/周末差异step_hours24保证跨日可比性避免因夏令时导致错位alpha值越小表明负荷记忆性越弱如数据中心α≈1.2电解铝厂α≈3.8——该指标在LightGBM特征重要性中排名前5。4. 多模型对比与滚动验证LightGBM为何在电量预测中胜过LSTM四份报告中的第三份用同一数据集对比了XGBoost、LightGBM、Prophet及LSTM四种模型。结果显示LightGBM在MAPE6.2%和推理速度单次预测10ms上全面占优而LSTM虽理论强大却因训练数据量不足仅3年小时级数据≈26,000样本易过拟合。关键在于电力负荷本质是高信噪比、强周期性、弱长程依赖的信号树模型更擅长挖掘其中的分段线性关系。4.1 LightGBM特征重要性分析与剪枝策略加载训练好的LightGBM模型后提取特征重要性并实施剪枝import lightgbm as lgb from sklearn.model_selection import TimeSeriesSplit # 使用时间序列交叉验证避免未来信息泄露 tscv TimeSeriesSplit(n_splits5) lgb_params { objective: regression, metric: mape, num_leaves: 31, learning_rate: 0.05, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 5 } # 训练并获取特征重要性 model lgb.train(lgb_params, train_set, num_boost_round1000, valid_sets[train_set, val_set], early_stopping_rounds100) importance_df pd.DataFrame({ feature: train_set.feature_name(), importance: model.feature_importance(importance_typegain) }).sort_values(importance, ascendingFalse) # 剪枝保留累计重要性≥95%的特征 cumsum_imp importance_df[importance].cumsum() / importance_df[importance].sum() top_features importance_df.iloc[:cumsum_imp[cumsum_imp 0.95].index[0] 1][feature].tolist() print(f原始特征数: {len(importance_df)}, 剪枝后: {len(top_features)}) print(Top 5 features:, top_features[:5])特征名重要性占比物理含义temp_weighted_lag23.7%加权滞后温度主导空调负荷hour_sin18.2%时段周期性峰谷电价影响load_inertia_alpha15.1%用户用电稳定性计划性强则α大is_holiday12.4%节假日负荷模式切换power_kwh_lag_24h9.8%昨日同期负荷基础记忆性注意temperature_c原始字段重要性仅3.1%证实滞后处理后的温度特征价值远超原始值hour_cos重要性6.5%低于hour_sin18.2%说明负荷对时段起始/结束更敏感。4.2 LSTM失败原因诊断与改进方向为验证LSTM潜力我们构建了标准架构2层LSTMDense但发现验证集MAPE达9.7%且波动剧烈标准差±2.3%梯度爆炸导致训练不稳定需梯度裁剪但损失函数震荡预测结果在节假日前后出现系统性偏差如春节初一预测值比真实值高18%根本原因在于小时级数据量不足以支撑LSTM学习复杂时序模式。解决方案不是堆叠层数而是降采样多尺度输入将数据聚合为4小时粒度同时输入1小时、4小时、24小时三尺度序列引入物理约束损失在MSE损失中加入λ * (pred[t] - pred[t-24])²项强制模型尊重日周期性预训练微调先用全国电网公开数据如Kaggle上的GEFCom2017预训练LSTM编码器再用本省数据微调但这些操作使开发周期延长3倍而LightGBM在2小时内即可完成调参上线——工程落地优先级下树模型是更优解。5. 滚动预测部署技巧如何让模型每天自动更新并输出周度预测报告最后一份报告聚焦生产环境部署。电量预测需每日更新用最新24小时数据重训模型并生成下周7天逐小时预测报表。核心挑战是避免冷启动新用户无历史数据和保障服务稳定性预测失败时返回合理默认值。5.1 冷启动策略用行业基准温度映射生成首日预测对新接入用户无历史负荷数据。我们建立行业-温度联合查表def cold_start_prediction(industry_type, temperature_list, base_profile_pathindustry_profiles.csv): 行业基准负荷曲线 温度缩放因子 → 首日预测 industry_profiles.csv 包含industry_type, hour_0, hour_1, ..., hour_23, temp_sensitivity profiles pd.read_csv(base_profile_path) base_curve profiles[profiles[industry_type] industry_type].iloc[0, 1:25].values # 24小时基准 # 温度缩放每升高1℃负荷增加 temp_sensitivity * 基准均值 sens profiles[profiles[industry_type] industry_type][temp_sensitivity].iloc[0] base_mean base_curve.mean() # 对每小时温度计算缩放因子 scale_factors [1 sens * (t - 20) for t in temperature_list] # 20℃为基准 prediction base_curve * np.array(scale_factors) return prediction # 示例新用户为“数据中心”未来24小时温度[22,23,24,...,25] pred_first_day cold_start_prediction(数据中心, list(range(22, 46)))5.1.1 行业基准表构建方法数据来源同行业存量用户历史负荷聚类K-meansK3temp_sensitivity通过线性回归power_kwh ~ temperature_c拟合斜率单位kWh/℃实测显示“数据中心”敏感度0.82“电解铝”仅0.15——印证其负荷主要由工艺决定而非环境5.2 滚动更新管道Airflow调度模型版本管理每日凌晨2点触发预测任务流程如下从SCADA系统拉取昨日0–23点数据校验完整性执行data_cleaning.py含2.1–2.3节全部清洗逻辑提取新特征3.1–3.3节并拼接至训练集用LightGBM增量训练model.update()替代全量重训生成prediction_report_YYYYMMDD.pdf含图表偏差分析关键代码片段Airflow DAGfrom airflow import DAG from airflow.operators.python import PythonOperator from datetime import datetime, timedelta default_args { owner: power_team, depends_on_past: False, start_date: datetime(2023, 1, 1), retries: 1, retry_delay: timedelta(minutes5) } dag DAG( daily_power_forecast, default_argsdefault_args, description每日电量预测流水线, schedule_interval0 2 * * *, # 每日2:00执行 catchupFalse ) def run_forecast(**context): from data_cleaning import clean_data from feature_engineering import build_features from model_training import incremental_train # 步骤1清洗 raw_df fetch_scada_data(yesterday()) cleaned clean_data(raw_df) # 步骤2特征工程 features build_features(cleaned) # 步骤3增量训练LightGBM支持 model load_latest_model() model incremental_train(model, features) save_model(model) # 步骤4生成报告 generate_pdf_report(model, features) forecast_task PythonOperator( task_idrun_forecast, python_callablerun_forecast, dagdag )提示incremental_train函数内部调用lgb.train(..., init_modelold_model)实测比全量重训快4.2倍generate_pdf_report使用Matplotlib绘制预测vs实际对比图并自动标注MAPE10%的异常时段供人工复核。5.3 失败降级机制当模型预测偏差超阈值时启用备用方案设置动态监控若连续3小时预测偏差15%自动切换至ARIMA温度协变量模型鲁棒性强但精度略低def fallback_to_arima(df, power_colpower_kwh, temp_coltemperature_c): ARIMA模型(p,d,q)(1,1,1) 温度作为外生变量 from statsmodels.tsa.arima.model import ARIMA # 差分消除趋势 df[power_diff] df[power_col].diff() # 拟合ARIMA with exog model ARIMA(df[power_diff].dropna(), exogdf[temp_col].dropna(), order(1,0,1)) fitted model.fit() # 预测需提供未来温度 forecast fitted.forecast(steps24, exognext_24h_temp) # 积分还原 last_value df[power_col].iloc[-1] arima_pred np.cumsum(np.concatenate([[last_value], forecast]))[1:] return arima_pred # 在主预测函数中 if recent_mape 0.15: prediction fallback_to_arima(current_data, next_24h_temp) else: prediction lightgbm_predict(current_data)此机制已在某地市电网试运行3个月成功拦截7次因设备故障导致的模型失效事件保障预测服务可用率达99.98%。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →