【问题标题】:Creating data partitions over a selected range of data to be fed into caret::train function for cross-validation在选定的数据范围内创建数据分区以输入 caret::train 函数以进行交叉验证
【发布时间】:2019-03-20 10:32:21
【问题描述】:

我想为下面的数据框创建千斤顶数据分区,这些分区将在caret::train 中使用(如caret::groupKFold() 产生的)。但是,问题是我想将测试点限制为大于 16 天,同时使用这些数据的其余部分作为训练集。

df <- data.frame(Effect = seq(from = 0.05, to = 1, by = 0.05),
     Time = seq(1:20))

我想这样做的原因是,我只对模型预测上限的能力真正感兴趣,因为这是感兴趣的区域。我觉得有一种方法可以使用 caret::groupKFold() 函数来做到这一点,但我不确定如何。任何帮助将不胜感激。

每个 CV 折叠包含的内容示例:

TrainSet1 <- subset(df, Time != 16)
TestSet1 <- subset(df, Time == 16)

TrainSet2 <- subset(df, Time != 17)
TestSet2 <- subset(df, Time == 17)

TrainSet3 <- subset(df, Time != 18)
TestSet3 <- subset(df, Time == 18)

TrainSet4 <- subset(df, Time != 19)
TestSet4 <- subset(df, Time == 19)

TrainSet5 <- subset(df, Time != 20)
TestSet5 <- subset(df, Time == 20)

尽管采用caret::groupKFold 函数输出的格式,以便可以将折叠输入caret::train 函数:

CVFolds <- caret::groupKFold(df$Time)
CVFolds

提前致谢!

【问题讨论】:

  • 我不清楚你到底想做什么。您能否在发布的数据上展示测试折叠(预期结果)的示例?
  • 抱歉,感谢您的建议!请参阅上面的编辑!

标签: r cross-validation r-caret data-partitioning


【解决方案1】:

我在内置函数中发现的自定义折叠通常不够灵活。因此我通常使用tidyverse 制作它们。解决您的问题的一种方法是:

library(tidyverse)

df %>%
  mutate(id = row_number()) %>% #use the row number as a column called id
  filter(Time > 15) %>% #filter Time as per your need
  split(.$Time)  %>% #split df to a list by Time
  map(~ .x %>% select(id)) #select row numbers for each list element

每次两行的例子:

df <- data.frame(Effect = seq(from = 0.025, to = 1, by = 0.025),
                 Time = rep(1:20, each = 2))

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 15) %>%
  split(.$Time)  %>%
  map(~ .x %>% select(id)) -> test_folds

test_folds
#output
$`16`
  id
1 31
2 32

$`17`
  id
3 33
4 34

$`18`
  id
5 35
6 36

$`19`
  id
7 37
8 38

$`20`
   id
9  39
10 40

每次行数不等

df <- data.frame(Effect = seq(from = 0.55, to = 1, by = 0.05),
                 Time = c(rep(1, 5), rep(2, 3), rep(rep(3, 2))))

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 1) %>%
  split(.$Time)  %>%
  map(~ .x %>% select(id))

$`2`
  id
1  6
2  7
3  8

$`3`
  id
4  9
5 10

现在您可以使用参数indexOuttrainControl 内定义这些保持折叠。

编辑:要获得与caret::groupKFold 类似的输出,可以:

df %>%
  mutate(id = row_number()) %>%
  filter(Time > 1) %>%
  split(.$Time)  %>%
  map(~ .x %>%
        select(id) %>%
        unlist %>%
        unname) %>%
  unname

【讨论】:

  • 你好误用,谢谢你的帮助!我刚刚回来看这些东西并遇到了一个小问题。上述代码的输出是带有单个整数列的 tibbles 列表,但 trainControl 函数需要包含单个整数向量的列表。我玩过它,但我对 tidyverse 不是很熟悉,也无法对其进行更改以提供所需的输出。所需格式显示在caret::groupKfold(data$Time) 行中。提前谢谢!
  • 您可以在地图调用中添加一个unlist。检查编辑。
  • 再次感谢@missuse 的帮助!我遇到了另一个我没有预见到的问题——如果我有这样的数据结构:df &lt;- data.frame(Effect = rep(seq(from = 0.05, to = 1, by = 0.05), each = 5), Time = rep(seq(1:20), each = 5))。有没有办法调整您的代码以获取上限中的每​​个时间点(例如 > 15)并在每一行中创建一个折叠? IE。大括号中的每个时间点都被用作测试集一次,而所有其他数据都用于训练。
  • 诸如遗漏一份简历但只包含所有数据的指定子集的东西?是的,但我认为如果您将此作为单独的问题发布会更好,因为 cmets 中的多个子问题通常会导致其他人通常难以解释的答案。
猜你喜欢
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2016-06-24
  • 2020-03-08
  • 2013-11-06
  • 1970-01-01
相关资源
最近更新 更多