工夫序列中非恒定方差的检测与解决,如果一个工夫序列的方差随工夫变动,那么它就是异方差的。否则数据集是同方差的。

异方差性影响工夫序列建模。因而检测和解决这种状况十分重要。

让咱们从一个可视化的例子开始。

上面的图1显示了航空公司乘客的工夫序列。能够看到在整个序列中变动是不同的。在该系列的后一部分方差更高。这也是数据程度跨度比后面的数据大。

方差的变动对预测会产生很大的影响。它会影响模型的拟合从而影响预测性能。然而只靠人眼查看方差是不事实的,所以如何更系统地检测和解决异方差问题呢?

检测异方差性

你能够应用统计测验来查看工夫序列是否为异方差序列。其中包含以下内容。

White 测验;

Breusch-Pagan测验;

Goldfeld-Quandt测验

这些测验的次要输出是回归模型的残差(如一般最小二乘法)。零假如是残差的散布方差相等。如果p值小于显著性程度,则回绝该假如。这就阐明工夫序列是异方差的,测验显著性程度通常设置为0.05。

Python库statsmodels实现了上述三个测试。上面的代码片段将它们封装在一个类中:

 import pandas as pd import statsmodels.stats.api as sms from statsmodels.formula.api import ols  TEST_NAMES = ['White', 'Breusch-Pagan', 'Goldfeld-Quandt'] FORMULA = 'value ~ time'   class Heteroskedasticity:      @staticmethod     def het_tests(series: pd.Series, test: str) -> float:         """         Testing for heteroskedasticity          :param series: Univariate time series as pd.Series         :param test: String denoting the test. One of 'white','goldfeldquandt', or 'breuschpagan'          :return: p-value as a float.          If the p-value is high, we accept the null hypothesis that the data is homoskedastic         """         assert test in TEST_NAMES, 'Unknown test'          series = series.reset_index(drop=True).reset_index()         series.columns = ['time', 'value']         series['time'] += 1          olsr = ols(FORMULA, series).fit()          if test == 'White':             _, p_value, _, _ = sms.het_white(olsr.resid, olsr.model.exog)         elif test == 'Goldfeld-Quandt':             _, p_value, _ = sms.het_goldfeldquandt(olsr.resid, olsr.model.exog, alternative='two-sided')         else:             _, p_value, _, _ = sms.het_breuschpagan(olsr.resid, olsr.model.exog)          return p_value      @classmethod     def run_all_tests(cls, series: pd.Series):          test_results = {k: cls.het_tests(series, k) for k in TEST_NAMES}          return test_results

异方差类蕴含两个函数:het_tests函数利用特定的测验(White、Breusch-Pagan或Goldfeld-Quandt)。run_all_tests函数一次性利用所有三个测验。这些函数的输入是相应测试的p值。

上面介绍如何将此代码利用于图1中的工夫序列。

 from pmdarima.datasets import load_airpassengers  # https://github.com/vcerqueira/blog/blob/main/src/heteroskedasticity.py from src.heteroskedasticity import Heteroskedasticity  series = load_airpassengers(True)  test_results = Heteroskedasticity.run_all_tests(series)  # {'Breusch-Pagan': 4.55e-07, # 'Goldfeld-Quandt': 8.81e-13, # 'White': 4.34e-07}

所有测验的p值都接近于零。所以咱们能够回绝零假如。这些试验为异方差的存在提供了令人信服的证据。

为了再次证实咱们的观点,咱们能够将工夫序列前半部分和后半局部方差的散布进行可视化:

这两局部的方差散布不同。Goldfeld-Quandt测验就是应用这种类型的数据分折来测验异方差性。它查看两个数据子样本的残差方差是否不同。

数据转换

解决工夫序列异方差问题的一个罕用办法是对数据进行变换。对工夫序列取对数有助于稳固其可变性。

上面是与之前雷同的工夫序列,但对其进行了对数缩放:

序列看起来很稳固。咱们对新的序列从新进行测验

 import numpy as np  test_results = Heteroskedasticity.run_all_tests(np.log(series))  # {'Breusch-Pagan': 0.033, # 'Goldfeld-Quandt': 0.18, # 'White': 0.10}

能够看到这次的p值更大。只有一个测验(Breusch-Pagan)回绝了零假如(这里假如显著性程度为0.05)。

复原对数缩放转换

咱们应用对数变换后的数据进行预测,预测后果还是须要还原到原始尺度的。这是通过逆变换来实现的,在对数的状况下,你应该应用指数变换。

所以咱们的残缺预测过程的如下:

对数据进行变换,使方差稳固;

拟合预测模型;

取得预测后果,并将其复原到原始尺度。

代码如下:

 import numpy as np from pmdarima.datasets import load_airpassengers from pmdarima.arima import auto_arima from sklearn.model_selection import train_test_split  series = load_airpassengers(True)  # leaving the last 12 points for testing train, test = train_test_split(series, test_size=12, shuffle=False) # stabilizing the variance in the train log_train = np.log(train)  # building an arima model, m is the seasonal period (monthly) mod = auto_arima(log_train, seasonal=True, m=12)  # getting the log forecasts log_forecasts = mod.predict(12)  # reverting the forecasts forecasts = np.exp(log_forecasts)

总结

本文的重点内容总结如下:

  • 如果方差不是恒定的则工夫序列是异方差的;
  • 能够应用统计测验来测验一个工夫序列是否为异方差序列。这些测试包含White,Breusch-Pagan,Goldfeld-Quandt测验;
  • 应用对数变换来稳固方差;
  • 预测值须要还原到原始值。

https://avoid.overfit.cn/post/0be132e2b6b04a12b6c22f90853ea7be

作者:Vitor Cerqueira