簡體   English   中英

按分區循環自動 Arima

[英]Loop Auto Arima by Partition

我正在合作一個項目,該項目要求我使用迄今為止我沒有任何經驗的 R。 我正在嘗試將 auto arima 應用於數據集中的分區/窗口,但我對如何開始一無所知。 3

本質上,我想使用行 c_id = "none" 在每個 partner_id 上訓練一個單獨的模型,然后預測/預測每個 partner_id 的最大值(日期)。 每個合作伙伴的月數/行數長短不一。 對於下面粘貼的這個示例數據框,partner_id = "1A9" 有 12 個月/行,c_id = "none" vs partner_id = "1B9" 有 13 個月/行,c_id = "none"。 每個partner_is 中擴展到max(Date) 的月數/行數也各不相同。 這很棘手,因為我假設我需要動態輸入要訓練的月數/行數以及要為每個合作伙伴 ID 預測的月數/行數。

我在下面包含了一個示例數據集。

x <- data.frame("c_id" = c("none","none","none","none","none",
"none","none","none","none","none","none","none","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101", "none","none","none","none","none","none","none","none","none","none","none","none","none","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111"), "partner_id" = c("1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9"), "rev_month" = as.Date(c("2016-01-01","2016-01-01","2016-02-01","2016-03-01","2016-04-01","2016-05-01","2016-06-01","2016-07-01","2016-08-01", "2016-09-01","2016-10-01","2016-11-01","2016-12-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01", "2017-01-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01", "2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01","2019-01-01","2019-02-01","2019-03-01","2019-04-01","2019-05-01","2019-06-01","2019-07-01","2019-08-01","2019-09-01","2019-10-01","2019-11-01","2019-12-01", "2020-01-01", "2020-02-01", "2020-03-01")), "rev" = c(101.25, 102.25, 103.50, 103.75, 104.15, 104.25, 104.3, 105.00, 105.20, 105.60, 106.00, 106.10, 106.50, 101.50, 100.30, 107.50, 108.30, 108.45, 109.10, 110.10, 112.15, 112.45, 114.65, 115.00, 116.00, 116.50, 117.25, 117.85, 119.25, 119.95, 120.20, 121.50, 122.30, 122.40, 123.25, 123.75, 124.00, 101.25, 102.25, 103.50, 103.75, 104.15, 104.25, 104.3, 105.00, 105.20, 105.60, 106.00, 106.10, 106.50, 101.50, 100.30, 107.50, 108.30, 108.45, 109.10, 110.10, 112.15, 112.45, 114.65, 115.00, 116.00, 116.50, 117.25, 117.85, 119.25, 119.95, 120.20, 121.50, 122.30, 122.40, 123.25, 123.75, 124.00, 124.10, 125.35, 125.45), stingsAsFactors=FALSE)

我很抱歉還沒有任何代碼入門代碼,因為我仍在嘗試從概念上考慮這一點,而對 R 沒有太多經驗。 最終,我想將預測列和置信區間添加回我的原始數據幀。 我願意接受任何 R 和/或 Python 解決方案。

從有關 R 和時間序列的編程角度來看,我的回答在很多層面上都是錯誤的。 主要方面是(還有其他問題,但我理解您的擔憂是使其盡快工作):

  1. 首先應該避免循環 - 但我的猜測是,矢量化的解決方案會讓你更難理解

  2. 如果您希望獲得季節性模式,那么將 arima 用於至少沒有兩個完整周期(在這種情況下為年)的時間序列並不是很有希望。

如果您真的對 R 中的時間序列預測主題感興趣,請閱讀這本書: https : //otexts.com/fpp2/

一個相關的附帶問題是您的測試數據:合作伙伴的兩個系列在第一個和第二個位置都有重復的日期,這與固定周期/間隔的時間序列預測不符 - 我只是落后於第一個以使事情起作用。 因此新的訓練數據是這樣的(我們不需要stringsAsFactores=FALSE):

 x <- data.frame(c_id = c("none","none","none","none","none","none","none","none","none","none","none","none","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-100","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101","c-101", "none","none","none","none","none","none","none","none","none","none","none","none","none","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-110","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111","c-111"), "partner_id" = c("1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1A9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9","1B9"),
                rev_month = as.Date(c("2015-12-01","2016-01-01","2016-02-01","2016-03-01","2016-04-01","2016-05-01","2016-06-01","2016-07-01","2016-08-01", "2016-09-01","2016-10-01","2016-11-01","2016-12-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01", "2016-12-31","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01", "2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01","2019-01-01","2019-02-01","2019-03-01","2019-04-01","2019-05-01","2019-06-01","2019-07-01","2019-08-01","2019-09-01","2019-10-01","2019-11-01","2019-12-01", "2020-01-01", "2020-02-01", "2020-03-01")),
                rev = c(101.25, 102.25, 103.50, 103.75, 104.15, 104.25, 104.3, 105.00, 105.20, 105.60, 106.00, 106.10, 106.50, 101.50, 100.30, 107.50, 108.30, 108.45, 109.10, 110.10, 112.15, 112.45, 114.65, 115.00, 116.00, 116.50, 117.25, 117.85, 119.25, 119.95, 120.20, 121.50, 122.30, 122.40, 123.25, 123.75, 124.00, 101.25, 102.25, 103.50, 103.75, 104.15, 104.25, 104.3, 105.00, 105.20, 105.60, 106.00, 106.10, 106.50, 101.50, 100.30, 107.50, 108.30, 108.45, 109.10, 110.10, 112.15, 112.45, 114.65, 115.00, 116.00, 116.50, 117.25, 117.85, 119.25, 119.95, 120.20, 121.50, 122.30, 122.40, 123.25, 123.75, 124.00, 124.10, 125.35, 125.45))

現在我們設置了一個 data.frame 來存儲預測 - 盡管這在理論上是不正確的(“永遠不會增長向量”)並且有更好的解決方案,但它會使它變得更加復雜並且無助於對實現的理解:

# empty data.frame to fill in predictions
predictions_df <- data.frame(c_id=character(),
                             partner=character(),
                             rev_month = character(),
                             rev=double())

現在我們構建一個獨特的合作伙伴向量來循環:

# unique partners
partners <- unique(x$partner_id)

讓我們調用本練習所需的庫:

library(xts)
library(dplyr)
library(forecast)

主要部分是循環本身:

# loop to build predictions and store them
for (i in 1:length(partners)){

  partner <- partners[i] # get specific partner
  x1 <- x[x$partner_id == partner, ] # get data for specific partner
  x1_t <- x1[x1$c_id == "none", c(3,4)] # training data
  x1_f <- x1[x1$c_id != "none", c(3,4)] # forecast data
  c_id <- x1[x1$c_id != "none", 1] # complementary data

  # convert training data to time-series object
  x1_t_ts <- xts(x1_t[,-1], order.by=as.Date(x1_t[,1], "%Y/%m/%d"))
  # run auto arima on the time series
  tm <- forecast::auto.arima(x1_t_ts)
  # forecast the number of future steps (rows for to predict data)
  fc <- forecast::forecast(tm, nrow(x1_f))

  predictions_df <- rbind(predictions_df, data.frame(c_id, partner, rev_month = as.character(x1_f$rev_month), rev = as.double(fc$mean)))

}

最后讓我們看看結果:

predictions_df

    c_id partner  rev_month      rev
1  c-100     1A9 2016-12-01 106.5409
2  c-100     1A9 2017-01-01 106.9818
3  c-100     1A9 2017-02-01 107.4227
4  c-100     1A9 2017-03-01 107.8636
5  c-100     1A9 2017-04-01 108.3045
6  c-100     1A9 2017-05-01 108.7455
7  c-100     1A9 2017-06-01 109.1864
8  c-100     1A9 2017-07-01 109.6273
9  c-100     1A9 2017-08-01 110.0682
10 c-100     1A9 2017-09-01 110.5091
11 c-100     1A9 2017-10-01 110.9500
12 c-100     1A9 2017-11-01 111.3909
13 c-101     1A9 2017-12-01 111.8318
14 c-101     1A9 2018-01-01 112.2727
15 c-101     1A9 2018-02-01 112.7136
16 c-101     1A9 2018-03-01 113.1545
17 c-101     1A9 2018-04-01 113.5955
18 c-101     1A9 2018-05-01 114.0364
19 c-101     1A9 2018-06-01 114.4773
20 c-101     1A9 2018-07-01 114.9182
21 c-101     1A9 2018-08-01 115.3591
22 c-101     1A9 2018-09-01 115.8000
23 c-101     1A9 2018-10-01 116.2409
24 c-101     1A9 2018-11-01 116.6818
25 c-101     1A9 2018-12-01 117.1227
26 c-110     1B9 2018-01-01 106.9375
27 c-110     1B9 2018-02-01 107.3750
28 c-110     1B9 2018-03-01 107.8125
29 c-110     1B9 2018-04-01 108.2500
30 c-110     1B9 2018-05-01 108.6875
31 c-110     1B9 2018-06-01 109.1250
32 c-110     1B9 2018-07-01 109.5625
33 c-110     1B9 2018-08-01 110.0000
34 c-110     1B9 2018-09-01 110.4375
35 c-110     1B9 2018-10-01 110.8750
36 c-110     1B9 2018-11-01 111.3125
37 c-110     1B9 2018-12-01 111.7500
38 c-111     1B9 2019-01-01 112.1875
39 c-111     1B9 2019-02-01 112.6250
40 c-111     1B9 2019-03-01 113.0625
41 c-111     1B9 2019-04-01 113.5000
42 c-111     1B9 2019-05-01 113.9375
43 c-111     1B9 2019-06-01 114.3750
44 c-111     1B9 2019-07-01 114.8125
45 c-111     1B9 2019-08-01 115.2500
46 c-111     1B9 2019-09-01 115.6875
47 c-111     1B9 2019-10-01 116.1250
48 c-111     1B9 2019-11-01 116.5625
49 c-111     1B9 2019-12-01 117.0000
50 c-111     1B9 2020-01-01 117.4375
51 c-111     1B9 2020-02-01 117.8750
52 c-111     1B9 2020-03-01 118.3125

如果您想獲得置信區間等,請解構循環(僅使用“i <- 1”運行內部部分)並了解正在發生的事情以及返回值是什么。 那么使用我提供的shemata來獲得你需要的東西應該沒有問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM