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”指定)。
因此,至少对于某些类型的数据集,这种细微的差异似乎非常重要。确实很有趣。