第2章 气象数据获取与处理
做风电功率预测,说白了就是跟数据打交道。而气象数据,就是咱们这行的「原材料」。原材料不行,后面模型再花哨也白搭。我刚开始做风电项目时,就吃过这个亏——拿到的数据看着挺全,一跑模型全乱套。后来才发现,数据源本身就有问题。
这一章,咱们就聊聊气象数据从哪来、怎么洗、怎么补、怎么归一化。嗯,都是实战中绕不开的坑。
2.1 气象数据源介绍
风电预测常用的气象数据源,主要有三类:NWP、SCADA、测风塔。这三兄弟各有各的脾气,咱们一个一个说。
2.1.1 NWP(数值天气预报)
NWP,全称是Numerical Weather Prediction。说白了,就是用超级计算机跑物理模型,算出未来几天的风速、风向、温度、气压这些。我习惯叫它「大模型预报」。
NWP的特点是:
- 覆盖范围广——整个区域甚至全球都有
- 时效性好——能预报未来3-7天
- 空间分辨率粗——一般几公里到几十公里一个格点
- 误差随时间增大——越往后越不准
我在项目中遇到过最头疼的事:NWP预报的风速和实际测风塔数据,有时候能差出3-4米/秒。为什么会这样?因为NWP的格点可能离风电场几十公里远,地形一变,风速就变了。
2.1.2 SCADA数据
SCADA是风电场自己的监控系统。每台风机上都有传感器,实时记录风速、功率、桨距角、转速这些。这个数据的特点是:
- 时间分辨率高——通常10秒到1分钟一个点
- 位置准确——就在风机轮毂高度
- 但噪声大——传感器故障、通信中断、数据跳变,家常便饭
我记得有一次,某台风机SCADA记录的风速连续三天都是12.5米/秒,纹丝不动。一看就知道传感器卡死了。这种数据如果不处理,模型会学出「风速恒等于12.5」这种荒唐规律。
2.1.3 测风塔数据
测风塔是风电场里专门立起来测风的塔,上面装了好几层风速仪、风向标。它比SCADA更专业,数据质量也更高。但问题是:
- 成本高——建一座塔几十万
- 数量少——一个风电场可能就1-2座
- 维护麻烦——结冰、雷击、鸟粪,都能让数据出问题
测风塔数据,我一般把它当作「金标准」。做模型训练时,优先用测风塔数据做标签。如果测风塔坏了,才退而求其次用SCADA。
2.2 数据清洗与异常值处理
数据拿到手,第一件事不是建模,是「洗数据」。我见过太多人上来就调模型,结果跑出来一堆垃圾。你想想看,数据里全是异常值,模型能学出什么好东西?
常见的异常值有这几类:
| 异常类型 | 表现 | 原因 |
|---|---|---|
| 缺失值 | NaN、空值 | 传感器故障、通信中断 |
| 跳变值 | 瞬间从5m/s跳到50m/s | 传感器受干扰、雷击 |
| 死值 | 连续多日数值不变 | 传感器卡死、冻结 |
| 越限值 | 风速超过60m/s(不合理) | 量程超限、记录错误 |
我处理异常值的流程是这样的:
- 可视化检查——先画个时序图,一眼就能看出异常
- 阈值过滤——风速超过60m/s的直接剔除
- 变化率检查——相邻两个点风速变化超过20m/s的,标记为异常
- 死值检测——连续24小时数值不变的,全部标记
避坑指南:我曾经犯过一个错——把异常值直接删掉,结果时间序列变得不连续,模型训练时出了大问题。后来我改成「先标记、后插补」,效果好了很多。
2.3 缺失值插补方法
数据清洗完,你会发现有些时间点还是空的。这时候就需要插补。插补方法很多,我常用的就两种:线性插值和KNN插值。
2.3.1 线性插值
线性插值,说白了就是用前后两个点的值,拉一条直线,算出中间缺失点的值。这个方法简单、快,适合短时间缺失(比如1-2个点)。
# 线性插值示例(Python)
import pandas as pd
# 假设df是包含风速数据的DataFrame
df['wind_speed_interp'] = df['wind_speed'].interpolate(method='linear')
# 如果缺失值在开头或结尾,interpolate会保留NaN
# 这时候可以用bfill或ffill填充
df['wind_speed_interp'].fillna(method='bfill', inplace=True)
df['wind_speed_interp'].fillna(method='ffill', inplace=True)
线性插值的局限也很明显:如果缺失时间太长(比如连续几个小时),线性插出来的值会失真。你想想看,风速变化那么剧烈,一条直线怎么可能拟合得好?
2.3.2 KNN插值
KNN插值,全称是K-Nearest Neighbors。它的思路是:找到跟缺失点「最像」的K个邻居,用它们的平均值来填补。这里的「像」,指的是其他特征(比如温度、气压、风向)的相似度。
我为什么喜欢KNN?因为它能利用多维信息。举个例子:某天风速缺失了,但同一天的温度、气压、风向都有记录。KNN会找到历史上跟这些条件最相似的几天,用那几天的风速平均值来填补。
# KNN插值示例(Python)
from sklearn.impute import KNNImputer
import numpy as np
# 假设X是特征矩阵,包含风速、温度、气压、风向等
# 注意:风速列中可能有NaN
imputer = KNNImputer(n_neighbors=5, weights='distance')
X_imputed = imputer.fit_transform(X)
# 提取插补后的风速列
df['wind_speed_knn'] = X_imputed[:, 0]
2.4 数据标准化与归一化
数据洗完了,插补完了,接下来就是标准化。为什么要做这一步?因为不同特征的量纲不一样——风速是0-30m/s,温度是-20到40℃,气压是900-1050hPa。如果不做标准化,模型会「偏袒」数值大的特征。
常用的方法有两种:
| 方法 | 公式 | 适用场景 |
|---|---|---|
| Min-Max归一化 | x' = (x - min) / (max - min) | 数据有明确上下界,比如风速0-30 |
| Z-score标准化 | x' = (x - μ) / σ | 数据分布近似正态,或者有异常值 |
我个人习惯:如果数据里异常值已经处理干净了,用Min-Max归一化。如果数据里还有少量离群点,用Z-score更稳健。
# Min-Max归一化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
df_scaled = scaler.fit_transform(df[['wind_speed', 'temperature', 'pressure']])
# Z-score标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df_standardized = scaler.fit_transform(df[['wind_speed', 'temperature', 'pressure']])
2.5 本章知识体系
说了这么多,咱们用一张图来总结一下本章的核心逻辑。从数据源到最终可用的标准化数据,每一步都有坑,每一步都得小心。
嗯,这一章的内容就到这。气象数据获取与处理,看似基础,但做扎实了,后面建模会省很多事。我见过太多人在这上面翻车——数据没洗干净,模型跑出来全是错的,还以为是算法不行。其实,数据才是根本。
公众号:蓝海数据掘金营,微信deep3321