2017-06-16 231 views
2

我将以我目前无法分享数据的前言来说明我的问题,因为它周围有非常严格的保密协议。希望我可以很快获得许可共享不知情的数据。XGBoost(R)CV测试与训练错误

我很努力让XGBoost在R中得到适当的训练。我一直在遵循指南here,到目前为止,我一直在步骤1中调整nrounds参数。我从我的交叉验证中得到的结果并没有做我期望他们做的事情,使我无法继续前进。

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

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

enter image description here

到目前为止,我已经能够适应PLS模型和随机森林(使用R库游侠)。将这两个模型应用到我的测试数据集中,我已经能够预测并从PLS得到19.133的RMSE,并且从ranger得到15.312。在游侠的情况下,使用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") 

如果这个函数做什么,我相信这是我不希望看到训练误差减小到高原和测试误差减小然后开始为模型overfits再次增加。然而,我得到的输出看起来像下面的代码(也是上面链接中的较低数字)。

##### 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奋斗!

感谢

回答

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

我希望它能帮助

+0

有用的,谢谢。我曾计划使用高斯过程(库rBayesianOptimization)进行参数优化,但我不确定是否继续。事实上,我的测试/训练错误似乎并没有显示出在一定数量的轮次后过度适应的通常模式,这让我认为更严重的事情是错误的。 –