第四章:经典统计方法——持续法、ARIMA与卡尔曼滤波
各位同行,今天我们来聊聊风电功率预测里最经典的几个统计方法。说实话,虽然现在深度学习很火,但这些经典方法在实际工程中依然有不可替代的位置。我自己做项目时,经常先用它们打个底,再考虑要不要上复杂模型。
4.1 持续法(Persistance)——最简单的基线模型
持续法,说白了就是“现在啥样,未来还啥样”。它假设未来时刻的功率和当前时刻差不多。你可能会觉得这也太简单了吧?但别小看它,它可是所有预测模型的“照妖镜”。
核心思想:
P(t+Δt) = P(t)
其中 P(t) 是当前时刻的功率,Δt 是预测步长。
为什么它重要?
- 它是评估其他模型好坏的基准线
- 如果复杂模型连持续法都跑不过,那基本可以扔了
- 在超短期预测(比如未来5-15分钟)中,持续法效果其实不错
我在项目中遇到过一件事:有个团队花了两周调一个LSTM模型,结果在15分钟预测上只比持续法好了3%。嗯,这投入产出比确实有点尴尬。所以我建议,做任何预测项目前,先把持续法跑出来,看看你的数据到底有多难预测。
实用技巧:
持续法虽然简单,但可以用来做数据质量检查。如果持续法的误差突然变大,往往意味着数据采集出了问题,或者天气发生了剧烈变化。我曾经用这个办法发现过一个风速仪故障,省了不少排查时间。
4.2 ARIMA模型——时间序列的经典武器
ARIMA,全称是自回归积分滑动平均模型。名字听着唬人,但拆开看就明白了:
- AR(自回归):用过去的值预测未来的值
- I(积分):对数据进行差分,让它变平稳
- MA(滑动平均):用过去的预测误差来修正当前预测
ARIMA模型有三个关键参数:p、d、q。我刚开始学的时候也记不住,后来总结了个口诀:
| 参数 | 含义 | 怎么选 |
|---|---|---|
| p | 自回归阶数 | 看偏自相关函数(PACF)的截尾点 |
| d | 差分阶数 | 做单位根检验,直到数据平稳 |
| q | 滑动平均阶数 | 看自相关函数(ACF)的截尾点 |
ARIMA建模步骤:
- 数据预处理:检查缺失值、异常值,做差分让数据平稳
- 模型识别:通过ACF和PACF图初步确定p、q范围
- 参数估计:用AIC或BIC准则选择最优参数组合
- 模型检验:检查残差是否为白噪声
- 预测:用选定的模型做未来预测
下面是一个简单的Python实现示例:
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt
# 假设我们有历史功率数据
# data = pd.read_csv('wind_power.csv')
# power_series = data['power']
# 1. 检查平稳性(这里假设已经平稳)
# 2. 画ACF和PACF图
# plot_acf(power_series)
# plot_pacf(power_series)
# plt.show()
# 3. 拟合ARIMA模型(p=2, d=1, q=2)
model = ARIMA(power_series, order=(2, 1, 2))
model_fit = model.fit()
# 4. 查看模型摘要
print(model_fit.summary())
# 5. 预测未来6个时间点
forecast = model_fit.forecast(steps=6)
print(forecast)
注意:风电功率数据通常有很强的季节性和非平稳性。直接用原始数据跑ARIMA效果往往不好。我习惯先做差分,或者用SARIMA(季节性ARIMA)来处理日周期和年周期。
4.3 卡尔曼滤波——动态系统的状态估计
卡尔曼滤波,这名字听起来就很高端。其实它解决的是一个很实际的问题:如何从带噪声的观测数据中,估计出系统的真实状态。
在风电预测中,卡尔曼滤波主要用在两个地方:
- 数据滤波:去除风速、功率测量中的噪声
- 状态估计:结合模型预测和实时观测,动态修正预测值
卡尔曼滤波的核心公式(简化版):
预测步骤:
x_pred = A * x_prev + B * u
P_pred = A * P_prev * A^T + Q
更新步骤:
K = P_pred * H^T * (H * P_pred * H^T + R)^(-1)
x_est = x_pred + K * (z - H * x_pred)
P_est = (I - K * H) * P_pred
看着公式多,其实逻辑很清晰:先根据模型预测下一步状态,然后用实际观测值来修正这个预测。K就是卡尔曼增益,它决定了你更相信模型还是更相信观测。
在风电预测中的应用场景:
- 风速滤波:风速仪数据常有随机噪声,卡尔曼滤波可以平滑数据
- 功率预测修正:用实时功率数据修正NWP(数值天气预报)的预测结果
- 参数自适应:在线估计模型参数,适应风场特性的变化
我曾经在一个海上风场项目中,用卡尔曼滤波把NWP的预测误差降低了约15%。做法很简单:把NWP的预测作为状态方程,把SCADA系统的实时功率作为观测值,然后做在线修正。效果立竿见影。
下面是一个简单的卡尔曼滤波实现:
import numpy as np
class KalmanFilter:
def __init__(self, A, H, Q, R, x0, P0):
self.A = A # 状态转移矩阵
self.H = H # 观测矩阵
self.Q = Q # 过程噪声协方差
self.R = R # 观测噪声协方差
self.x = x0 # 初始状态
self.P = P0 # 初始协方差
def predict(self):
self.x = self.A @ self.x
self.P = self.A @ self.P @ self.A.T + self.Q
return self.x
def update(self, z):
y = z - self.H @ self.x # 残差
S = self.H @ self.P @ self.H.T + self.R
K = self.P @ self.H.T @ np.linalg.inv(S) # 卡尔曼增益
self.x = self.x + K @ y
self.P = (np.eye(len(self.x)) - K @ self.H) @ self.P
return self.x
# 使用示例
# A = np.array([[1, 1], [0, 1]]) # 简单运动模型
# H = np.array([[1, 0]])
# Q = np.eye(2) * 0.01
# R = np.array([[0.1]])
# kf = KalmanFilter(A, H, Q, R, np.array([0, 0]), np.eye(2) * 100)
#
# for z in measurements:
# kf.predict()
# x_est = kf.update(z)
调参经验:卡尔曼滤波的Q和R参数很关键。Q越大,说明你越不相信模型,滤波结果会更跟随观测值;R越大,说明你越不相信观测,结果会更平滑。我一般先用一段历史数据做离线调参,找到合适的Q和R比值,再上线运行。
4.4 三种方法的对比与选择
这三种方法各有适用场景,我整理了一个对比表:
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 持续法 | 超短期预测(≤15分钟) | 简单、快速、零成本 | 长期预测误差大 |
| ARIMA | 短期预测(15分钟-4小时) | 理论基础扎实、可解释性强 | 对非平稳数据需要预处理 |
| 卡尔曼滤波 | 在线修正、数据滤波 | 实时性好、能融合多源数据 | 需要调参、模型假设较强 |
我个人习惯的做法是:先用持续法建立基线,然后用ARIMA做离线预测模型,最后用卡尔曼滤波做在线修正。这样三层结构下来,基本能覆盖大部分风电预测场景。
下面这张图展示了这三种方法在风电预测中的关系:
好了,这一章的内容就到这里。经典统计方法虽然看起来不如深度学习“高大上”,但在实际工程中,它们往往更稳定、更可控。我建议你从持续法开始,逐步过渡到ARIMA和卡尔曼滤波,每一步都理解透彻了再往前走。