【问题标题】:xgbTree fails with non-formula for caret trainingxgbTree 因插入符号训练的非公式而失败
【发布时间】:2017-08-13 05:59:10
【问题描述】:

我正在尝试使用 caret 包中的 train 函数来拟合 xgbTree 模型。

编辑:这是一个示例数据集,用于使示例可重现。我还按照建议将所有变量转换为数字:

df<-data.frame(
x1=c(-231,5,-166,-158,170,-243,-184,25,-130,-209,453,-46,-13,-247,-74,-209,-130,-118,10,40),
x2=c(2,48,6,7,24,2,5,7,12,48,48,24,2,8,4,1,8,5,50,6),
x3=c(6, 3, 2, 1, 2, 6, 0, 6, 2, 4, 5, 5, 2, 4, 1, 2, 3, NA, 0, 1),
x4=c(0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0),
x5=c(45.1, 58.6, 41.3, 58.6, 45.1, 60.8, 44.1, 58.6, 38.8, 40.5, 60.8, 45.1, 41.3, 45.1, 41.3, 45.1, 39, 41.3, 51.7, 51.7),
x6=c(0, 2, 4, 0, NA, 0, 1, 0, NA, 0, 3, 0, 0, 0, 0, 0, 0, NA, 0, 0),
x7=c(NA, 6, 6, NA, 6, NA, 3, NA, 6, NA, 6, NA, NA, NA, NA, NA, NA, 1, NA, NA),
x8=c(0, 1, 4, 0, 4, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0),
x9=c(0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
x10=c(NA, NA, NA, NA, 0, NA, 0, NA, NA, NA, 0, NA, NA, NA, NA, NA, NA, NA, NA, NA),
y=c(0.00272609554964902, 0.00196386488609584, 0.0169606512890095, 0, 0.00978263953223331, 0.00310850075796128, 0.0225595119926366, 0.00456053067993367, 0.00980320074504326, 0.0116718460483506, 0.0618914994405961, 0.0420972062763108, 0.00139303482587065, 0.0426927149151269, 0.0248756218905473, 0, 0, 0.000855672497463542, 0.0287026406429392, 0.00190374657325617))

当我使用公式界面时,一切正常:

编辑:添加了使用的库

library(caret)
library(doParallel)

registerDoParallel(cores=n) 

xgb_model <-train(y ~.,
                     data = df,
                     method = "xgbTree",
                     na.action = na.pass)

但是当我使用非公式接口时模型训练失败:

xgb_model <-train(x=df[,-ncol(df)],
                  y=df[,ncol(df)],
                     data = df,
                     method = "xgbTree",
                     na.action = na.pass)

我已经尝试省略所有 NA,以及仅使用特定变量来缩小问题范围,但我真的找不到与输入数据有关的任何问题。

实际的data.frame 如下所示:

'data.frame':   433 obs. of  30 variables:
 $ x1      : int  -231 5 -166 -158 170 -243 -184 25 -130 -209 ...
 $ x2      : int  2 48 6 7 24 2 5 7 12 48 ...
 $ x3      : Ord.factor w/ 7 levels "0"<"1"<"2"<"3"<..: 4 3 2 3 7 1 7 3 5 6 ...
 $ x4      : Ord.factor w/ 8 levels "0"<"1"<"2"<"3"<..: 1 2 2 1 2 1 2 1 2 2 ...
 $ x5      : num  45.1 58.6 41.3 58.6 45.1 60.8 44.1 58.6 38.8 40.5 ...
 $ x6      : int  0 2 4 0 NA 0 1 0 NA 0 ...
 $ x7      : Ord.factor w/ 6 levels "1"<"2"<"3"<"4"<..: NA 6 6 NA 6 NA 3 NA 6 NA ...
 $ x8      : Ord.factor w/ 5 levels "0"<"1"<"2"<"3"<..: 1 2 5 1 5 1 3 1 2 1 ...
 $ x9      : Ord.factor w/ 5 levels "0"<"2"<"4"<"6"<..: 1 1 5 1 1 1 1 1 1 1 ...
 $ x10     : int  NA NA NA NA 0 NA 0 NA NA NA ...
 $ x11     : Ord.factor w/ 10 levels "0"<"2"<"4"<"5"<..: 7 5 1 5 4 4 9 7 5 8 ...
 $ x12     : Ord.factor w/ 32 levels "0"<"1"<"2"<"3"<..: 10 2 1 13 1 10 6 6 1 1 ...
 $ x13     : Ord.factor w/ 13 levels "0"<"0.7"<"1.4"<..: 1 1 1 8 1 1 13 6 1 6 ...
 $ x14     : Factor w/ 4 levels "1","2","3","4": 2 1 1 4 1 2 4 1 4 4 ...
 $ x15     : int  1 2 3 1 2 1 1 9 2 2 ...
 $ x16     : int  180 200 160 250 120 160 300 600 180 150 ...
 $ x17     : Ord.factor w/ 6 levels "1"<"2"<"3"<"4"<..: 2 6 5 3 2 2 1 3 2 2 ...
 $ x18     : Ord.factor w/ 5 levels "1"<"2"<"3"<"4"<..: 4 1 2 3 5 3 4 4 5 5 ...
 $ x19     : num  366825 509200 353760 502500 306666 ...
 $ x20     : num  2 2 2 2 2.83 ...
 $ x21     : Factor w/ 2 levels "0","1": 1 2 1 1 1 1 2 1 1 1 ...
 $ x22     : int  50 70 32 48 20 56 57 51 53 55 ...
 $ x23     : int  5 2 5 5 2 3 3 2 4 1 ...
 $ x24     : int  0 0 3 0 0 0 0 0 0 0 ...
 $ x25     : int  0 2 0 0 0 0 0 0 0 0 ...
 $ x26     : Factor w/ 3 levels "1","2","3": 3 3 3 3 3 3 3 3 3 3 ...
 $ x27     : Ord.factor w/ 5 levels "12"<"13"<"14"<..: NA NA 3 3 1 5 1 5 5 5 ...
 $ x28     : Ord.factor w/ 9 levels "4"<"6"<"7"<"8"<..: 7 7 2 NA 4 6 8 NA 4 9 ...
 $ x29     : num  -0.3211 -0.0462 -0.8133 0.3825 -0.5475 ...
 $ y       : num  0.00273 0.00196 0.01696 0 0.00978 ...

【问题讨论】:

  • 您遇到的错误究竟是什么?请提供reproducible example。共享来自str() 的数据没有帮助,或许可以改用dput()。您是否定义了变量ydataset[,y] 真的会为您返回感兴趣的列吗?
  • 我添加了一个可重现的示例。我从 caret 得到的错误不是很有帮助,因此我没有在这里添加它。错误是:'train.default 中的错误(x = df[, -ncol(df)], y = df[, ncol(df)], : Stopping'

标签: r r-caret xgboost


【解决方案1】:

表单?train帮助参考train(x, y, ...)接口:

只要底层模型拟合函数可以处理对象类,x 中的预测变量几乎可以是任何对象。

底层的xgb.DMatrix 函数(您可以从getModelInfo('xgbTree') 看到插入符号的xgboost 包装器中的所有函数)需要一个数字矩阵作为输入,因此您会收到错误消息。公式train 接口有效,因为它在后台使用model.matrix 将您的公式转换为数字矩阵,包括因子变量的编码。要使用 (x,y) 接口,您首先必须将 data.frame 转换为矩阵。 model.matrixcaret::dummyVars 是解决此问题的常用选项。

注意:您的数据中有许多序数因子变量。由于树可以轻松处理序数区间的任何不均匀性,因此对于基于树的非参数算法,最好将每个序数因子简单地转换为单列数值,而不是从中创建多个虚拟变量。

【讨论】:

  • 我尝试将我的 data.set 转换为数值,并使用'as.matrix(sapply(df, as.numeric))' 将数据转换为矩阵,但我得到了同样的错误。
【解决方案2】:

data=na.action= 参数只能与train() 的公式版本一起使用。这意味着您应该使用

xgb_model <- train(y ~.,
                 data = df,
                 method = "xgbTree",
                 na.action = na.pass)

xgb_model <- train(x=df[,-ncol(df)],
                  y=df[,ncol(df)],
                  method = "xgbTree")

【讨论】:

    【解决方案3】:

    我发现问题不是由train() 命令中的任何错误引起的,而是由尝试使用doParallel 包中的registerDoParallel(cores=n) 并行化模型引起的。 doParallel 与我迄今为止在 caret 中测试过的所有其他模型(即 treebagcforestgbm)都可以正常工作。

    因此,鉴于您不使用doParallel,以下代码可以正常工作:

    xgb_model <- train(x=df[,-ncol(df)],
                      y=df[,ncol(df)],
                      method = "xgbTree")
    

    【讨论】:

      猜你喜欢
      • 2014-04-07
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2018-06-24
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多