预测模型识别未来趋势

数据挖掘 机器学习 预测建模 回归 特征选择
2022-02-15 08:48:29

我建立了一个预测呼叫数据的预测模型。预测模型使用随机森林回归模型。

数据:自 2013 年以来,我每年每隔 15 分钟调用一次数据。

以下是数月累积值的图表:

通话数据

可以清楚地看到,2017 年的通话数据比 2016 年几乎翻了一番。这种趋势在未来几年也应该可以观察到。

特征:

首先,我的数据格式:

 DATE                     CALL
 ....
 2017-10-23 10:15:00.000    259
 2017-10-23 10:30:00.000    292
 2017-10-23 10:45:00.000    309
 ....

从中我提取了以下特征:我提取了以下特征来预测我的目标变量 Y(调用数据):

-Weekday
-Month
-Holiday (yes / no)
-Interval of the day

So I ask my model:

What is the call volume of a day and interval with the following features?

我已经使用 2015-2016-2017 年来训练模型。然而,该模型并没有给出预期的预后。

他甚至错误地预测了 2017 年的日子。虽然我给了他数据作为训练数据。

问题:

- Should I work on my features?

- How do I show my forecasting model that the data will double year by year 
  as observable since 2016?
3个回答

在进入建模之前,我想你可以做更多的探索性分析(逐月,逐年)。如果您发现任何趋势或季节性等。

为什么不使用ARIMA、ARMA、指数平滑AR之类的基础技术而直接进入 RF。

有时 RF 可能不会像基本模型那样给你带来好的结果,我认为你没有趋势,这是来自你的图表(但不确定)。如果您可以尝试做一些研究,看看是否有一些外部因素影响您的需求。为什么会发生这种情况,它的根本原因是什么。

为了让您的模型理解,它需要一些能够以某种方式解释其尖峰的特性,它可以通过进行特性 engg/ 研究来实现

随机森林和一般的基于树的模型不能很好地处理趋势。

原因很简单:在任何决策树内部,都有离散规则,例如: 这是深度为 1 的树(所谓的“茎”),但更深的树遵循相同的逻辑。变量和常量适合训练数据。这就是问题所在:如果在训练数据中从未高于,那么即使明显增加,您的树也永远不会预测

y={y1,if x>cy2,if x<=c
xy1y2cyy1y>y1y

另一方面,线性模型(例如 XARIMA 及其特殊情况)可以很好地捕捉趋势。但是它们在数据中的非线性和特征相互作用很差。根据我自己的经验,以下堆叠方法效果最好:

  1. 为您的数据拟合一个简单的基于时间的线性模型。
  2. 将基于树的模型(随机森林或提升)拟合到线性模型的残差。

如果正确指定了线性模型,它将捕获并消除数据中的非平稳性。因此,基于树的模型将预测静态残差并找到比线性模型更精细的依赖关系。

这个 Python 示例说明了这个问题:

import numpy as np
from sklearn.datasets import make_friedman2
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import HuberRegressor
from sklearn.metrics import r2_score
from sklearn.model_selection import cross_val_predict

# make a difficult dataset with a linear trend
X, y = make_friedman2(n_samples=1000, random_state=1, noise=10)
time = np.arange(1000)
y += time * 1.5
X = np.hstack([X, time[:, np.newaxis]])
X_train, y_train = X[:700], y[:700]
X_test, y_test = X[700:], y[700:]

# build a pure Random Forest
rf = RandomForestRegressor(random_state=1, n_jobs=-1).fit(X_train, y_train)
y_rf = rf.predict(X_test)

# build a pure linear model
linear = HuberRegressor().fit(X_train, y_train)
y_lin = linear.predict(X_test)

# build a stack of two models
lin_resid = y_train - cross_val_predict(linear, X_train, y_train)
rf.fit(X_train, lin_resid)
y_stack = y_lin + rf.predict(X_test)

print(r2_score(y_test, y_rf))    # R2 on test data is only 0.34
print(r2_score(y_test, y_lin))   # R2 due to time trend is 0.86 
print(r2_score(y_test, y_stack)) # R2 of combined model is 0.95

考虑到您的数据(您在上面显示的示例),我建议tbats()使用 R 中的预测包中的函数。因为您的数据可能具有每小时和每天的季节性,这建议我们使用“TBATS 模型(具有 Box-Cox 转换的指数平滑状态空间模型) , ARMA 错误, 趋势和季节性分量)"

参考文献:De Livera, AM, Hyndman, RJ, & Snyder, RD (2011),使用指数平滑法预测具有复杂季节性模式的时间序列,美国统计协会杂志,106(496)

或者您可以使用动态谐波回归。参考和示例https://otexts.org/fpp2/complexseasonality.html