您好,欢迎访问一九零五行业门户网

比较基于SARIMA、XGBoost和CNN-LSTM的时间序列预测方法

利用统计测试和机器学习分析和预测太阳能发电的性能测试和对比
本文将讨论通过使用假设测试、特征工程、时间序列建模方法等从数据集中获得有形价值的技术。我还将解决不同时间序列模型的数据泄漏和数据准备等问题,并且对常见的三种时间序列预测进行对比测试。
介绍时间序列预测是一个经常被研究的话题,我们这里使用使用两个太阳能电站的数据,研究其规律进行建模。首先将它们归纳为两个问题来解决这些问题:
是否有可能识别出性能欠佳的太阳能组件?是否可以预报两天的太阳能发电量?在继续回答这些问题之前,让我们先了解太阳能发电厂是如何发电的。
上图描述了从太阳能电池板模块到电网的发电过程。太阳能通过光电效应直接转化为电能。当硅(太阳能电池板中最常见的半导体材料)等材料暴露在光线下时,光子(电磁能量的亚原子粒子)被吸收并释放自由电子,从而产生直流电(dc)。使用逆变器,直流电被转换成交流电(ac)并发送到电网,在那里它可以被分配到家庭。
数据原始数据由每个太阳能发电厂的两个逗号分隔值(csv)文件组成。一份文件显示了发电过程,另一份文件显示了太阳能发电厂传感器记录的测量数据。每个太阳能发电厂的两个数据集都被整理成一个pandas的df。
太阳能发电厂1号(sp1)和太阳能发电厂2号(sp2)的数据每15分钟收集一次,从2020年5月15日到2020年6月18日。sp1和sp2数据集都包含相同的变量。
date time -间隔15分钟ambient temperature-模块周围空气的温度module temperature-模块的温度irradiation——模块上的辐射dc power (kw)  -直流ac power (kw) -交流daily yield-每日发电量总和total yield-逆变器的累计产量plant id -太阳能电站的唯一标识module id  -每个模块的唯一标识天气传感器用于记录每个太阳能发电厂的环境温度、组件温度和辐射。
对于这个数据集直流功率将是因变量(目标变量)。我们目标是的试图找到性能不佳的太阳能模块。
两个独立的df用于分析和预测。唯一的区别是用于预测的数据被重新采样为每小时的间隔,而用于分析的数据帧包含15分钟的间隔。
首先我们删除plant id,因为它对试图回答上述问题没有任何价值。module id也从预测数据集中删除。表1和表2显示了数据示例。
在继续分析数据之前,我们对太阳能发电厂做了一些假设,包括:
数据采集仪器无故障模块定期清洗(忽略维护的影响)两个太阳能电站周围都没有遮挡问题探索性数据分析(eda)对于数据科学的新手来说,eda是通过绘图可视化和执行统计测试来理解数据的关键一步。我们首先通过绘制sp1和sp2的dc和ac,可以观察到每个太阳能发电厂的性能。
sp1显示的直流功率比sp2高一个数量级。假设sp1采集的数据是正确的,用于记录数据的仪器没有故障,这就说明sp1中逆变器需要进行更深入的研究
通过按每个模块的日频率聚合ac和dc功率,图3显示了sp1中所有模块的逆变器效率。根据领域内知识,太阳能逆变器的效率应该在93-96%之间。由于所有模块的效率范围为9.76% - 9.79%,这里可以说明需要调查逆变器的性能,以及是否需要更换。
由于sp1显示了逆变器的问题,因此仅在sp2上进行了进一步的分析。
尽管这一小段分析是我们花了更多的时间对逆变器进行研究,但它并没有回答确定太阳能模块性能的主要问题。
由于sp2的逆变器正常工作,可以通过深入挖掘数据,来识别和调查任何异常情况。
图4中显示了模块温度和环境温度之间的关系,并且有模块温度极高的情况。
这看起来似乎违反我们的认知,但是可以看到高温对太阳能电池板的确有负面影响。当光子与太阳能电池内的电子接触时,它们会释放自由电子,但在更高的温度下,更多的电子已经处于激发态,这降低了电池板可以产生的电压,进而降低了效率。
考虑到这一现象,下面的图5显示了sp2的模块温度和直流功率(环境温度低于模块温度的数据点和模块运行数量较少的一天中的时间已经过过滤,以防止数据倾斜)。
在图5中,红线表示平均温度。这里可以看到有一个明确的临界点和直流电源停滞的迹象。在~52°c开始平稳。为了找到性能次优的太阳能模块,所有显示模块温度超过52°c的行都被删除。
下面的图6显示了sp2中每个模块在一天中的直流功率。这样就基本符合了预期,午间发电量较大。但是还有个问题,在运行高峰时期,发电量较低。我们很难总结造成这种情况的原因,因为当天的天气条件可能很差,或者sp2可能需要进行日常的维护等等。
图6中也有低性能模块的迹象。它们可以被识别为图上偏离最近群集的模块(单个数据点)。
为了确定哪些模块表现不佳,我们可以进行统计测试,同时将每个模块的性能与其他模块进行比较,从而确定性能。
每隔15分钟,不同模块的直流电源在同一时间的分布是正态分布,通过假设检验可以确定哪些模块表现不佳。计数是指模块落在99.9%置信区间之外且p值
图7按降序显示了每个模块在统计上显著低于同期其他模块的次数。
从图7中可以清楚地看出,模块' quc1tzyxw2pyowx '是有问题的。这些信息可以提供给sp2的相关工作人员,调查原因。
建模下面我们开始使用三种不同的时间序列算法:sarima、xgboost和cnn-lstm,进行建模并比较
对于所有三个模型,都使用预测下一个数据点进行预测。walk-forward验证是一种用于时间序列建模的技术,因为随着时间的推移,预测会变得不那么准确,因此更实用的方法是在实际数据可用时,用实际数据重新训练模型。
在建模之前需要更详细地研究数据。图8显示了sp2数据集中所有特征的相关热图。热图显示了因变量直流功率,与模块温度、辐照和环境温度的强相关性。这些特征可能在预测中发挥重要作用。
在下面的热图中,交流功率显示皮尔森相关系数为1。为了防止数据泄漏问题,我们将直流功率从数据中删除。
sarima季节自回归综合移动平均(sarima)是一种单变量时间序列预测方法。由于目标变量显示出24小时循环周期的迹象,sarima是一个有效的建模选项,因为它考虑了季节影响。这可以从下面的季节分解图中观察到。
sarima算法要求数据是平稳的。有多种方法来检验数据是否平稳,例如统计检验(增强迪基-福勒检验),汇总统计(比较数据的不同部分的均值/方差)和可视化分析数据。在建模之前进行多次测试是很重要的。
增强迪基-富勒(adf)检验是一种“单位根检验”,用于确定时间序列是否平稳。从根本上说,这是一个统计显著性检验,其中存在一个零假设和替代假设,并根据得出的p值得出结论。
零假设:时间序列数据是非平稳的。
替代假设:时间序列数据是平稳的。
在我们的例子中,如果p值≤0.05,我们可以拒绝原假设,并确认数据没有单位根。
from statsmodels.tsa.stattools import adfuller result = adfuller(plant2_dcpower.values) print('adf statistic: %f' % result[0]) print('p-value: %f' % result[1]) print('critical values:') for key, value in result[4].items(): print('t%s: %.3f' % (key, value))
从adf检验来看,p值为0.000553, len(sequences): break x.append(sequences[i:end_x, :-1]) y.append(sequences[end_x-1, -1]) return np.array(x), np.array(y) def cnn_lstm(x, y, x_val, y_val): cnn-lstm model. model = sequential() model.add(timedistributed(conv1d(filters=14, kernel_size=1, activation=sigmoid, input_shape=(none, x.shape[2], x.shape[3])))) model.add(timedistributed(maxpooling1d(pool_size=1))) model.add(timedistributed(flatten())) model.add(lstm(21, activation=tanh, return_sequences=true)) model.add(lstm(14, activation=tanh, return_sequences=true)) model.add(lstm(7, activation=tanh)) model.add(dense(3, activation=sigmoid)) model.add(dense(1)) model.compile(optimizer=adam(learning_rate=0.001), loss=mse, metrics=['mse']) history = model.fit(x, y, epochs=250, batch_size=36, verbose=0, validation_data=(x_val, y_val)) return model, history # split and resahpe data train, test = train_test_split(dropped_df_cat) train_x = train.drop(columns=dc_power, axis=1).to_numpy() train_y = train[dc_power].to_numpy().reshape(len(train), 1) test_x = test.drop(columns=dc_power, axis=1).to_numpy() test_y = test[dc_power].to_numpy().reshape(len(test), 1) #scale data scaler_x = minmaxscaler(feature_range=(-1,1)) scaler_y = minmaxscaler(feature_range=(-1,1)) train_x = scaler_x.fit_transform(train_x) train_y = scaler_y.fit_transform(train_y) test_x = scaler_x.transform(test_x) test_y = scaler_y.transform(test_y) # shape data into cnn-lstm format [samples, subsequences, timesteps, features] original train_data_np = np.hstack((train_x, train_y)) x, y = split_data(train_data_np, n_steps) x_subseq = x.reshape(x.shape[0], subseq, x.shape[1], x.shape[2]) # create validation set x_val, y_val = x_subseq[-24:], y[-24:] x_train, y_train = x_subseq[:-24], y[:-24] n_features = x.shape[2] actual = scaler_y.inverse_transform(test_y) # run cnn-lstm model if __name__ == '__main__': start_time = time() model, history = cnn_lstm(x_train, y_train, x_val, y_val) prediction = [] for i in range(len(test_x)): test_input = test_x[i].reshape(1, subseq, n_steps, n_features) yhat = model.predict(test_input, verbose=0) yhat_it = scaler_y.inverse_transform(yhat) prediction.append(yhat_it[0][0]) time_len = time() - start_time mse = mean_squared_error(actual.flatten(), prediction) print(f'cnn-lstm runtime: {round(time_len/60,2)} mins') print(fcnn-lstm mse: {round(mse,2)})
图18显示了cnn-lstm模型的预测值与sp2 2天内记录的直流功率的对比。
由于cnn-lstm的随机性,该模型运行10次,并记录一个平均mse值作为最终值,以判断模型的性能。图19显示了为所有模型运行记录的mse的范围。
结果对比下表显示了每个模型的mse (cnn-lstm的平均mse)和每个模型的运行时间(以分钟为单位)。
从表中可以看出,xgboost的mse最低、运行时第二快,并且与所有其他模型相比具有最佳性能。由于该模型显示了一个可以接受的每小时预测的运行时,它可以成为帮助运营经理决策过程的强大工具。
总结在本文中我们分析了sp1和sp2,确定sp1性能较低。所以对sp2的进一步调查显示,并且查看了sp2中那些模块性能可能有问题,并使用假设检验来计算每个模块在统计上明显表现不佳的次数,' quc1tzyxw2pyowx '模块显示了约850次低性能计数。
我们使用数据训练三个模型:sarima、xgboost和cnn-lstm。sarima表现最差,xgboost表现最好,mse为16.9,运行时间为1.43 min。所以可以说xgboost在表格数据中还是最优先得选择。
以上就是比较基于sarima、xgboost和cnn-lstm的时间序列预测方法。的详细内容。
其它类似信息

推荐信息