如何在 caret 包的 randomForest 输出上使用 forestFloor()?

How to use forestFloor() on randomForest output from caret package?

我一直在使用 forestFloor 包来可视化随机森林模型结构。一切都很顺利,直到我尝试在 caret 包的随机森林输出上使用 forestFloor()。我需要为我的数据集使用 caret 而不是 randomForest,因为我的 classes 严重不平衡,所以使用 SMOTE 采样策略。我修复了一些问题,将 keep.inbag=TRUEkeep.forest=TRUE 传递给 caret::train,然后找到隐藏在 train class 对象中的 randomForest 对象, $finalModel.

我仍然得到错误: Error in eval(substitute(expr), envir, enclos) : index out of bounds

请参阅以下最小工作示例,取自 mlbench 中的 Pima Indians 糖尿病数据集。提前致谢!

> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.5 LTS

other attached packages:
[1] DMwR_0.4.1          caret_6.0-70        ggplot2_2.1.0      
[4] lattice_0.20-34     forestFloor_1.9.5   randomForest_4.6-12
[7] mlbench_2.1-1

library(mlbench)
library(randomForest)
library(forestFloor)

data(PimaIndiansDiabetes)
y = PimaIndiansDiabetes$diabetes
X = PimaIndiansDiabetes
X = X[,!names(X)=="diabetes"]
rf.randomForest  = randomForest(X,y,sampsize=25,ntree=5000,mtry=4,
 keep.inbag = T,keep.forest = T)

## Use forestFloor on randomForest output, works great
ff = forestFloor(rf.randomForest,X,binary_reg = T,calc_np=T)
Col = fcol(ff,cols=1,outlier.lim = 2.5)
plot(ff,col=Col,plot_GOF = T)

## Now fit random forest using SMOTE from caret package
ctrl <- trainControl(method = "cv", number=5,
                     classProbs = TRUE,
                     summaryFunction = twoClassSummary,
                     sampling = "smote")
rf.SMOTE <- train(x=X,y=y,
                      method = "rf",
                      tuneGrid = data.frame(mtry = 3),
                      metric = "ROC",
                      trControl = ctrl,
                      keep.inbag=TRUE,
                      keep.forest=TRUE)
rf.caret <- rf.SMOTE$finalModel

## Use forestFloor on caret output, throws error
ff = forestFloor(rf.caret,X,binary_reg = T,calc_np=T)

在 Soren 的帮助下解决了这个问题:https://github.com/sorhawell/forestFloor/issues/22

解释 Soren:问题是 caret 的 SMOTE 版本对训练数据重新采样并将其保存在其他地方(?)。要估计特征贡献,您需要将用于训练的相同数据集 (X) 传递给 forestFloorforestFloor 的特征贡献计算依赖袋外采样和袋内矩阵来匹配提供的训练集。

修复:可以在 DMwR 包中使用 SMOTE 功能,而不是在 caret 包中使用 SMOTE。 DMwR::SMOTE returns 然后可以放入 randomForestforestFloor.

的重新采样训练数据
library(randomForest)
library(DMwR)
library(forestFloor)
# covar = names of covariate/feature column names (character vector)
# target = response column names (character)
X <- cbind(dat[,covar], factor(dat[,target]))
names(X) <- c(covar, target)
bin.formula <- formula(paste0(target," ~ ",paste0(covar,collapse=" + ")))
X.SMOTE <- SMOTE(bin.formula, data=X, k=5)
rf.SMOTE <- randomForest(x=X.SMOTE[,covar], y=X.SMOTE[,target], keep.inbag=T, ...)
ff.bin = forestFloor(rf.fit = rf.SMOTE, X = X.SMOTE[,covar])