【问题标题】:Make caret's genetric feature selection faster使插入符号的遗传特征选择更快
【发布时间】:2019-06-12 19:49:17
【问题描述】:

我正在尝试通过使用带有插入符号的遗传算法的特征选择来优化 xgboost 树

results <- gafs(iris[,1:4], iris[,5],
               iters = 2,
               method = "xgbTree",
               metric = "Accuracy",
               gafsControl = gafsControl(functions=caretGA, method="cv", repeats=2, verbose = TRUE),
               trConrol = trainControl(method = "cv", classProbs = TRUE, verboseIter = TRUE)
               )

然而这非常慢,即使我只是使用iters = 2 而不是iters = 200 更合适。我可以做些什么来加快速度?

【问题讨论】:

  • 并行化,减少 popSize, repeats = 1, ...
  • @JuliusVainora:我应该使用什么popSize 以及如何并行化?
  • 不确定popSize 的建议是什么。 ?gafs 中“详细信息”部分的结尾是并行化。

标签: r genetic-algorithm r-caret


【解决方案1】:

这是一个使用doParallel 包并行化gafs() 函数并修改一些其他参数以使其更快的示例。在可能的情况下,我包括运行时间。

原代码是使用交叉验证(method = "cv")而不是重复交叉验证(method = "repeatedcv"),所以我相信repeats = 2参数被忽略了。我没有在并行示例中包含该选项。

首先,使用原始代码,不做任何修改或并行化:

> library(caret)
> data(iris)

> set.seed(1)
> st.01 <- system.time(results.01 <- gafs(iris[,1:4], iris[,5],
                                          iters  = 2, 
                                          method = "xgbTree", 
                                          metric = "Accuracy",
                                          gafsControl = gafsControl(functions = caretGA, 
                                                                    method  = "cv", 
                                                                    repeats = 2, 
                                                                    verbose = TRUE),
                                          trConrol = trainControl(method = "cv", 
                                                                  classProbs  = TRUE, 
                                                                  verboseIter = TRUE)))

Fold01 1 0.9596575 (1)
Fold01 2 0.9596575->0.9667641 (1->1, 100.0%) *
Fold02 1 0.9598146 (1)
Fold02 2 0.9598146->0.9641482 (1->1, 100.0%) *
Fold03 1 0.9502661 (1)

我在一夜之间(8 到 10 小时)运行了上面的代码,但因为完成时间太长而停止运行。运行时间的粗略估计至少为 24 小时。

第二,包括减少popSize参数(从50到20),allowParallelgenParallel选项到gafsControl(),最后减少number的折叠次数(从10到5 ) 在gafsControl()trControl() 中:

> library(doParallel)
> cl <- makePSOCKcluster(detectCores() - 1)
> registerDoParallel(cl)

> set.seed(1)
> st.09 <- system.time(results.09 <- gafs(iris[,1:4], iris[,5],
                                          iters   = 2, 
                                          popSize = 20, 
                                          method  = "xgbTree", 
                                          metric  = "Accuracy",
                                          gafsControl = gafsControl(functions = caretGA, 
                                                                    method    = "cv", 
                                                                    number    = 5, 
                                                                    verbose   = TRUE, 
                                                                    allowParallel = TRUE, 
                                                                    genParallel   = TRUE),
                                          trConrol = trainControl(method      = "cv", 
                                                                  number      = 5, 
                                                                  classProbs  = TRUE, 
                                                                  verboseIter = TRUE)))

 final GA
 1 0.9508099 (4)
 2 0.9508099->0.9561501 (4->1, 25.0%) *
 final model
> st.09
   user   system  elapsed
   3.536    0.173 4152.988

我的系统有 4 个内核,但按照说明它只使用了 3 个内核,并且我验证它正在运行 3 个 R 进程。

gafsControl() 文档描述了 allowParallelgenParallel,如下所示:

  • allowParallel:如果并行后端已加载且可用, 该函数应该使用它吗?

  • genParallel:如果并行后端已加载且可用,则应 'gafs' 使用它来并行化适应度计算 重采样中的一代?

插入符号文档表明allowParallel 选项将比genParallel 选项提供更大的运行时间改进: https://topepo.github.io/caret/feature-selection-using-genetic-algorithms.html

与原始代码相比,我预计并行化代码的结果至少会略有不同。以下是并行代码的结果:

> results.09

Genetic Algorithm Feature Selection

150 samples
4 predictors
3 classes: 'setosa', 'versicolor', 'virginica'

Maximum generations: 2
Population per generation: 20
Crossover probability: 0.8
Mutation probability: 0.1
Elitism: 0

Internal performance values: Accuracy, Kappa
Subset selection driven to maximize internal Accuracy

External performance values: Accuracy, Kappa
Best iteration chose by maximizing external Accuracy
External resampling method: Cross-Validated (5 fold)

During resampling:
  * the top 4 selected variables (out of a possible 4):
    Petal.Width (80%), Petal.Length (40%), Sepal.Length (20%), Sepal.Width (20%)
  * on average, 1.6 variables were selected (min = 1, max = 4)

In the final search using the entire training set:
   * 4 features selected at iteration 1 including:
     Sepal.Length, Sepal.Width, Petal.Length, Petal.Width
   * external performance at this iteration is

   Accuracy       Kappa
     0.9467      0.9200

【讨论】:

  • a) 训练时间太长了!虹膜数据集非常小。怎么会有人希望 xgboost 在任何合理的时间内完成一个真实的工业数据集......我不是分类专家(我主要研究无监督方法),所以我真的很惊讶 - 如果没有混淆......什么是在这里进行吗?
  • b) 运行第二个版本需要多长时间?
  • b) 第二个版本的总运行时间为 4,153 秒(请参阅上面的经过时间)并存储在 st.09 变量中。可以在 R 会话中使用 ?proc.time 找到 st.09 中三个数字的详细信息。
  • a) 我同意,培训时间太长了。虽然有两个级别的交叉验证。我敢打赌 gafs() 在 xgboost 方面并不慢,除非它被调用太多次。我的猜测是它在遗传算法方面很慢。 caret 包中的另一种特征选择方法是“用于特征选择的模拟退火”函数 safs(),但同样具有两个级别的交叉验证。一个稍微不同的选择是使用正则化方法进行特征选择,例如 glmnet,带有 train() 函数,该函数只有一个级别的交叉验证。
  • 我猜答案是“能做的只有这么多”;-)。我要除外。
猜你喜欢
  • 2019-11-11
  • 2016-04-26
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 2016-01-02
  • 1970-01-01
相关资源
最近更新 更多