Machine Learning Mastery 时间序列入门教程(八)
如何在 Python 中使用和删除时间序列数据中的趋势信息
原文:
machinelearningmastery.com/time-series-trends-in-python/
我们的时间序列数据集可能包含趋势。
随着时间的推移,趋势是系列的持续增加或减少。识别,建模甚至从时间序列数据集中删除趋势信息可能会有所帮助。
在本教程中,您将了解如何在 Python 中建模和删除时间序列数据中的趋势信息。
完成本教程后,您将了解:
- 时间序列中可能存在的趋势的重要性和类型以及如何识别它们。
- 如何使用简单的差分方法删除趋势。
- 如何建模线性趋势并将其从销售时间序列数据集中删除。
让我们开始吧。
如何在 Python 中使用和删除时间序列数据中的趋势信息 照片来自 john78727 ,保留一些权利。
时间序列的趋势
趋势是时间序列水平的长期增加或减少。
一般而言,时间序列中看似不是周期性的系统变化被称为趋势。
- 第 5 页, R 入门时间序列
识别和理解趋势信息有助于提高模型表现;以下是几个原因:
- 更快的建模:也许趋势或缺乏趋势的知识可以提出方法并使模型选择和评估更有效率。
- 更简单的问题:也许我们可以纠正或消除趋势,以简化建模并提高模型表现。
- 更多数据:也许我们可以直接或作为摘要使用趋势信息,为模型提供额外信息并提高模型表现。
趋势类型
有各种趋势。
我们可以考虑的两个一般课程是:
- 确定性趋势:这些是持续增加或减少的趋势。
- 随机趋势:这些趋势不一致地增加和减少。
通常,确定性趋势更容易识别和删除,但本教程中讨论的方法仍然可用于随机趋势。
我们可以根据观察范围来考虑趋势。
- 全球趋势:这些趋势适用于整个时间序列。
- 本地趋势:这些趋势适用于时间序列的部分或子序列。
通常,全球趋势更容易识别和解决。
识别趋势
您可以绘制时间序列数据以查看趋势是否明显。
困难在于,在实践中,识别时间序列中的趋势可以是主观过程。因此,从时间序列中提取或移除它可以是主观的。
创建数据的线图并检查图表以获得明显的趋势。
在图中添加线性和非线性趋势线,看看趋势是否明显。
删除趋势
具有趋势的时间序列称为非平稳的。
可以对已识别的趋势建模。建模后,可以从时间序列数据集中删除它。这称为趋势时间序列。
如果数据集没有趋势或我们成功删除趋势,则数据集称为趋势静止。
在机器学习中使用时间序列趋势
从机器学习的角度来看,数据中的趋势代表了两个机会:
- 删除信息:删除扭曲输入和输出变量之间关系的系统信息。
- 添加信息:添加系统信息以改善输入和输出变量之间的关系。
具体而言,可以从时间序列数据(以及将来的数据)中删除趋势,作为数据准备和清理练习。这在使用统计方法进行时间序列预测时很常见,但在使用机器学习模型时并不总能改善结果。
或者,可以直接或作为摘要添加趋势,作为监督学习问题的新输入变量以预测输出变量。
一种或两种方法可能与您的时间序列预测问题相关,可能值得研究。
接下来,让我们看一下具有趋势的数据集。
洗发水销售数据集
该数据集描述了 3 年期间每月洗发水的销售数量。
单位是销售计数,有 36 个观察。原始数据集归功于 Makridakis,Wheelwright 和 Hyndman(1998)。
下面是前 5 行数据的示例,包括标题行。
"Month","Sales"
"1-01",266.0
"1-02",145.9
"1-03",183.1
"1-04",119.3
"1-05",180.3
下面是从数据市场中获取的整个数据集的图表,您可以在其中了解更多信息并下载数据集。
数据集显示出增长趋势。
洗发水销售数据集
加载 Shampoo Sales Dataset
下载数据集并将其放在当前工作目录中,文件名为“ shampoo-sales.csv ”
可以使用自定义日期解析例程加载数据集,如下所示:
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
series.plot()
pyplot.show()
运行该示例将加载数据集并创建绘图。
洗发水销售数据集图
通过差异趋势
也许最简单的解决时间序列的方法是差分。
具体地,构建新系列,其中当前时间步长的值被计算为原始观察与前一时间步骤的观察之间的差异。
value(t) = observation(t) - observation(t-1)
这具有从时间序列数据集中移除趋势的效果。
我们可以通过直接实现这一点在 Python 中创建一个新的差异数据集。可以创建新的观察列表。
下面是一个创建 Shampoo Sales 数据集的差异去趋势版本的示例。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
X = series.values
diff = list()
for i in range(1, len(X)):
value = X[i] - X[i - 1]
diff.append(value)
pyplot.plot(diff)
pyplot.show()
运行该示例将创建新的去趋势数据集,然后绘制时间序列。
因为没有为第一次观察创建差异值(没有任何东西可以从中减去),所以新数据集包含少一个记录。我们可以看到,这种趋势似乎确实已被删除。
洗发水销售数据集差异趋势
这种方法适用于具有线性趋势的数据。如果趋势是二次的(趋势的变化也增加或减少),那么可以采用已经差异的数据集的差异,即第二级差分。如果需要,可以进一步重复该过程。
由于差分仅需要在前一时间步进行观察,因此可以轻松地将其应用于看不见的样本外数据,以进行预处理或为监督学习提供额外输入。
接下来,我们将研究拟合模型来描述趋势。
由模型拟合引起的趋势
趋势通常很容易通过观察结果显示为一条线。
线性趋势可以通过线性模型来概括,并且可以使用多项式或其他曲线拟合方法来最佳地总结非线性趋势。
由于识别趋势的主观性和特定领域性,这种方法可以帮助确定趋势是否存在。即使将线性模型拟合到明显超线性或指数的趋势也是有帮助的。
除了用作趋势识别工具之外,这些拟合模型还可用于消除时间序列。
例如,可以在时间索引上拟合线性模型以预测观察。该数据集如下所示:
X, y
1, obs1
2, obs2
3, obs3
4, obs4
5, obs5
此模型的预测将形成一条直线,可以将其作为数据集的趋势线。也可以从原始时间序列中减去这些预测,以提供数据集的去趋势版本。
value(t) = observation(t) - prediction(t)
来自模型拟合的残差是数据集的去趋势形式。也可以使用多项式曲线拟合和其他非线性模型。
我们可以通过在数据上训练 scikit-learn LinearRegression 模型在 Python 中实现这一点。
from pandas import read_csv
from pandas import datetime
from sklearn.linear_model import LinearRegression
from matplotlib import pyplot
import numpy
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# fit linear model
X = [i for i in range(0, len(series))]
X = numpy.reshape(X, (len(X), 1))
y = series.values
model = LinearRegression()
model.fit(X, y)
# calculate trend
trend = model.predict(X)
# plot trend
pyplot.plot(y)
pyplot.plot(trend)
pyplot.show()
# detrend
detrended = [y[i]-trend[i] for i in range(0, len(series))]
# plot detrended
pyplot.plot(detrended)
pyplot.show()
首先运行示例将线性模型拟合到整数索引的观测值,并绘制原始数据集(蓝色)上的趋势线(绿色)。
洗发水销售数据集与趋势
接下来,从原始数据集中减去趋势,并绘制得到的去趋势数据集。
洗发水销售数据集模型趋势
同样,我们可以看到这种方法已经有效地去除了数据集。残差中可能存在抛物线,这表明也许多项式拟合可能做得更好。
由于趋势模型仅将观察的整数索引作为输入,因此可以将其用于新数据,以取消趋势或为模型提供新的输入变量。
进一步阅读
以下是有关趋势估计和时间序列去趋势的一些额外资源。
- 维基百科上的线性趋势估计
- 趋势说明,GEOS 585A,应用时间序列分析[PDF]
- 更新:从此页面下载。
摘要
在本教程中,您发现了时间序列数据的趋势以及如何使用 Python 删除它们。
具体来说,你学到了:
- 关于时间序列中趋势信息的重要性以及如何在机器学习中使用它。
- 如何使用差分从时间序列数据中删除趋势。
- 如何建模线性趋势并将其从时间序列数据中删除。
您对 detrending 或本教程有任何疑问吗? 在下面的评论中提出您的问题,我会尽力回答。
如何在 Python 中调整 ARIMA 参数
原文:
machinelearningmastery.com/tune-arima-parameters-python/
在 Python 中使用 Statsmodels 配置 ARIMA 模型时,需要考虑许多参数。
在本教程中,我们将介绍一些您可能对此感兴趣的关键参数(除了 order 参数之外)。
具体来说,完成本教程后,您将了解:
- 如何在拟合 ARIMA 模型时抑制基础数学库的噪声输出。
- 在 ARIMA 模型中启用或禁用趋势术语的效果。
- 使用不同的数学求解器将系数拟合到训练数据的影响。
注意,如果您对调整 order 参数感兴趣,请参阅帖子:
让我们开始吧。
洗发水销售数据集
该数据集描述了 3 年期间每月洗发水的销售数量。
单位是销售计数,有 36 个观察。原始数据集归功于 Makridakis,Wheelwright 和 Hyndman(1998)。
下面的示例加载并创建已加载数据集的图。
# load and plot dataset
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# summarize first few rows
print(series.head())
# line plot
series.plot()
pyplot.show()
运行该示例将数据集作为 Pandas Series 加载并打印前 5 行。
Month
1901-01-01 266.0
1901-02-01 145.9
1901-03-01 183.1
1901-04-01 119.3
1901-05-01 180.3
Name: Sales, dtype: float64
然后创建该系列的线图,显示明显的增加趋势。
每月洗发水销售数据集的线图
实验测试 - 设置
一致地评估时间序列预测模型非常重要。
在本节中,我们将定义如何评估本教程中的三个预测模型。
首先,我们将保留最后一年的数据并评估此数据的预测。鉴于数据是每月一次,这意味着最后 12 个观测值将用作测试数据。
我们将使用前瞻性验证方法来评估模型表现。这意味着将枚举测试数据集中的每个时间步,在历史数据上构建模型,并将预测与预期值进行比较。然后将观察结果添加到训练数据集中并重复该过程。
前瞻性验证是评估时间序列预测模型的现实方法,因为人们可以期望在新观察结果可用时更新模型。
最后,将使用均方根误差或 RMSE 来评估预测。 RMSE 的好处在于它会对大错误进行处罚,并且得分与预测值(每月汽车销售额)的单位相同。
ARIMA(4,1,0)预测模型将用作探索模型的其他参数的基线。这可能不是该问题的最佳模型,但通常对某些其他手动测试配置非常熟练。
总之,测试工具包括:
- 最近 2 年的数据使用了测试集。
- 模型评估的前瞻性验证。
- 用于报告模型技能的均方根误差。
- ARIMA(4,1,0)模型将用作基线。
下面列出了完整的示例。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
train, test = X[0:-12], X[-12:]
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit()
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
# plot forecasts against actual outcomes
pyplot.plot(test)
pyplot.plot(predictions, color='red')
pyplot.show()
运行该示例会发出大量的收敛信息并完成 RMSE 评分为每月 84.832 的洗发水销售额。
...
Tit = total number of iterations
Tnf = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip = number of BFGS updates skipped
Nact = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F = final function value
* * *
N Tit Tnf Tnint Skip Nact Projg F
5 15 20 1 0 0 8.882D-08 5.597D+00
F = 5.5972342395324288
CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH
Cauchy time 0.000E+00 seconds.
Subspace minimization time 0.000E+00 seconds.
Line search time 0.000E+00 seconds.
Total User time 0.000E+00 seconds.
Test RMSE: 84.832
创建预测与测试工具中实际观测的关系图,为我们正在使用的模型提供一些上下文。
ARIMA 月度洗发水销售数据集预测
现在让我们深入研究一些其他 ARIMA 参数。
“disp”参数
我们将看到的第一个参数是disp参数。
这描述如下:
如果为 True,则打印收敛信息。对于默认的 l_bfgs_b 求解器,disp 在迭代期间控制输出的频率。 disp&lt; 0 表示在这种情况下没有输出。
默认情况下,此参数设置为 1,显示输出。
我们首先要处理这个问题,因为在使用前向验证评估 ARIMA 模型时,删除所有收敛输出至关重要。
设置为False会关闭所有这些噪音。
下面列出了完整的示例。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit(disp=False)
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
运行此示例不仅可以生成更清晰的输出,而且执行速度也快得多。
Test RMSE: 81.545
我们将在以下所有示例中留下 disp = False 。
“transparams”参数
此参数控制是否对 AR 参数执行变换。
具体来说,它被描述为:
是否转换参数以确保平稳性。使用 Jones(1980)中提出的转换。如果为假,则不检查平稳性或可逆性。
默认情况下,transparams设置为True,表示执行此转换。
此参数也用于 ARIMA 实现的 R 版本(参见 docs ),我希望这就是它在 statsmodels 中的原因。
statsmodels doco 在这方面很弱,但您可以在论文中了解有关转换的更多信息:
以下示例演示了关闭此参数。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit(disp=False, transparams=False)
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
运行此示例会导致解算器收到更多收敛警告。
关闭transparams的模型的 RMSE 也会导致该数据集的结果略差。
在数据集上打开和关闭此参数并确认它会带来好处。
...
.../site-packages/statsmodels/base/model.py:496: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
"Check mle_retvals", ConvergenceWarning)
Test RMSE: 81.778
“_ 趋势 _”参数
_ 趋势 _ 参数为模型添加了一个额外的常数项。可以把它想象成偏见或拦截术语。
它被描述为:
是否包含常数。 'c'包括常数,'nc'没有常量。
默认情况下,在 _ 趋势 _ 设置为'c'时启用趋势项。
如果我们重新运行原始示例并打印前向验证的每个步骤的模型系数并将其与关闭的趋势项进行比较,我们可以清楚地看到效果。
下面的示例在每次迭代时打印系数,并启用趋势常量(默认值)。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit(disp=False, trend='c')
print(model_fit.params)
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
运行该示例显示按模型顺序指定的 4 个 AR 项加上数组中的第一个项,这是趋势常量。
请注意,为每个模型拟合打印一组参数,一个用于前进验证的每个步骤。
...
[ 11.42283717 -1.16087885 -0.6519841 -0.547411 -0.28820764]
[ 11.75656838 -1.11443479 -0.61607471 -0.49084722 -0.24452864]
[ 11.40486702 -1.11705478 -0.65344924 -0.50213939 -0.25677931]
Test RMSE: 81.545
我们可以在禁用趋势项( trend ='nc')的情况下重复此实验,如下所示。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit(disp=False, trend='nc')
print(model_fit.params)
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
运行该示例显示此问题的 RMSE 得分略差,具有此 ARIMA 配置。
我们可以看到每次迭代从系数数组中移除常数项(11.xxx)。
...
[-0.90717131 -0.22332019 -0.11240858 -0.04008561]
[-0.88836083 -0.21098412 -0.09046333 -0.02121404]
[-0.89260136 -0.24120301 -0.10243393 -0.03165432]
Test RMSE: 95.061
试验您自己的问题并确定此常量是否可以提高表现。
我自己的实验表明 ARIMA 模型可能不太可能收敛 _ 趋势 _ 术语禁用,特别是当使用超过零 MA 术语时。
“_ 求解器 _”参数
_ 求解器 _ 参数指定数值优化方法以使系数适合数据。
如果您有大量数据,除了执行速度之外,通常没有理由调整此参数。差异可能很小。
该参数描述如下:
要使用的解算器。默认为'lbfgs'(有限的内存 Broyden-Fletcher-Goldfarb-Shanno)。其他选择是'bfgs','newton'(Newton-Raphson),'nm'(Nelder-Mead),'cg' - (共轭梯度),'ncg'(非共轭梯度)和'powell'。默认情况下,有限内存 BFGS 使用 m = 12 来近似 Hessian,投影梯度容差为 1e-8,factr = 1e2。您可以使用 kwargs 更改这些内容。
默认为快速“lbfgs”方法(限制内存 BFGS )。
然而,下面是一个比较 RMSE 模型技能和每个求解器执行时间的实验。
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
from math import sqrt
from time import time
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
# split into train and test sets
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
# solvers
solvers = ['lbfgs', 'bfgs', 'newton', 'nm', 'cg', 'ncg', 'powell']
scores = []
times = []
for solver in solvers:
start_time = time()
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
# fit model
model = ARIMA(history, order=(4,1,0))
model_fit = model.fit(disp=False, solver=solver)
# one step forecast
yhat = model_fit.forecast()[0]
# store forecast and ob
predictions.append(yhat)
history.append(test[t])
# evaluate forecasts
rmse = sqrt(mean_squared_error(test, predictions))
timing = time() - start_time
scores.append(rmse)
times.append(timing)
print('Solver=%s, Test RMSE: %.3f, Time=%f' % (solver, rmse, timing))
# plot scores
ticks = [i for i in range(len(solvers))]
pyplot.bar(ticks, scores)
pyplot.xticks(ticks, solvers)
pyplot.show()
# plot times
ticks = [i for i in range(len(solvers))]
pyplot.bar(ticks, times)
pyplot.xticks(ticks, solvers)
pyplot.show()
运行该示例将打印每个 _ 解算器 _ 的 RMSE 和时间(以秒为单位)。
Solver=lbfgs, Test RMSE: 81.545, Time=1.630316
Solver=bfgs, Test RMSE: 81.545, Time=2.122630
Solver=newton, Test RMSE: 81.545, Time=2.418718
Solver=nm, Test RMSE: 81.472, Time=1.432801
Solver=cg, Test RMSE: 81.543, Time=3.474055
Solver=ncg, Test RMSE: 81.545, Time=2.643767
Solver=powell, Test RMSE: 81.704, Time=1.839257
提供了 _ 求解器 _ 与 RMSE 的关系图。正如预期的那样,这个小数据集上的求解器之间几乎没有差别。
您可能会在自己的问题上看到不同的结果或解算器的不同稳定性。
ARIMA 模型误差(测试 RMSE)与求解器
还创建了 _ 求解器 _ 与执行时间(以秒为单位)的图表。该图显示了求解器之间的显着差异。
通常,“lbfgs”和“bfgs”在速度,表现和稳定性之间提供了良好的实际权衡。
ARIMA 执行时间(秒)vs Solver
如果你决定测试求解器,你可能还想改变“maxiter”来限制收敛前的迭代次数,“tol”参数定义精度收敛,以及定义被优化的成本函数的“_ 方法 _”参数。
其他资源
本节列出了您可能会发现本教程中有用的一些资源。
摘要
在本教程中,您发现了使用 Python 中的 Statsmodels 配置 ARIMA 模型的一些细节。
具体来说,你学到了:
- 如何在拟合系数时关闭求解器的噪声收敛输出。
- 如何评估不同求解器之间的差异以适合您的 ARIMA 模型。
- 在 ARIMA 模型中启用和禁用趋势术语的效果。
您对在 Python 中使用 ARIMA 模型有任何疑问吗? 在下面的评论中提出您的问题,我会尽力回答。
如何用 Python 可视化时间序列预测残差
原文:
machinelearningmastery.com/visualize-time-series-residual-forecast-errors-with-python/
时间序列回归问题的预测误差称为残差或残差。
仔细探索时间序列预测问题中的残差可以告诉您很多关于您的预测模型,甚至建议改进。
在本教程中,您将了解如何从时间序列预测中可视化残差。
完成本教程后,您将了解:
- 如何创建和查看残余错误随时间变化的线图。
- 如何查看残差图分布的摘要统计和图表。
- 如何探讨残差的相关结构。
让我们开始吧。
剩余预测错误
时间序列预测问题的预测误差称为残差或残差。
剩余误差计算为预期结果减去预测,例如:
residual error = expected - forecast
或者,更简洁,并使用标准术语:
e = y - yhat
我们经常停在那里并总结模型的技巧作为此错误的摘要。
相反,我们可以在所有预测中收集这些个别残差,并使用它们来更好地理解预测模型。
通常,在探索残差时,我们正在寻找模式或结构。模式的标志表明错误不是随机的。
我们期望残差是随机的,因为这意味着模型已经捕获了所有结构,剩下的唯一错误是无法建模的时间序列中的随机波动。
模式或结构的标志表明模型可以捕获并使用更多信息来进行更好的预测。
在我们开始探索在残差中寻找模式的不同方法之前,我们需要上下文。在下一节中,我们将查看一个数据集和一个简单的预测方法,我们将使用它们来生成本教程中要探索的残差。
每日女性出生数据集
该数据集描述了 1959 年加利福尼亚州每日女性出生人数。
单位是计数,有 365 个观测值。数据集的来源归功于牛顿,1988 年。
下载数据集并将其放在当前工作目录中,文件名为“ daily-total-female-births.csv ”。
以下是从 CSV 加载每日女性出生数据集的示例。
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
print(series.head())
series.plot()
pyplot.show()
运行该示例将打印加载文件的前 5 行。
Date
1959-01-01 35
1959-01-02 32
1959-01-03 30
1959-01-04 31
1959-01-05 44
Name: Births, dtype: int64
数据集也以随时间变化的观察线图显示。
每日女性出生数据集
持久性预测模型
我们可以做的最简单的预测是预测上一个时间步骤中发生的事情将与下一个时间步骤中发生的情况相同。
这称为“_ 朴素预测 _”或持久性预测模型。
我们可以在 Python 中实现持久性模型。
加载数据集后,它被定性为监督学习问题。创建数据集的滞后版本,其中先前时间步长(t-1)用作输入变量,下一时间步骤(t + 1)用作输出变量。
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
接下来,数据集分为训练集和测试集。共有 66%的数据用于训练,其余 34%用于测试集。持久性模型不需要训练;这只是一种标准的测试工具方法。
拆分后,训练和测试装置将分为输入和输出组件。
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
通过预测输出值(y)作为输入值(x)的副本来应用持久性模型。
# persistence model
predictions = [x for x in test_X]
然后将残余误差计算为预期结果(test_y)和预测(_ 预测 _)之间的差异。
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
该示例将所有这些放在一起,并为我们提供了一组残余预测错误,我们可以在本教程中探讨这些错误。
from pandas import Series
from pandas import DataFrame
from pandas import concat
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [x for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = DataFrame(residuals)
print(residuals.head())
运行该示例将打印预测残差的前 5 行。
0 9.0
1 -10.0
2 3.0
3 -6.0
4 30.0
剩余线图
第一个图是将残差预测误差随时间变化作为线图。
我们期望该图在 0 的值附近是随机的,并且不显示任何趋势或循环结构。
剩余错误数组可以包装在 Pandas DataFrame 中并直接绘制。下面的代码提供了一个示例。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [x for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = DataFrame(residuals)
# plot residuals
residuals.plot()
pyplot.show()
运行该示例显示了剩余时间序列的看似随机的图。
如果我们确实看到趋势,季节性或循环结构,我们可以回到我们的模型并尝试直接捕获这些元素。
每日女性出生数据集残差的线图
接下来,我们将查看可用于查看错误如何在零周围传播的摘要统计量。
剩余摘要统计
我们可以计算剩余误差的汇总统计量。
首先,我们对残差的平均值感兴趣。接近于零的值表明预测中没有偏差,而正值和负值表明预测中存在正偏差或负偏差。
了解预测中的偏差很有用,因为它可以在使用或评估之前直接在预测中进行校正。
下面是计算残差分布的汇总统计量的示例。这包括分布的均值和标准差,以及百分位数和观察到的最小和最大误差。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [x for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = DataFrame(residuals)
# summary statistics
print(residuals.describe())
运行该示例显示接近零的平均错误值,但可能不够接近。
它表明可能存在一些偏差,我们可以通过执行偏差校正来进一步改进模型。这可以通过将平均残差(0.064000)添加到预测来完成。
这可能适用于这种情况,但它是一种朴素的偏差校正形式,并且有更复杂的方法可用。
count 125.000000
mean 0.064000
std 9.187776
min -28.000000
25% -6.000000
50% -1.000000
75% 5.000000
max 30.000000
接下来,我们将超越摘要统计,并查看可视化残差分布的方法。
残差直方图和密度图
可以使用绘图来更好地理解除摘要统计之外的错误分布。
我们希望预测误差通常分布在零均值附近。
图可以帮助发现此分布中的偏差。
我们可以使用直方图和密度图来更好地理解残差的分布。下面是创建每个绘图之一的示例。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [(x-0.064000) for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = DataFrame(residuals)
# histogram plot
residuals.hist()
pyplot.show()
# density plot
residuals.plot(kind='kde')
pyplot.show()
我们可以看到分布确实具有高斯外观,但可能更尖,显示具有一些不对称性的指数分布。
如果绘图显示明显非高斯分布,则表明建模过程所做的假设可能不正确,并且可能需要不同的建模方法。
大的偏斜可能表明在建模之前对数据执行变换的机会,例如采用对数或平方根。
每日女性出生数据集残差的直方图
每日女性出生数据集残差的密度图
接下来,我们将看另一种快速,可能更可靠的方法来检查残差的分布是否为高斯分布。
剩余 Q-Q 图
Q-Q 图或分位数图比较两个分布,可用于查看它们恰好相似或不同。
我们可以使用 statsmodels 库中的 qqplot()函数创建 Q-Q 图。
Q-Q 图可用于快速检查残差分布的正态性。
对这些值进行排序并与理想化的高斯分布进行比较。比较显示为散点图(在 x 轴上为理论值并在 y 轴上观察),其中两个分布之间的匹配显示为从图的左下到右上的对角线。
该情节有助于发现明显的偏离这种期望。
下面是残差的 Q-Q 图的示例。 x 轴表示理论分位数,y 轴表示样本分位数。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
import numpy
from statsmodels.graphics.gofplots import qqplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [(x-0.064000) for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = numpy.array(residuals)
qqplot(residuals)
pyplot.show()
运行该示例显示了 Q-Q 图,该分布看起来很正常,有一些凸起和异常值。
每日女性出生数据集残差的 Q-Q 图
接下来,我们可以检查错误随时间的相关性。
残差自相关图
自相关计算观察和先前时间步骤的观察之间关系的强度。
我们可以计算剩余误差时间序列的自相关并绘制结果。这称为自相关图。
我们不希望残差之间存在任何相关性。这将通过自相关分数低于显着性阈值(图上的虚线和虚线水平线)来显示。
剩余图中的显着自相关表明该模型可以更好地结合观察与滞后观察之间的关系,称为自回归。
Pandas 提供了一个用于计算自相关图的内置函数,称为 autocorrelation_plot()。
下面是可视化残差的自相关的示例。 x 轴显示滞后,y 轴显示观察值和滞后变量之间的相关性,其中相关值分别在-1 和 1 之间,用于负相关和正相关。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
from pandas.tools.plotting import autocorrelation_plot
series = Series.from_csv('daily-total-female-births.csv', header=0)
# create lagged dataset
values = DataFrame(series.values)
dataframe = concat([values.shift(1), values], axis=1)
dataframe.columns = ['t-1', 't+1']
# split into train and test sets
X = dataframe.values
train_size = int(len(X) * 0.66)
train, test = X[1:train_size], X[train_size:]
train_X, train_y = train[:,0], train[:,1]
test_X, test_y = test[:,0], test[:,1]
# persistence model
predictions = [x for x in test_X]
# calculate residuals
residuals = [test_y[i]-predictions[i] for i in range(len(predictions))]
residuals = DataFrame(residuals)
autocorrelation_plot(residuals)
pyplot.show()
运行该示例会创建其他残差的自回归图。
整个情节我们没有看到明显的自相关趋势。可能存在一些值得进一步调查的正自相关,这在滞后 7 处似乎很重要。
每日女性出生数据集残差的自相关图
摘要
在本教程中,您了解了如何使用 Python 探索残差预测错误的时间序列。
具体来说,你学到了:
- 如何将预测残差的时间序列绘制为线图。
- 如何使用统计,密度图和 Q-Q 图来探索残差的分布。
- 如何检查自相关的剩余时间序列。
您对探索剩余错误时间序列或本教程有任何疑问吗? 在下面的评论中提出您的问题。
Python 中的白噪声时间序列
原文:
machinelearningmastery.com/white-noise-time-series-python/
白噪声是时间序列预测中的一个重要概念。
如果时间序列是白噪声,则它是一系列随机数并且无法预测。如果一系列预测误差不是白噪声,则表明可以对预测模型进行改进。
在本教程中,您将发现使用 Python 的白噪声时间序列。
完成本教程后,您将了解:
- 白噪声时间序列的定义及其重要性。
- 如何检查您的时间序列是否为白噪声。
- 统计和诊断图,用于识别 Python 中的白噪声。
让我们开始吧。
白噪声时间序列与 Python 照片由 Dan Eckert ,保留一些权利。
什么是白噪声时间序列?
时间序列可能是白噪声。
如果变量是独立的并且相同地分布为均值为零,则时间序列是白噪声。
这意味着所有变量具有相同的方差( sigma ^ 2 ),并且每个值与系列中的所有其他值具有零相关性。
如果系列中的变量是从高斯分布中提取的,则该系列称为高斯白噪声。
为什么这有关系?
白噪声是时间序列分析和预测中的一个重要概念。
这有两个主要原因:
- 可预测性:如果你的时间序列是白噪声,那么根据定义,它是随机的。您无法对其进行合理建模并做出预测。
- 模型诊断:时间序列预测模型中的一系列误差理想情况下应为白噪声。
模型诊断是时间序列预测的重要领域。
期望时间序列数据在基础过程生成的信号之上包含一些白噪声分量。
例如:
y(t) = signal(t) + noise(t)
一旦通过时间序列预测模型做出预测,就可以收集和分析它们。理想情况下,一系列预测误差应为白噪声。
当预测误差是白噪声时,意味着时间序列中的所有信号信息都已被模型利用以做出预测。剩下的就是无法建模的随机波动。
模型预测不是白噪声的迹象表明可能进一步改进预测模型。
你的时间系列白噪声?
如果满足以下任一条件,则您的时间序列不是白噪声:
- 你的系列是否有零均值?
- 方差是否随时间而变化?
- 值是否与滞后值相关?
您可以使用一些工具来检查时间序列是否为白噪声:
- 创建折线图。检查总体特征,例如变化的均值,方差或滞后变量之间的明显关系。
- 计算汇总统计。检查整个序列的均值和方差与系列中有意义的连续值块(例如,天,月或年)的均值和方差。
- 创建自相关图。检查滞后变量之间的总相关性。
白噪声时间序列示例
在本节中,我们将在 Python 中创建高斯白噪声系列并执行一些检查。
在实践中创建和查看白噪声时间序列是有帮助的。它将提供参考框架和示例图和统计测试,以便在您自己的时间序列项目中使用和比较,以检查它们是否是白噪声。
首先,我们可以使用随机模块中的gauss()函数创建 1,000 个随机高斯变量的列表。
我们将从高斯分布中绘制变量,其平均值(mu)为 0.0,标准偏差(sigma)为 1.0。
一旦创建,我们可以将列表包装在 Pandas 系列中以方便使用。
from random import gauss
from random import seed
from pandas import Series
from pandas.tools.plotting import autocorrelation_plot
# seed random number generator
seed(1)
# create white noise series
series = [gauss(0.0, 1.0) for i in range(1000)]
series = Series(series)
接下来,我们可以计算并打印一些汇总统计量,包括系列的均值和标准差。
# summary stats
print(series.describe())
鉴于我们在绘制随机数时定义了均值和标准差,应该没有意外。
count 1000.000000
mean -0.013222
std 1.003685
min -2.961214
25% -0.684192
50% -0.010934
75% 0.703915
max 2.737260
我们可以看到平均值接近 0.0,标准差接近 1.0。考虑到样本的小尺寸,预计会有一些差异。
如果我们有更多的数据,将系列分成两半并计算和比较每一半的汇总统计量可能会更有趣。我们希望每个子系列看到类似的均值和标准差。
现在我们可以创建一些图表,从系列的线图开始。
# line plot
series.plot()
pyplot.show()
我们可以看到该系列似乎是随机的。
白噪声系列线图
我们还可以创建直方图并确认分布是高斯分布。
# histogram plot
series.hist()
pyplot.show()
实际上,直方图显示了明显的钟形曲线形状。
白噪声系列直方图
最后,我们可以创建一个相关图并检查与滞后变量的任何自相关。
# autocorrelation
autocorrelation_plot(series)
pyplot.show()
相关图没有显示任何明显的自相关模式。
有一些峰值高于 95%和 99%的置信水平,但这些都是统计上的侥幸。
白噪声系列 Correlogram Plot
为完整起见,下面提供了完整的代码清单。
from random import gauss
from random import seed
from pandas import Series
from pandas.tools.plotting import autocorrelation_plot
from matplotlib import pyplot
# seed random number generator
seed(1)
# create white noise series
series = [gauss(0.0, 1.0) for i in range(1000)]
series = Series(series)
# summary stats
print(series.describe())
# line plot
series.plot()
pyplot.show()
# histogram plot
series.hist()
pyplot.show()
# autocorrelation
autocorrelation_plot(series)
pyplot.show()
进一步阅读
本节列出了一些用于进一步阅读白噪声和白噪声时间序列的资源。
- 白噪声过程,第 28 页,时间序列分析:预测和控制
- 第 4.2 节白噪声,引入时间序列与 R 。
- 维基百科上的白噪声
- 维基百科上的高斯噪声
摘要
在本教程中,您在 Python 中发现了白噪声时间序列。
具体来说,你学到了:
- 白噪声时间序列由零均值,常数方差和零相关定义。
- 如果您的时间序列是白噪声,则无法预测,如果您的预测残差不是白噪声,您可以改进模型。
- 您可以在时间序列中使用的统计量和诊断图来检查是否为白噪声。
您对本教程有任何疑问吗?在下面的评论中提出您的问题,我会尽力回答。
如何处理时间序列预测项目
原文:
machinelearningmastery.com/work-time-series-forecast-project/
时间序列预测过程是一组步骤或秘籍,可引导您定义问题,直至具有时间序列预测模型或预测集的结果。
在这篇文章中,您将发现可用于指导您完成预测项目的时间序列预测流程。
阅读这篇文章后,你会知道:
- Hyndman 和 Athanasopoulos 的 5 步预测任务将指导您从问题定义到使用和评估您的预测模型。
- Shmueli 和 Lichtendahl 的迭代预测开发流程将指导您将目标定义为实现预测。
- 处理您自己的时间序列预测项目的建议和技巧。
让我们开始吧。
如何通过时间序列预测项目 照片由 TravelingOtter ,保留一些权利。
5 步预测任务
Hyndman 和 Athanasopoulos 在他们的书预测:原则和实践中总结了预测任务中的 5 个基本步骤。这些步骤是:
- 问题定义。仔细考虑谁需要预测以及如何使用预测。这被描述为该过程中最困难的部分,很可能是因为它完全是问题特定和主观的。
- 收集信息。收集历史数据进行分析和建模。这还包括访问领域专家和收集有助于最好地解释历史信息的信息,以及最终将要进行的预测。
- 初步探索性分析。使用简单的工具(如图形和摘要统计)来更好地理解数据。回顾图并总结并注意明显的时间结构,如趋势季节性,缺失数据,腐败和异常值等异常情况,以及可能影响预测的任何其他结构。
- 选择和拟合模型。评估问题中的两个,三个或一组不同类型的模型。可以基于它们做出的假设以及数据集是否符合来选择模型用于评估。模型已配置并适合历史数据。
- 使用和评估预测模型。该模型用于做出预测,评估这些预测的表现并估算模型的技能。这可能涉及对历史数据进行回溯测试或等待新观察结果可用于比较。
这个 5 个步骤的过程提供了从概念或问题陈述开始到可用于做出预测的模型的强大概述。
该过程的重点是理解问题并拟合一个好的模型。
每个模型本身是一个基于一组假设(显式和隐式)的人工构造,并且通常涉及一个或多个必须使用已知历史数据“拟合”的参数。
- 第 22 页,预测:原则与实践
迭代预测开发过程
作者 Shmueli 和 Lichtendahl 在他们的书实用时间序列预测与 R:动手指南中提出了一个 8 步骤的过程。
这个过程超出了模型的开发和预测,并涉及迭代循环。
他们的过程可归纳如下:
- 定义目标。
- 获取数据。
- 探索和可视化系列。
- 预处理数据。
- 分区系列。
- 应用预测方法。
- 评估和比较表现。
- 实现预测/系统。
以下是流程中的迭代循环:
- 探索和可视化系列=&gt;获取数据。数据探索可能会导致需要访问新数据的问题。
- 评估和比较表现=&gt;应用预测方法/ 。对模型的评估可能会为新方法或新方法配置提出问题或想法。
该过程更侧重于对问题的一个或多个模型的持续开发和改进,直到达到可接受的表现水平。
随着新数据和新见解的提供,在修改和更新模型的过程中,此过程可以继续。
当然,一旦生成预测,该过程就不会结束,因为预测通常是一个持续的目标。因此,监测预测准确率,并且有时调整或改变预测方法以适应目标或数据随时间的变化
- 第 16 页, R 实用时间序列预测:动手指南
建议和提示
本节列出了在完成时间序列预测项目时需要考虑的 10 条建议和提示。
这些建议的主旨集中在这样一个前提,即你无法知道哪些方法可行,更不用说哪种方法可以预先解决你的问题。而预测项目的最佳知识来源是真实历史数据的试错结果。
- 选择或设计适合您的项目,工具,团队和专业水平的时间序列预测流程。
- 写下你在分析和预测工作中所有的假设和问题,然后在以后重新审视它们,并通过对历史数据的小实验来寻求答案。
- 在不同的时间尺度,缩放和观察变换中查看大量的数据图,以帮助使数据中的可利用结构显而易见。
- 使用有意义的表现测量和可靠的测试策略(例如前瞻性验证(滚动预测))开发用于评估模型的强大测试工具。
- 从简单的朴素预测模型开始,为更复杂的方法提供表现基准。
- 为您的时间序列数据创建大量透视图或视图,包括一套自动变换,并使用一个或一组模型评估每个透视图或视图,以帮助自动发现非直观的表示和模型组合,从而获得良好的预测你的问题。
- 从简单到更高级的方法,尝试一系列不同类型的模型来解决您的问题。
- 针对给定问题尝试一套配置,包括在其他问题上运行良好的配置。
- 尝试使用模型的自动超参数优化方法来清除一套表现良好的模型以及您不会手动尝试的非直观模型配置。
- 为正在进行的预测设计表现和技能的自动化测试,以帮助自动确定模型是否以及何时变得陈旧并需要审查或重新训练。
进一步阅读
本节列出了一些可用于了解时间序列预测过程的资源。
- 第 1.3 节预测过程,实际时间序列预测与 R:动手指南。
- 第 1.6 节预测任务的基本步骤,预测:原则和实践
你知道有关时间序列预测过程的任何好资源吗? 在下面的评论中分享。
摘要
在这篇文章中,您发现了可用于处理时间序列预测问题的流程。
具体来说,你学到了:
- 通过 Hyndman 和 Athanasopoulos 完成时间序列预测任务的 5 个步骤。
- 由 Shmueli 和 Lichtendahl 定义目标和实现预测系统的 8 步迭代过程。
- 在完成时间序列预测项目时需要考虑的 10 条建议和实用技巧。
您对时间序列预测流程或此帖有任何疑问吗? 在下面的评论中提出您的问题。