生成具有R中随机选择特征的数据集列表

时间:2019-02-11 18:36:30

标签: r feature-selection

我有一个包含20个要素的数据集。我希望创建一个数据集列表,其中包含来自原始数据集的特征的随机子集。 例如-[dataset[, c(1,3,4)], dataset[, c(2,3,5,11,20)]]

我正在尝试以下代码

selectors = array(runif(2000), dim=c(100, 20, 1))
list_datasets = vector("list", 100)
i = 1
while(i < 100)
  list_datasets[[i]] = dataset[, selectors[i,,1] > 0.5]
  i = i + 1

在这里,我的dataset具有20个特征,在这20个特征中,我需要100个具有随机特征的数据集。因此,我创建了selectors数组,方法是首先创建一个带有随机值的大小为2000的向量,然后将其设置为100 * 20。然后,在while循环中,仅当为其生成的随机值大于0.5时,我才尝试向list_datasets[[i]]添加一个功能。希望我能够自我解释

但这很慢。我是R的新手,想知道实现我正在尝试的最佳方法是什么。

1 个答案:

答案 0 :(得分:0)

我不确定我是否了解您的设置,如果错过了一些内容,请纠正我。我的理解是,您有一个数据集(我创建了一个大小为100行x 20个特征的假数据集),并希望使用特征的随机子集创建100个新数据集。您可以通过生成随机的统一值并检查每个值是否大于0.5来生成要素的随机子集。

我在这里有两个选择,一个使用lapply,另一个使用for循环。

apply函数通常比循环要快(我认为您想使用for循环,而不是这里的while循环)。

其他更改:

1)按照@Krash的建议使用布尔掩码,因为您可以检查循环外的每个值是否大于0.5,因为它是否不取决于i

2)selectors可以是2d

set.seed(123)

# Original dataset: assume it's 100 x 20 features
dataset <- array(rnorm(2000), dim = c(100, 20))
## Original (Option 0: while loop)

system.time({
  # Select features: 100 x 20 x 1 (one row per dataset)
  selectors = array(runif(2000), dim = c(100, 20, 1));

  # Initialize list
  list_datasets = vector("list", 100);

  # Fill in list
  i = 1;
  while(i < 100) {
    list_datasets[[i]] = dataset[, selectors[i,,1] > 0.5];
    i = i + 1 # This causes an off-by-one error, as list_datasets[[100]] is never filled in
  }
})
##   user  system elapsed 
##  0.006   0.000   0.006 

# Option 1: for loop
system.time({
  # Select: boolean mask: 100 x 20 (need one row to create each dataset)
  selectors = array(runif(2000), dim = c(100, 20));
  selectors = selectors < 0.5

  # Initialize list
  list_datasets = vector("list", 100);

  # Fill in list
  for (i in 1:100) {
    list_datasets[[i]] = dataset[ , selectors[i, ]] 
  }
})

##   user  system elapsed 
##  0.004   0.000   0.005

# Option 2: lapply
system.time({
  # Select: boolean mask: 100 x 20 (need one row to create each dataset)
  selectors = array(runif(2000), dim = c(100, 20));
  selectors = selectors < 0.5

  # Fill in list
  list_datasets <- lapply(1:100, FUN = function(x) dataset[ , selectors[x, ]])
})
##   user  system elapsed 
##  0.003   0.000   0.003

显然,每次运行语句所需的时间会有所不同,但希望其中一些建议的更改可以提高速度。

作为检查以确保代码符合我的期望:

# Check number of cols per dataset
list_datasets %>% 
  purrr::map_int(~ncol(.))

##  [1]  8  7  9 12 11 13 11 10 10 14 14  7  8 10 10  9 14 10  6 11 13  8  7  8 10 12  9 11  9  9 13
## [32] 12  8 14 11 11  8 10 11  8 10 13 12 10  6 10 10 12  9  9 10 11  7  8 11  9 11  9  7  9  9 11
## [63] 14  9  9  9  9 13 13 14 12  9 10  9 12  8 11 14  9  7 12  7  6 11 11  7  9  8 12 10 12  9 11
## [94] 13 12 16  9  8 11 10

其他想法:您可以在循环中添加这样的行(或selectors lapply,而不是通过随机制服创建FUN数组,而每一行都对应一个新数据集。 )。

include_feature <- sample(0:1, size = 20, replace = TRUE)
include_feature
## [1] 0 0 1 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 0 1