我想使用 R 包 rsample 来生成我的数据的重采样。

该包提供了函数 rolling_origin 来生成保持数据时间序列结构的重采样。这意味着训练数据(在名为 analysis 的包中)总是在测试数据( assessment )的过去。

另一方面,我想执行数据的块样本。这意味着在采样期间行组保持在一起。这可以使用函数 group_vfold_cv 来完成。人们可以想到的团体是几个月。说,我们想要做时间序列交叉验证,总是保持几个月的时间。

有没有办法在 rsample 中结合这两种方法?

我为每个程序单独举例:

## generate some data
library(tidyverse)
library(lubridate)
library(rsample)
my_dates = seq(as.Date("2018/1/1"), as.Date("2018/8/20"), "days")
some_data = data_frame(dates = my_dates)
some_data$values = runif(length(my_dates))
some_data = some_data %>% mutate(month = as.factor(month(dates)))

这给出了以下形式的数据
 A tibble: 232 x 3
   dates      values month
   <date>      <dbl> <fctr>
 1 2018-01-01 0.235  1
 2 2018-01-02 0.363  1
 3 2018-01-03 0.146  1
 4 2018-01-04 0.668  1
 5 2018-01-05 0.0995 1
 6 2018-01-06 0.163  1
 7 2018-01-07 0.0265 1
 8 2018-01-08 0.273  1
 9 2018-01-09 0.886  1
10 2018-01-10 0.239  1

然后我们可以例如生成需要 20 周数据并在 future 5 周进行测试的样本(参数 skip 跳过一些额外的行):
rolling_origin_resamples <- rolling_origin(
  some_data,
  initial    = 7*20,
  assess     = 7*5,
  cumulative = TRUE,
  skip       = 7
)

我们可以用下面的代码检查数据,看不到重叠:
rolling_origin_resamples$splits[[1]] %>% analysis %>% tail
# A tibble: 6 x 3
  dates       values month
  <date>       <dbl> <fctr>
1 2018-05-15 0.678   5
2 2018-05-16 0.00112 5
3 2018-05-17 0.339   5
4 2018-05-18 0.0864  5
5 2018-05-19 0.918   5
6 2018-05-20 0.317   5

### test data of first split:
rolling_origin_resamples$splits[[1]] %>% assessment
# A tibble: 6 x 3
  dates      values month
  <date>      <dbl> <fctr>
1 2018-05-21  0.912 5
2 2018-05-22  0.403 5
3 2018-05-23  0.366 5
4 2018-05-24  0.159 5
5 2018-05-25  0.223 5
6 2018-05-26  0.375 5

或者,我们可以按月拆分:
## sampling by month:
gcv_resamples = group_vfold_cv(some_data, group = "month", v = 5)
gcv_resamples$splits[[1]]  %>% analysis %>% select(month) %>% summary
gcv_resamples$splits[[1]] %>% assessment %>% select(month) %>% summary

最佳答案

正如@missuse 的解决方案的评论中所讨论的,实现这一点的方法记录在 github 问题中:https://github.com/tidymodels/rsample/issues/42

本质上,这个想法是首先嵌套在你的“块”上,然后 rolling_origin() 将允许你滚动它们,保持完整的块完好无损。

library(dplyr)
library(lubridate)
library(rsample)
library(tidyr)
library(tibble)

# same data generation as before
my_dates = seq(as.Date("2018/1/1"), as.Date("2018/8/20"), "days")
some_data = data_frame(dates = my_dates)
some_data$values = runif(length(my_dates))
some_data = some_data %>% mutate(month = as.factor(month(dates)))

# nest by month, then resample
rset <- some_data %>%
  group_by(month) %>%
  nest() %>%
  rolling_origin(initial = 1)

# doesn't show which month is which :(
rset
#> # Rolling origin forecast resampling
#> # A tibble: 7 x 2
#>   splits       id
#>   <list>       <chr>
#> 1 <S3: rsplit> Slice1
#> 2 <S3: rsplit> Slice2
#> 3 <S3: rsplit> Slice3
#> 4 <S3: rsplit> Slice4
#> 5 <S3: rsplit> Slice5
#> 6 <S3: rsplit> Slice6
#> 7 <S3: rsplit> Slice7


# only January (31 days)
analysis(rset$splits[[1]])$data
#> [[1]]
#> # A tibble: 31 x 2
#>    dates      values
#>    <date>      <dbl>
#>  1 2018-01-01 0.373
#>  2 2018-01-02 0.0389
#>  3 2018-01-03 0.260
#>  4 2018-01-04 0.803
#>  5 2018-01-05 0.595
#>  6 2018-01-06 0.875
#>  7 2018-01-07 0.273
#>  8 2018-01-08 0.180
#>  9 2018-01-09 0.662
#> 10 2018-01-10 0.849
#> # ... with 21 more rows


# only February (28 days)
assessment(rset$splits[[1]])$data
#> [[1]]
#> # A tibble: 28 x 2
#>    dates      values
#>    <date>      <dbl>
#>  1 2018-02-01 0.402
#>  2 2018-02-02 0.556
#>  3 2018-02-03 0.764
#>  4 2018-02-04 0.134
#>  5 2018-02-05 0.0333
#>  6 2018-02-06 0.907
#>  7 2018-02-07 0.814
#>  8 2018-02-08 0.0973
#>  9 2018-02-09 0.353
#> 10 2018-02-10 0.407
#> # ... with 18 more rows

reprex package (v0.2.0) 于 2018 年 8 月 28 日创建。

关于r - 在 rsample 中结合滚动原点预测重采样和组 V 折叠交叉验证,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51925991/

10-12 17:34