R语言 指数平滑法

R语言 指数平滑法

指数平滑是一种使用指数窗口函数对时间序列数据进行平滑的技术。它是一种经验法则。与简单的移动平均不同,随着时间的推移,指数函数分配的权重呈指数递减。在这里,较大的权重被放在最近的数值或观测值上,而较小的权重被放在较早的数值或观测值上。在许多窗口函数中,在信号处理中,指数平滑函数通常被应用于平滑数据,它作为一个低通滤波器,以去除高频噪声。这种方法相当直观,一般可以应用于广泛或巨大的时间序列,而且计算效率高。在这篇文章中,让我们讨论一下R编程中的指数平滑法。基于趋势和季节性的指数平滑技术有很多类型,具体如下。

  • 简单指数平滑法
  • 霍尔特的方法
  • 霍尔特-温特的季节性方法
  • 阻尼趋势法

在继续之前,需要看看复制的要求。

在R中分析的复制要求

在R语言中,本分析的先决条件是安装所需的包。我们需要在R控制台使用 install.packages() 命令来安装以下两个包。

  • fpp2 (预测包将被自动加载)。
  • tidyverse

在预测包下,我们将得到许多功能,这些功能将加强和帮助我们的预测。在这个分析中,我们将在 fpp2 包下处理两个数据集。它们是 “goog “数据集和 “qcement “数据集。现在我们需要使用 library() 函数在我们的R脚本中加载所需的包。在加载这两个包之后,我们将准备我们的数据集。对于这两个数据集,我们将把数据分成两组,即训练集和测试集。

# loading the required packages
library(tidyverse)
library(fpp2)
 
# create training and testing set
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# create training and testing
# set of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
R

现在我们准备进行分析了。

简单指数平滑法(SES)

简单指数平滑 技术用于没有趋势或季节性模式的数据。SES是所有指数平滑技术中最简单的一种。我们知道,在任何类型的指数平滑中,我们对最近的数值或观测值的权重比对旧的数值或观测值的权重要高。每一个参数的权重总是由一个 平滑参数阿尔法 决定 。 在实践中,如果阿尔法在0.1和0.2之间,那么SES将表现得相当好。当α值接近0时,它被认为是缓慢的学习,因为该算法给予历史数据更多的权重。如果α值接近于1,那么它被称为快速学习,因为该算法给予最近的观察或数据更多的权重。因此,我们可以说,数据中最近的变化将对预测留下更大的影响。

在R中,为了执行简单指数平滑分析,我们需要使用 ses() 函数。为了理解这个技术,我们将看到一些例子。我们将使用goog的SES数据集。

例1 :

在这个例子中,我们为我们的初始模型设置了α=0.2和预测前移步数h=100。

# SES in R
# loading the required packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog, end = 900)
goog.test <- window(goog, start = 901)
 
# Performing SES on  the
# Google stock data
ses.goog <- ses(goog.train,
                alpha = .2,
                h = 100)
autoplot(ses.goog)
R

输出

R编程中的指数平滑法

从上面的输出图中,我们可以注意到,我们的预测模型对未来的预测是一个平缓的估计。因此,我们可以说,从数据来看,它没有捕捉到目前的趋势。因此,为了纠正这一点,我们将使用 diff() 函数来去除数据中的趋势。

例2 :

# SES in R
# loading the required packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# removing the trend
goog.dif <- diff(goog.train)
autoplot(goog.dif)
 
# reapplying SES on the filtered data
ses.goog.dif <- ses(goog.dif,
                    alpha = .2,
                    h = 100)
autoplot(ses.goog.dif)
R

输出

R编程中的指数平滑法

为了了解我们模型的性能,我们需要将我们的预测与验证或测试数据集进行比较。由于我们的训练数据集是有差异的,我们也需要形成或创建有差异的验证或测试集。

例3 :

这里我们要创建一个差分验证集,然后将我们的预测与验证集进行比较。在这里,我们使用循环设置了0.01-0.99的α值。我们试图了解哪个水平将使RMSE测试最小化。我们将看到,0.05将是最小的。

# SES in R
# loading the required packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# removing trend from test set
goog.dif.test <- diff(goog.test)
accuracy(ses.goog.dif, goog.dif.test)
 
# comparing our model
alpha <- seq(.01, .99, by = .01)
RMSE <- NA
for(i in seq_along(alpha)) {
  fit <- ses(goog.dif, alpha = alpha[i],
             h = 100)
  RMSE[i] <- accuracy(fit,
                      goog.dif.test)[2,2]
}
 
# convert to a data frame and
# identify min alpha value
alpha.fit <- data_frame(alpha, RMSE)
alpha.min <- filter(alpha.fit,
                    RMSE == min(RMSE))
 
# plot RMSE vs. alpha
ggplot(alpha.fit, aes(alpha, RMSE)) +
  geom_line() +
  geom_point(data = alpha.min,
             aes(alpha, RMSE),
             size = 2, color = "red")
R

输出

                      ME     RMSE      MAE       MPE     MAPE      MASE        ACF1 Theil's U
Training set -0.01368221 9.317223 6.398819  99.97907 253.7069 0.7572009 -0.05440377        NA
Test set      0.97219517 8.141450 6.117483 109.93320 177.9684 0.7239091  0.12278141 0.9900678
R

R编程中的指数平滑法

现在,我们将尝试用α=0.05来重新拟合我们对SES的预测模型。我们会注意到α0.02和α=0.05之间的显著差异。

例4 :

# SES in R
# loading packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# removing trend
goog.dif <- diff(goog.train)
 
# refit model with alpha = .05
ses.goog.opt <- ses(goog.dif,
                    alpha = .05,
                    h = 100)
 
# performance eval
accuracy(ses.goog.opt, goog.dif.test)
 
# plotting results
p1 <- autoplot(ses.goog.opt) +
  theme(legend.position = "bottom")
p2 <- autoplot(goog.dif.test) +
  autolayer(ses.goog.opt, alpha = .5) +
  ggtitle("Predicted vs. actuals for
                 the test data set")
 
gridExtra::grid.arrange(p1, p2,
                        nrow = 1)
R

输出

> accuracy(ses.goog.opt, goog.dif.test)
                      ME     RMSE      MAE       MPE     MAPE      MASE       ACF1 Theil's U
Training set -0.01188991 8.939340 6.030873 109.97354 155.7700 0.7136602 0.01387261        NA
Test set      0.30483955 8.088941 6.028383  97.77722 112.2178 0.7133655 0.12278141 0.9998811
R

R编程中的指数平滑法

我们将看到,现在我们模型的预测置信区间要窄得多。

霍尔特的方法

我们已经看到,在SES中,我们必须去除长期趋势以改善模型。但在 霍尔特方法 中,我们可以在捕捉数据趋势的同时应用指数平滑法。这是一种适用于有趋势但无季节性的数据的技术。为了对数据进行预测,霍尔特方法使用了两个 平滑参数,α和β ,它们分别对应于水平成分和趋势成分。

在R语言中,为了应用霍尔特方法,我们将使用 holt() 函数。我们将再次通过一些例子来了解这一技术的工作原理。我们将再次使用goog数据集。

例1 :

# holt's method in R
 
# loading packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# applying holt's method on
# Google stock Data
holt.goog <- holt(goog.train,
                  h = 100)
autoplot(holt.goog)
R

输出

R编程中的指数平滑法

在上述例子中,我们没有手动设置α和β的值。但我们可以这样做。然而,如果我们提到阿尔法和贝塔的任何值,那么 holt() 函数将自动识别最佳值。在这个例子中,如果阿尔法的值是0.9967,那么它表示快速学习,如果贝塔的值是0.0001,那么它表示趋势的缓慢学习。

例子2 :

在这个例子中,我们将设置α和β的值。同时,我们将看到模型的准确性。

# holt's method in R
 
# loading the packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# holt's method
holt.goog$model
 
# accuracy of the model
accuracy(holt.goog, goog.test)
R

输出

Holt's method 

Call:
 holt(y = goog.train, h = 100) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 1e-04 

  Initial states:
    l = 401.1276 
    b = 0.4091 

  sigma:  8.8149

     AIC     AICc      BIC 
10045.74 10045.81 10069.75 

> accuracy(holt.goog, goog.test)
                       ME      RMSE       MAE         MPE     MAPE     MASE       ACF1 Theil's U
Training set -0.003332796  8.795267  5.821057 -0.01211821 1.000720 1.002452 0.03100836        NA
Test set      0.545744415 16.328680 12.876836  0.03013427 1.646261 2.217538 0.87733298  2.024518
R

最佳值,即β=0.0001,用于消除训练集中的错误。我们可以将我们的β值调整到这个最佳值。

例3 :

让我们尝试通过一个从0.0001到0.5的循环找到beta的最佳值 ,使RMSE测试最小。我们将看到,0.0601将是能使RMSE下降的β值。

# holts method in R
# loading the package
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
# identify optimal alpha parameter
beta <- seq(.0001, .5, by = .001)
RMSE <- NA
for(i in seq_along(beta)) {
  fit <- holt(goog.train,
              beta = beta[i],
              h = 100)
  RMSE[i] <- accuracy(fit,
                      goog.test)[2,2]
}
 
# convert to a data frame and
# identify min alpha value
beta.fit <- data_frame(beta, RMSE)
beta.min <- filter(beta.fit,
                   RMSE == min(RMSE))
 
# plot RMSE vs. alpha
ggplot(beta.fit, aes(beta, RMSE)) +
  geom_line() +
  geom_point(data = beta.min,
             aes(beta, RMSE),
             size = 2, color = "red")
R

输出

R编程中的指数平滑法

现在让我们用得到的最优β值重新构建模型。

例4 :

我们将设定β的最佳值,并与我们的原始模型比较预测的准确性。

# loading the package
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the Google stock data
goog.train <- window(goog,
                     end = 900)
goog.test <- window(goog,
                    start = 901)
 
holt.goog <- holt(goog.train,
                  h = 100)
 
# new model with optimal beta
holt.goog.opt <- holt(goog.train,
                      h = 100,
                      beta = 0.0601)
 
# accuracy of first model
accuracy(holt.goog, goog.test)
 
# accuracy of new optimal model
accuracy(holt.goog.opt, goog.test)
 
p1 <- autoplot(holt.goog) +
  ggtitle("Original Holt's Model") +
  coord_cartesian(ylim = c(400, 1000))
 
p2 <- autoplot(holt.goog.opt) +
  ggtitle("Optimal Holt's Model") +
  coord_cartesian(ylim = c(400, 1000))
 
gridExtra::grid.arrange(p1, p2,
                        nrow = 1)
R

输出

> accuracy(holt.goog, goog.test)
                       ME      RMSE       MAE         MPE     MAPE     MASE       ACF1 Theil's U
Training set -0.003332796  8.795267  5.821057 -0.01211821 1.000720 1.002452 0.03100836        NA
Test set      0.545744415 16.328680 12.876836  0.03013427 1.646261 2.217538 0.87733298  2.024518

> accuracy(holt.goog.opt, goog.test)
                      ME      RMSE       MAE          MPE     MAPE     MASE        ACF1 Theil's U
Training set -0.01493114  8.960214  6.058869 -0.005524151 1.039572 1.043406 0.009696325        NA
Test set     21.41138275 28.549029 23.841097  2.665066997 2.988712 4.105709 0.895371665  3.435763
R

R编程中的指数平滑法

我们会发现,与原始模型相比,最优模型要保守得多。同时,最优模型的置信区间也更加极端。

霍尔特-温特的季节性方法

霍尔特-温特的季节性 方法被用于具有季节性模式和趋势的数据。这个方法可以通过使用 加法结构 或使用 乘法结构 来实现,这取决于数据集的情况。当数据的季节性模式具有相同的幅度或始终保持一致时,就采用加法结构或模型,而如果数据的季节性模式的幅度随时间的推移而增加,就采用乘法结构或模型。它使用 三个平滑参数,即α、β和γ。

在R中,我们使用 decompose() 函数来执行这种指数平滑。我们将使用qcement数据集来研究这种技术的工作。

例1 :

# Holt-Winter's method in R
# loading packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
 
# applying holt-winters
# method on qcement
autoplot(decompose(qcement))
R

输出

R编程中的指数平滑法

为了创建一个处理误差、趋势和季节性的加性模型,我们将使用ets () 函数。在36个模型中,ets () 选择了最佳的加性模型。对于加性模型,ets () 的模型参数将是’AAA’。

例2 :

# loading package
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
 
# applying ets
qcement.hw <- ets(qcement.train,
                  model = "AAA")
autoplot(forecast(qcement.hw))
R

输出

R编程中的指数平滑法

现在我们将评估我们的模型并总结出平滑参数。我们还将检查残差并找出我们模型的准确性。

例3 :

# additive model
# loading packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
 
qcement.hw <- ets(qcement.train, model = "AAA")
 
# assessing our model
summary(qcement.hw)
checkresiduals(qcement.hw)
 
# forecast the next 5 quarters
qcement.f1 <- forecast(qcement.hw,
                       h = 5)
 
# check accuracy
accuracy(qcement.f1, qcement.test)
R

输出

> summary(qcement.hw)
ETS(A,A,A) 

Call:
 ets(y = qcement.train, model = "AAA") 

  Smoothing parameters:
    alpha = 0.6418 
    beta  = 1e-04 
    gamma = 0.1988 

  Initial states:
    l = 0.4511 
    b = 0.0075 
    s = 0.0049 0.0307 9e-04 -0.0365

  sigma:  0.0854

     AIC     AICc      BIC 
126.0419 126.8676 156.9060 

Training set error measures:
                      ME       RMSE       MAE          MPE     MAPE      MASE       ACF1
Training set 0.001463693 0.08393279 0.0597683 -0.003454533 3.922727 0.5912949 0.02150539

> checkresiduals(qcement.hw)

    Ljung-Box test

data:  Residuals from ETS(A,A,A)
Q* = 20.288, df = 3, p-value = 0.0001479

Model df: 8.   Total lags used: 11

> accuracy(qcement.f1, qcement.test)
                      ME       RMSE        MAE          MPE     MAPE      MASE        ACF1 Theil's U
Training set 0.001463693 0.08393279 0.05976830 -0.003454533 3.922727 0.5912949  0.02150539        NA
Test set     0.031362775 0.07144211 0.06791904  1.115342984 2.899446 0.6719311 -0.31290496 0.2112428
R

R编程中的指数平滑法

现在我们要看看乘法模型是如何使用ets () 工作的 。 为此,ets () 的模型参数将是 “MAM”。

例4 :

# multiplicative model in R
# loading package
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
 
# applying ets
qcement.hw2 <- ets(qcement.train,
                   model = "MAM")
checkresiduals(qcement.hw2)
R

输出

> checkresiduals(qcement.hw2)

    Ljung-Box test

data:  Residuals from ETS(M,A,M)
Q* = 23.433, df = 3, p-value = 3.281e-05

Model df: 8.   Total lags used: 11
R

R编程中的指数平滑法

在这里,我们将优化gamma参数,以最小化错误率。伽马的值将是0.21。同时,我们将找出准确度,并绘制预测值。

例5 :

# Holt winters model in R
# loading packages
library(tidyverse)
library(fpp2)
 
# create training and validation
# of the AirPassengers data
qcement.train <- window(qcement,
                        end = c(2012, 4))
qcement.test <- window(qcement,
                       start = c(2013, 1))
 
qcement.hw <- ets(qcement.train,
                  model = "AAA")
 
# forecast the next 5 quarters
qcement.f1 <- forecast(qcement.hw,
                       h = 5)
 
# check accuracy
accuracy(qcement.f1, qcement.test)
 
gamma <- seq(0.01, 0.85, 0.01)
RMSE <- NA
 
for(i in seq_along(gamma)) {
  hw.expo <- ets(qcement.train,
                 "AAA",
                 gamma = gamma[i])
  future <- forecast(hw.expo,
                     h = 5)
  RMSE[i] = accuracy(future,
                     qcement.test)[2,2]
}
 
error <- data_frame(gamma, RMSE)
minimum <- filter(error,
                  RMSE == min(RMSE))
ggplot(error, aes(gamma, RMSE)) +
  geom_line() +
  geom_point(data = minimum,
             color = "blue", size = 2) +
  ggtitle("gamma's impact on
            forecast errors",
  subtitle = "gamma = 0.21 minimizes RMSE")
 
# previous model with additive
# error, trend and seasonality
accuracy(qcement.f1, qcement.test)
 
 
# new model with
# optimal gamma parameter
qcement.hw6 <- ets(qcement.train,
                   model = "AAA",
                   gamma = 0.21)
qcement.f6 <- forecast(qcement.hw6,
                       h = 5)
accuracy(qcement.f6, qcement.test)
 
# predicted values
qcement.f6
autoplot(qcement.f6)
R

输出

> accuracy(qcement.f1, qcement.test)
                      ME       RMSE        MAE          MPE     MAPE      MASE        ACF1 Theil's U
Training set 0.001463693 0.08393279 0.05976830 -0.003454533 3.922727 0.5912949  0.02150539        NA
Test set     0.031362775 0.07144211 0.06791904  1.115342984 2.899446 0.6719311 -0.31290496 0.2112428

> accuracy(qcement.f6, qcement.test)
                       ME       RMSE        MAE        MPE     MAPE      MASE        ACF1 Theil's U
Training set -0.001312025 0.08377557 0.05905971 -0.2684606 3.834134 0.5842847  0.04832198        NA
Test set      0.033492771 0.07148708 0.06775269  1.2096488 2.881680 0.6702854 -0.35877010 0.2202448

> qcement.f6
        Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
2013 Q1       2.134650 2.025352 2.243947 1.967494 2.301806
2013 Q2       2.427828 2.299602 2.556055 2.231723 2.623934
2013 Q3       2.601989 2.457284 2.746694 2.380681 2.823296
2013 Q4       2.505001 2.345506 2.664496 2.261075 2.748927
2014 Q1       2.171068 1.987914 2.354223 1.890958 2.451179
R

R编程中的指数平滑法

R中的阻 尼法

阻尼法使用 阻尼系数 phi 来更保守地估计预测的趋势。如果我们相信我们的加法和乘法模型将是一条平坦的线,那么它有可能是阻尼的。为了理解阻尼预测的工作原理,我们将使用 fpp2::ausair 数据集,我们将创建许多模型,并试图获得更保守的趋势线。

例子

# Damping model in R
 
# loading the packages
library(tidyverse)
library(fpp2)
 
# holt's linear (additive) model
fit1 <- ets(ausair, model = "ZAN",
            alpha = 0.8, beta = 0.2)
pred1 <- forecast(fit1, h = 5)
 
# holt's linear (additive) model
fit2 <- ets(ausair, model = "ZAN",
            damped = TRUE, alpha = 0.8,
            beta = 0.2, phi = 0.85)
pred2 <- forecast(fit2, h = 5)
 
# holt's exponential
# (multiplicative) model
fit3 <- ets(ausair, model = "ZMN",
            alpha = 0.8, beta = 0.2)
pred3 <- forecast(fit3, h = 5)
 
# holt's exponential
# (multiplicative) model damped
fit4 <- ets(ausair, model = "ZMN",
            damped = TRUE,
            alpha = 0.8, beta = 0.2,
            phi = 0.85)
pred4 <- forecast(fit4, h = 5)
 
autoplot(ausair) +
  autolayer(pred1mean,
            color = "blue") +
  autolayer(pred2mean,
            color = "blue",
            linetype = "dashed") +
  autolayer(pred3mean,
            color = "red") +
  autolayer(pred4mean,
            color = "red",
            linetype = "dashed")
R

输出

R编程中的指数平滑法

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册