【发布时间】:2016-04-24 18:50:22
【问题描述】:
xgboost 包允许构建随机森林(实际上,它选择列的随机子集来为整个树的拆分选择一个变量,而不是一个点头,因为它在算法的经典版本中,但可以容忍)。但似乎只使用了森林中的一棵树(也许是最后一棵树)进行回归。
为确保这一点,请仅考虑一个标准玩具示例。
library(xgboost)
library(randomForest)
data(agaricus.train, package = 'xgboost')
dtrain = xgb.DMatrix(agaricus.train$data,
label = agaricus.train$label)
bst = xgb.train(data = dtrain,
nround = 1,
subsample = 0.8,
colsample_bytree = 0.5,
num_parallel_tree = 100,
verbose = 2,
max_depth = 12)
answer1 = predict(bst, dtrain);
(answer1 - agaricus.train$label) %*% (answer1 - agaricus.train$label)
forest = randomForest(x = as.matrix(agaricus.train$data), y = agaricus.train$label, ntree = 50)
answer2 = predict(forest, as.matrix(agaricus.train$data))
(answer2 - agaricus.train$label) %*% (answer2 - agaricus.train$label)
是的,当然,xgboost 随机森林的默认版本不使用 Gini 评分函数,而只是使用 MSE;它可以很容易地改变。做这样的验证等等也是不正确的。它不会影响主要问题。无论尝试使用哪组参数,与 randomForest 实现相比,结果都非常糟糕。这也适用于其他数据集。
有人可以就这种奇怪的行为提供提示吗?当涉及到分类任务时,该算法确实按预期工作。
#嗯,所有的树都长出来了,都用来做预测。您可以使用“predict”函数的参数“ntreelimit”来检查。
主要问题仍然存在:由 xgbbost 包生成的随机森林算法的具体形式是否有效?
交叉验证、参数调整和其他废话与此无关——每个人都可以对代码添加必要的更正,看看会发生什么。
您可以像这样指定“目标”选项:
mse = function(predict, dtrain)
{
real = getinfo(dtrain, 'label')
return(list(grad = 2 * (predict - real),
hess = rep(2, length(real))))
}
这使您在为拆分选择变量时使用 MSE。即使在那之后,与 randomForest 的结果相比,结果也差得惊人。
也许,问题是学术性质的,涉及如何选择随机特征子集进行拆分。经典实现为每个拆分单独选择特征子集(大小由 randomForest 包的“mtry”指定),xgboost 实现为树选择一个子集(用“colsample_bytree”指定)。
因此,至少对于某些类型的数据集而言,这种细微差别似乎非常重要。确实很有趣。
【问题讨论】:
-
你的问题是什么?
-
正如我已经说过的,我想知道为什么会得到这样的结果。包裹里有错误吗?还是我只是对如何使用包的功能有错误?
标签: r random-forest xgboost