时间序列是按照一定的时间间隔排列的一组数据,其时间间隔可以是任意的时间单位,如小时、日、周月等,这些数据形成了以一定时间间隔的数据。通过对这些时间序列的分析,从中发现和揭示现象发展变化的规律,并将这些信息用于预测。时间序列预测在水文领域有着广泛的应用,比如缺少多维水文数据的中小型水库水位预测、山洪沟流量、水位预测、部分灌区水量预测等。下面我们利用Python完成时间序列预测相关的模型的图形绘制,进而对比预测结果。
以某大型水库为例,利用其2012年至2021年日平均库水位数据来预测,其中选用2012年至2017年数据作为训练数据,2018年至2020年作为测试数据。 时间序列预测模型中利用Python实现时,尽可能应用Seaborn库。代码如下: [Python] 纯文本查看 复制代码 import pandas as pdimport matplotlib.pyplot as pltimport Seaborn as sns# Subsetting the dataset# Index 11856 marks the end of year 2013df = pd.read_csv('Resrvoir.csv', nrows=3652)# Creating train and test set# Index 10392 marks the end of October 2013train = df[0:2191]test = df[2192:]df.head() 水文领域的数据存在着明显的季节性,因此,本次图绘采用时间序列预测模型中的Holt-Winters季节性预测模型、受季节影响的自回归移动平均模型(SARIMA)和Facebook开源的Prophet模型。 如果数据集在一定时间段内的固定区间内呈现相似的模式,那么该数据集就具有季节性。Holt-Winters季节性预测模型,它是一种三次指数平滑预测,其背后的理念就是除了水平和趋势外,还将指数平滑应用到季节分量上。 二次指数平滑考虑了序列的基数和趋势,三次就是在此基础上增加了一个季节分量。类似于趋势分量,对季节分量也要做指数平滑。比如预测下一个季节第3个点的季节分量时,需要指数平滑地考虑当前季节第3个点的季节分量、上个季节第3个点的季节分量…等等。 如果数据集在一定时间段内的固定区间内呈现相似的模式,那么该数据集就具有季节性。Holt-Winters季节性预测模型,它是一种三次指数平滑预测,其背后的理念就是除了水平和趋势外,还将指数平滑应用到季节分量上。 [Python] 纯文本查看 复制代码 from statsmodels.tsa.api import ExponentialSmoothingy_hat_avg = test.copy()fit1 = ExponentialSmoothing(np.asarray(train['Count']), seasonal_periods=7, trend='add', seasonal='add', ).fit()y_hat_avg['Holt_Winter'] = fit1.forecast(len(test))plt.figure(figsize=(16, 8))plt.plot(train['Count'], label='Train')plt.plot(test['Count'], label='Test')plt.plot(y_hat_avg['Holt_Winter'], label='Holt_Winter')plt.legend(loc='best')plt.show()
2.受季节影响的自回归移动平均模型(SARIMA)ARIMA(Auto Regressive Integrate Moving Average Model)差分自回归移动平均模型是在ARMA模型的基础上进行改造的,ARMA模型是针对t期值进行建模的,而ARIMA是针对t期与t-d期之间差值进行建模,我们把这种不同期之间做差称为差分,这里的d是几就是几阶差分。指数平滑模型都是基于数据中的趋势和季节性的描述,而自回归移动平均模型的目标是描述数据中彼此之间的关系。SARIMA的一个优化版就是季节性ARIMA。它像Holt-Winters季节性预测模型一样,也把数据集的季节性考虑在内。SARIMA季节性自回归移动平均模型模型在ARIMA模型的基础上添加了季节性的影响,结构参数有七个:SARIMA(p,d,q)(P,D,Q,s),其中p,d,q分别为之前ARIMA模型中我们所说的p:趋势的自回归阶数。d:趋势差分阶数。q:趋势的移动平均阶数。P:季节性自回归阶数。 D:季节性差分阶数。 Q:季节性移动平均阶数。 s:单个季节性周期的时间步长数。 [Python] 纯文本查看 复制代码 import statsmodels.api as smy_hat_avg = test.copy()fit1 = sm.tsa.statespace.SARIMAX(train.Count, order=(2, 1, 4), seasonal_order=(0, 1, 1, 7)).fit()y_hat_avg['SARIMA'] = fit1.predict(start="2013-11-1", end="2013-12-31", dynamic=True)plt.figure(figsize=(16, 8))plt.plot(train['Count'], label='Train')plt.plot(test['Count'], label='Test')plt.plot(y_hat_avg['SARIMA'], label='SARIMA')plt.legend(loc='best')plt.show()
3. Prophet模型 Prophet是Facebook开源的python预测库,是工业级应用算法,并不是说在模型原理上相对于ARIMA模型有更好的突破,而是从模型使用体验上有所提升。即使没有统计学背景,也能快速上手使用。 [Python] 纯文本查看 复制代码 m = Prophet( changepoint_prior_scale = 0.2, daily_seasonality = False, yearly_seasonality = True, #年周期性 weekly_seasonality = True, #周周期性 growth = 'linear', interval_width = 0.8, #置信区间宽度,有多大概率落在浅蓝色线里 ) m.fit(df) future = m.make_future_dataframe(periods = 10) # 往后预测多少 future['cap'] = datal.iloc[:,column].max() future['floor'] = datal.iloc[:, column].min() forecast = m.predict(future) fig1 = m.plot(forecast) fig2 = m.plot_components(forecast) return future, forecastfuture, forecast = FB(data_dmean, 0)
时间序列预测模型林林总总,比较繁多,结合水文特性,考虑季节性因素的模型比较适合水文领域的预测,尤其在一些资料缺少、水文因素单薄的场景,具有一定的应用价值,而Python在这方面因为库丰富而具有一定的优势,但在应用时应充分考虑Python版本等因素,本文只是作为一个例子说明,无数据分享。 以上内容参考: 1.7 methods to perform Time Series forecasting (with Python codes) https://www.analyticsvidhya.com/blog/2018/02/time-series-forecasting-methods/ 2.时间序列(一):时间序列数据与时间序列预测模型_时间序列分析预测模型-CSDN博客 https://blog.csdn.net/qq_42692386/article/details/108619863
3、 Prophet官网 https://facebook.github.io/prophet/ 一图胜千言!水文图绘改版后致力于分享水文相关的精美图表,为读者提供作图思路和经验,帮助大家制作更漂亮丰富的图表。同时欢迎留言咨询绘图难点,我们会针对性地分享相关绘制经验。
|