第3章:SCADA数据基础
大家好,我是老张。在风电行业摸爬滚打了十几年,今天咱们来聊聊SCADA数据。说实话,这玩意儿看着简单,但坑是真不少。我见过太多团队,算法模型建得花里胡哨,结果数据质量一塌糊涂,最后全白干。
SCADA系统,说白了就是风电场的"黑匣子"。它记录着每台风机从出生到退役的点点滴滴。我个人习惯,拿到一个新项目,第一件事就是看SCADA数据——这比看任何报告都管用。
3.1 SCADA系统架构
先说说架构。SCADA系统一般分三层:
- 现场层:风机上的传感器、PLC、变桨系统这些。我管它叫"前线士兵"。
- 通信层:光纤、4G/5G、WiFi这些传输通道。嗯,这里要注意,很多风场在偏远山区,通信质量是个大问题。
- 监控层:中控室的服务器、操作员站。数据最终汇总到这里。
我给大家画个图,一看就明白:
你看,数据从风机传感器采集,经过通信网络传到中控室。但这里有个坑——通信延迟。我在内蒙古一个风场遇到过,光纤被老鼠咬断了,数据延迟了整整两天才发现。所以,我建议大家在监控层加个心跳检测,每5秒检查一次数据新鲜度。
3.2 数据采集频率与类型
SCADA数据采集频率,这个得看具体需求。我给大家列个表:
| 数据类型 | 典型采样频率 | 用途 | 我的经验 |
|---|---|---|---|
| 风速 | 1Hz | 功率预测、性能评估 | 注意机舱风速仪受尾流影响 |
| 有功功率 | 1Hz | 发电量统计、功率曲线 | 电网限电时数据会失真 |
| 发电机温度 | 0.1Hz (10秒一次) | 热模型、故障预警 | 温度变化慢,没必要高频采样 |
| 齿轮箱振动 | 10Hz ~ 100Hz | 轴承故障诊断 | 高频数据存储成本高,需权衡 |
| 桨距角 | 1Hz | 变桨系统状态监测 | 变桨卡涩时角度变化异常 |
| 机舱振动 | 10Hz | 塔筒振动、共振监测 | 低频振动容易被忽略 |
说白了,不是频率越高越好。温度这种慢变量,10秒采一次完全够用。但振动信号,尤其是齿轮箱高速轴,低于10Hz基本啥也看不出来。我有个教训:之前为了省存储空间,把振动数据降到1Hz,结果轴承故障特征全丢了,白白浪费了三个月的数据。
3.3 数据质量与缺失值处理
数据质量,这是AI风电运维的命门。我常说一句话:垃圾数据进,垃圾模型出。SCADA数据常见的质量问题有:
- 传感器漂移:风速仪用久了,零偏会变化。我见过一台风机,风速仪坏了半年,一直报0.5m/s,运维愣是没发现。
- 通信中断:数据包丢失,产生时间戳空洞。嗯,这个在偏远风场特别常见。
- 异常值:比如功率突然跳到200%额定值,这明显是传感器故障或者通信错误。
- 数据冻结:连续几百个采样点数值完全不变。你想想看,风速怎么可能10分钟纹丝不动?
数据质量检查清单(我自己的经验)
- 检查时间戳是否连续,间隔是否一致
- 检查数值范围是否在物理可行区间内(风速0-40m/s,功率0-1.2倍额定功率)
- 检查变化率是否合理(风速1秒内跳变超过10m/s,基本是异常)
- 检查数据冻结(连续N个点数值完全一样)
- 检查停机/限电标记是否完整
缺失值处理,这个我踩过不少坑。常用的方法有:
- 删除法:缺失率低于5%时,直接删掉。简单粗暴,但有效。
- 前向填充:用上一个有效值填充。适合短时间缺失(比如几秒钟)。
- 线性插值:用前后两个有效值做线性插值。适合风速、温度这种连续变化的数据。
- 模型预测:用其他相关变量预测缺失值。比如用风速和桨距角预测功率。这个方法精度高,但计算量大。
我给大家看一段Python代码,处理SCADA缺失值:
import pandas as pd
import numpy as np
# 读取SCADA数据
df = pd.read_csv('wind_turbine_scada.csv', parse_dates=['timestamp'])
# 设置时间戳为索引
df.set_index('timestamp', inplace=True)
# 检查缺失率
missing_rate = df.isnull().mean() * 100
print("各列缺失率:")
print(missing_rate)
# 处理策略
# 1. 短时间缺失(< 5个连续点):线性插值
df_interpolated = df.interpolate(method='linear', limit=5)
# 2. 长时间缺失(> 5个连续点):用相关变量预测
# 这里用风速预测功率
from sklearn.linear_model import LinearRegression
# 找到功率缺失但风速正常的样本
mask_missing_power = df_interpolated['power'].isnull()
mask_valid_wind = df_interpolated['wind_speed'].notnull()
mask = mask_missing_power & mask_valid_wind
if mask.any():
# 用完整数据训练模型
train_data = df_interpolated[df_interpolated['power'].notnull()]
X_train = train_data[['wind_speed']]
y_train = train_data['power']
model = LinearRegression()
model.fit(X_train, y_train)
# 预测缺失值
X_pred = df_interpolated.loc[mask, ['wind_speed']]
df_interpolated.loc[mask, 'power'] = model.predict(X_pred)
print("缺失值处理完成!")
print(f"处理后缺失率:{df_interpolated.isnull().mean() * 100}")
我的小技巧:处理缺失值时,一定要先看数据的时间戳。如果缺失发生在风机停机期间(比如维护),那就不应该插值,而是直接标记为"停机状态"。我曾经犯过这个错,把停机期间的功率插值成正常值,结果模型学出来全是错的。
警告:千万不要对振动数据做线性插值!振动信号是高频非平稳的,线性插值会引入虚假的频率成分。我见过有人这么干,结果FFT分析出来一堆不存在的故障频率,差点误导了维修决策。
最后说一句,SCADA数据预处理,占整个AI项目工作量的60%以上。别嫌麻烦,这一步做扎实了,后面的模型训练就是水到渠成的事。我个人习惯,每次拿到新数据,先花一周时间做数据质量评估,再花一周做清洗和特征工程。磨刀不误砍柴工嘛。
公众号:蓝海资料掘金营,微信deep3321