XGBoost(R)CV测试与培训错误

时间:2017-06-16 12:19:01

标签: r xgboost

我将在我的问题前面说,由于围绕它的极其严格的保密协议,我目前无法分享我的数据。希望我很快就能获得分享盲法数据的许可。

我很难在R中正确地训练XGBoost。我一直在遵循指南here并且到目前为止仍然停留在第1步,调整nrounds参数。我从交叉验证中得到的结果并不是我希望他们做的事情让我不知所措。

我的数据包含105个obervations,一个连续响应变量(下面链接中图像左上方窗格中的直方图)和16095个预测变量。所有预测变量都在相同的比例上,它们的直方图都位于下面链接中图像的右上方。预测变量非常重,所有值的62.82%为0。

作为一组单独的测试数据,我还有48个观察结果。两个数据集的响应变量范围都非常相似。

enter image description here

到目前为止,我已经能够适应PLS模型和随机森林(使用R库游侠)。将这两个模型应用于我的测试数据集,我已经能够预测并从PLS获得19.133的RMSE,并从测距仪获得15.312的RMSE。在游侠的情况下,使用2000棵树和每个分裂的760个变量证明非常稳定。

回到XGBoost,使用下面的代码,我一直在修复除了nrounds之外的所有参数,并使用R包xgboost中的xgb.cv函数来计算训练和测试错误。

data.train<-read.csv("../Data/Data_Train.csv")
data.test<-read.csv("../Data/Data_Test.csv")

dtrain <- xgb.DMatrix(data = as.matrix(data.train[,-c(1)]), 
label=data.train[,1])
# dtest <- xgb.DMatrix(data = as.matrix(data.test[,-c(1)]), label=data.test[,1]) # Not used here

## Step 1 - tune number of trees using CV function

  eta = 0.1; gamma = 0; max_depth = 15;
  min_child_weight = 1; subsample = 0.8; colsample_bytree = 0.8
  nround=2000
  cv <- xgb.cv(
    params = list(
      ## General Parameters
      booster = "gbtree", # Default
      silent = 0, # Default

      ## Tree Booster Parameters
      eta = eta,
      gamma = gamma,
      max_depth = max_depth,
      min_child_weight = min_child_weight,
      subsample = subsample,
      colsample_bytree = colsample_bytree,
      num_parallel_tree = 1, # Default

      ## Linear Booster Parameters
      lambda = 1, # Default
      lambda_bias = 0, # Default
      alpha = 0, # Default

      ## Task Parameters
      objective = "reg:linear", # Default
      base_score = 0.5, # Default
      # eval_metric = , # Evaluation metric, set based on objective
      nthread = 60
    ),
    data = dtrain,
    nround = nround,
    nfold = 5,
    stratified = TRUE,
    prediction = TRUE,
    showsd = TRUE,
    # early_stopping_rounds = 20,
    # maximize = FALSE,
    verbose = 1
  )

library(ggplot)
plot.df<-data.frame(NRound=as.matrix(cv$evaluation_log)[,1], Train=as.matrix(cv$evaluation_log)[,2], Test=as.matrix(cv$evaluation_log)[,4])
library(reshape2)
plot.df<-melt(plot.df, measure.vars=2:3)
ggplot(data=plot.df, aes(x=NRound, y=value, colour=variable)) + geom_line() + ylab("Mean RMSE")

如果此功能完成了我认为的功能,那么我希望看到训练误差降低到稳定状态,然后测试误差减小,然后随着模型的过度再次开始增加。但是我得到的输出看起来像下面的代码(以及上面链接中的下图)。

##### xgb.cv 5-folds
    iter train_rmse_mean train_rmse_std test_rmse_mean test_rmse_std
       1      94.4494006   1.158343e+00       94.55660      4.811360
       2      85.5397674   1.066793e+00       85.87072      4.993996
       3      77.6640230   1.123486e+00       78.21395      4.966525
       4      70.3846390   1.118935e+00       71.18708      4.759893
       5      63.7045868   9.555162e-01       64.75839      4.668103
---                                                                 
    1996       0.0002458   8.158431e-06       18.63128      2.014352
    1997       0.0002458   8.158431e-06       18.63128      2.014352
    1998       0.0002458   8.158431e-06       18.63128      2.014352
    1999       0.0002458   8.158431e-06       18.63128      2.014352
    2000       0.0002458   8.158431e-06       18.63128      2.014352

考虑到游侠的工作情况,我倾向于相信我做了一些愚蠢的事情并导致XGBoost挣扎!

由于

1 个答案:

答案 0 :(得分:0)

要调整参数,您可以使用tuneParams。这是一个例子

 task = makeClassifTask(id = id, data = "your data", target = "the name of the column in your data of the y variable")

  # Define the search space
  tuning_options <- makeParamSet(                                     
    makeNumericParam("eta",              lower = 0.1,         upper = 0.4), 
    makeNumericParam("colsample_bytree", lower = 0.5,         upper = 1), 
    makeNumericParam("subsample",        lower = 0.5,         upper = 1),  
    makeNumericParam("min_child_weight", lower = 3,           upper = 10),    
    makeNumericParam("gamma",            lower = 0,           upper = 10), 
    makeNumericParam("lambda",           lower = 0,           upper = 5), 
    makeNumericParam("alpha",            lower = 0,           upper = 5),
    makeIntegerParam("max_depth",        lower = 1,           upper = 10),
    makeIntegerParam("nrounds",          lower = 50,          upper = 300))

 ctrl = makeTuneControlRandom(maxit = 50L)
  rdesc = makeResampleDesc("CV", iters = 3L)
  learner = makeLearner("classif.xgboost", predict.type = "response",par.vals = best_param)

 res = tuneParams(learner = learner,task = task, resampling = rdesc,
                   par.set = tuning_options, control = ctrl,measures = acc)

当然,您可以使用参数的间隔。最后res将包含xgboost的最佳参数集,然后您可以使用此参数训练xgboost。请注意,除了交叉验证之外,您可以选择其他方法,请尝试?makeResampleDesc

我希望它有所帮助