跳到内容

通过根据先前学习模型中的决策树向训练数据添加新特征,可以提高学习效果。

用法

xgb.create.features(model, data)

参数

model

在原始数据上学习的决策树增强模型。

数据

原始数据(通常以 dgCMatrix 矩阵形式提供)。

一个 dgCMatrix 矩阵,包括原始数据和新特征。

详细信息

此函数受论文第 3.1 段启发:

在 Facebook 预测广告点击量的实践经验

(Xinran He, Junfeng Pan, Ou Jin, Tianbing Xu, Bo Liu, Tao Xu, Yan, xin Shi, Antoine Atallah, Ralf Herbrich, Stuart Bowers, Joaquin Quinonero Candela)

在线广告数据挖掘国际研讨会 (ADKDD) - 2014 年 8 月 24 日

https://research.facebook.com/publications/practical-lessons-from-predicting-clicks-on-ads-at-facebook/.

解释方法的摘录:

“我们发现,增强决策树是一种强大且非常方便的方法,可以实现我们刚刚描述的非线性和元组变换。我们将每个单独的树视为一个分类特征,其值是实例最终落入的叶子的索引。我们使用 1-of-K 编码来表示此类特征。

例如,考虑图 1 中带有 2 个子树的增强树模型,其中第一个子树有 3 个叶子,第二个子树有 2 个叶子。如果一个实例最终落在第一个子树的叶子 2 和第二个子树的叶子 1 中,则线性分类器的总体输入将是二进制向量 [0, 1, 0, 1, 0],其中前 3 个条目对应于第一个子树的叶子,最后 2 个对应于第二个子树的叶子。

...

我们可以将基于增强决策树的变换理解为一种监督式特征编码,它将实值向量转换为紧凑的二进制值向量。从根节点到叶节点的遍历代表了关于某些特征的规则。”

示例

data(agaricus.train, package = "xgboost")
data(agaricus.test, package = "xgboost")

dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))

param <- list(max_depth = 2, learning_rate = 1, objective = 'binary:logistic', nthread = 1)
nrounds = 4

bst <- xgb.train(params = param, data = dtrain, nrounds = nrounds)

# Model accuracy without new features
accuracy.before <- sum((predict(bst, agaricus.test$data) >= 0.5) == agaricus.test$label) /
                   length(agaricus.test$label)

# Convert previous features to one hot encoding
new.features.train <- xgb.create.features(model = bst, agaricus.train$data)
new.features.test <- xgb.create.features(model = bst, agaricus.test$data)

# learning with new features
new.dtrain <- xgb.DMatrix(
  data = new.features.train, label = agaricus.train$label, nthread = 1
)
new.dtest <- xgb.DMatrix(
  data = new.features.test, label = agaricus.test$label, nthread = 1
)
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds)

# Model accuracy with new features
accuracy.after <- sum((predict(bst, new.dtest) >= 0.5) == agaricus.test$label) /
                  length(agaricus.test$label)

# Here the accuracy was already good and is now perfect.
cat(paste("The accuracy was", accuracy.before, "before adding leaf features and it is now",
          accuracy.after, "!\n"))