第二章:数据采集与预处理——SCADA系统与数据清洗实战

各位同学,大家好。今天我们来聊聊风功率预测里最基础、也最容易被忽视的一环——数据采集与预处理。

我见过太多团队,模型选得花里胡哨,结果数据一塌糊涂,预测精度根本提不上去。说白了,数据质量决定了模型的天花板。你想想看,垃圾数据进去,再牛的算法也白搭。

2.1 SCADA系统:风机的“黑匣子”

SCADA,全称是数据采集与监视控制系统。你可以把它想象成风机的“黑匣子”。它每时每刻都在记录风机的运行状态。

我个人习惯,拿到一个风场的数据,第一件事就是看SCADA的采样频率。大部分风场是10分钟一个点,也有1秒或1分钟的。频率不同,后续处理方式完全不同。

SCADA系统主要采集哪些数据?

  • 气象数据:风速、风向、温度、气压、湿度
  • 机组状态:有功功率、无功功率、桨距角、转速
  • 运行参数:发电机温度、齿轮箱油温、振动值

我在项目中遇到过,有些风场的SCADA系统会漏记“风向”这个字段。当时我们做功率曲线分析,怎么拟合都不对。后来发现,风向数据缺失了整整三个月。嗯,这里要注意:缺失的字段,有时候比异常值更致命

2.2 数据清洗:把“脏数据”洗干净

数据清洗,说白了就是“去伪存真”。SCADA数据里,什么妖魔鬼怪都有。

2.4.1 异常值处理

异常值分两种:一种是物理上不可能的值,比如风速500m/s;另一种是统计上离群的值,比如功率突然跳变。

我曾经处理过一个海上风场的数据,发现凌晨3点到5点,所有风机的功率都归零。一开始以为是停机维护,后来查日志才发现是SCADA通讯中断。这种“假停机”数据,如果不处理,模型会学到一个错误的规律:半夜没风。

我的处理原则:

  1. 物理阈值法:风速0~50m/s,功率0~额定功率×1.2
  2. 3σ原则:超出均值±3倍标准差的数据,标记为异常
  3. 四分位法:IQR(四分位距)之外的,视为离群点

代码示例(Python):

import pandas as pd
import numpy as np

# 物理阈值过滤
df = df[(df['wind_speed'] >= 0) & (df['wind_speed'] <= 50)]
df = df[(df['power'] >= 0) & (df['power'] <= rated_power * 1.2)]

# 3σ法
mean = df['power'].mean()
std = df['power'].std()
df = df[(df['power'] >= mean - 3*std) & (df['power'] <= mean + 3*std)]

2.4.2 缺失值处理

SCADA数据缺失,原因很多:传感器故障、通讯丢包、存储溢出。你想想看,一个10万条的数据集,缺失率超过5%,基本就不能直接用了。

我常用的方法有三种:

方法 适用场景 缺点
删除法 缺失率<1%,且随机缺失 浪费数据
插值法 短时间连续缺失(≤3个点) 长序列插值会失真
模型预测法 缺失率较高(5%~20%) 计算量大

避坑指南:我曾经用线性插值填补了连续2小时的缺失数据,结果模型预测的功率曲线出现了一个诡异的“平台”。后来才发现,插值把停机时段和运行时段连在了一起。所以,插值前一定要先判断机组状态

2.3 数据标准化与归一化

为什么要做标准化?因为风速的单位是m/s,功率的单位是kW,温度的单位是℃。数值范围差好几个数量级。如果不处理,模型会天然认为“数值大的特征更重要”。

我个人习惯,对于树模型(随机森林、XGBoost),其实不太需要标准化。但对于神经网络、SVM、KNN这类模型,标准化是必须的。

2.3.1 归一化(Min-Max Scaling)

把数据压缩到[0,1]区间。公式很简单:

X_norm = (X - X_min) / (X_max - X_min)

代码示例:

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
df[['wind_speed', 'power']] = scaler.fit_transform(df[['wind_speed', 'power']])

注意:归一化对异常值非常敏感。如果数据里有一个风速100m/s的异常点,归一化后正常数据会被压缩到很小的区间。所以,先清洗,再归一化

2.3.2 标准化(Z-score Scaling)

把数据变成均值为0、标准差为1的分布。公式:

X_std = (X - μ) / σ

代码示例:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df[['wind_speed', 'power']] = scaler.fit_transform(df[['wind_speed', 'power']])

标准化不要求数据有上下界,适合有离群点的场景。我一般优先用标准化,除非模型明确要求归一化。

2.4 本章知识体系

下面这张图,是我自己总结的数据预处理流程。你把它打印出来贴在工位上,每次做数据都过一遍,能省不少事。

风功率预测数据预处理流程 SCADA数据采集 数据清洗(异常值+缺失值) 标准化 / 归一化 特征工程(后续章节) 模型训练与误差修正 原始数据 脏数据 干净数据 特征数据 预测模型 采样频率检查 物理阈值+3σ MinMax/Standard 后续章节详解

好了,这一章的内容就到这里。数据预处理是苦活、累活,但也是最有价值的活。你花80%的时间把数据搞干净,后面20%的时间建模就够了。

一句话总结:SCADA数据是金矿,但金矿里也有石头。清洗干净了,才能炼出金子。


蓝海数据掘金营,专注资料整理