分层划分为列车并测试并处理每个层次的少量观测

时间:2014-09-28 18:21:22

标签: r cross-validation

想象一下,我有一个足球运动员的数据集'工资,国籍和高度。我有兴趣看看两个变量和足球运动员的薪水之间是否存在关联。我想出了一些不同的模型,并希望比较模型的预测效果。但要做到这一点,我需要在列车和测试数据中包含相同级别国籍的列车和测试数据。

想象一下,我的数据看起来像这样:

> soccer_player_df
     salary nationality   height
1  504731.1         USA 6.466627
2  485333.2         USA 5.468320
3  483259.4         USA 4.694929
4  493594.2         USA 5.685126
5  530805.8     England 5.856093
6  520851.5     England 6.031963
7  484309.9       Spain 6.127087
8  462986.6    Portugal 6.023823
9  492580.1      Brazil 5.949609
10 470410.0      Brazil 5.978207

我如何分割数据,以确保我至少可以观察到列车和测试数据中的每个国籍?

如果他是他的国籍的唯一代表(因此对于那个国家,我没有火车和测试对),我将如何移除一名足球运动员?

1 个答案:

答案 0 :(得分:2)

正如我在评论中提到的,我建议您查看my stratifiedDT function - 但需要注意:您需要至少使用 V1.9.3 的“data.table”版本,可以从"data.table" GitHub page获得。

我还使用“dplyr”方便过滤。

加载完该功能后,加载相关的软件包,然后执行以下操作:

library(dplyr)
library(data.table)

set.seed(1)
soccer_player_df %>%
  group_by(nationality) %>%
  filter(length(nationality) > 1) %>%
  stratifiedDT("nationality", .5, bothSets = TRUE)
# $SAMP1
# Source: local data frame [4 x 3]
# Groups: 
# 
#     salary nationality   height
# 1 492580.1      Brazil 5.949609
# 2 530805.8     England 5.856093
# 3 483259.4         USA 4.694929
# 4 493594.2         USA 5.685126
# 
# $SAMP2
# Source: local data frame [4 x 3]
# Groups: 
# 
#     salary nationality   height
# 1 470410.0      Brazil 5.978207
# 2 520851.5     England 6.031963
# 3 504731.1         USA 6.466627
# 4 485333.2         USA 5.468320

bothSets是一个新参数,可让您返回包含两个子集的list


如果你不喜欢生活在最前沿,你可以使用the data.frame version of the function,这非常快(但不如“data.table”版本那么快)。

用法几乎相同:

soccer_player_df %>%
  group_by(nationality) %>%
  filter(length(nationality) > 1) %>%
  stratified("nationality", .5, bothSets = TRUE)

更新

如果您只是想使用该功能而不想仅使用“dplyr”进行过滤和管道处理,您也可以直接在stratifiedstratifiedDT函数中进行子集化。我添加了参数的名称,以便您可以更清楚地看到发生了什么:

set.seed(1)
stratified(
  soccer_player_df, 
  group = "nationality", 
  size = .5, 
  select = list(
    nationality = names(which(table(soccer_player_df$nationality) > 1))), 
  bothSets = TRUE)

请注意,有一个select参数可让您指定您感兴趣的子集。