我有一个相对较大的数据集,关于美国几个市场的房屋销售。对于每个市场,我想建立一个梯度提升回归模型来预测销售价格。我的大多数自变量(特性)都有缺失值,这对于R中的gbm来说应该没问题。
caret中的gbm算法要求您指定超参数(n.trees、shrinkage、interaction.depth、n.minobsinnode等)的值。我想结合交叉验证进行网格搜索,以选择最佳的超参数集:
# -------- A function to drop variables that are more than 80% missing or have no variance
Drop_Useless_Vars <- function(datan) {
n = nrow(datan)
p = ncol(datan)
na = is.na(datan)
n_na = apply(X = na, MARGIN = 2, FUN = sum)
n_unique = apply(X = datan, MARGIN = 2, function(x) length(na.omit((unique(x)))))
return(as.data.frame(datan[, -which(n_na > 0.8*n | n_unique < 2)]))
}
# -------- load libraries
library(gbm)
library(caret)
# -------- prepare training scheme
control = trainControl(method = "cv", number = 5)
# -------- design the parameter tuning grid
grid = expand.grid(n.trees = 10000,
interaction.depth = seq(2, 10, 1),
n.minobsinnode = c(3, 4, 5),
shrinkage = c(0.1, 0.01, 0.001))
# -------- tune the parameters
tuner = train(log(saleprice) ~ ., data = Drop_Useless_Vars(df), method = "gbm", distribution = "gaussian",
trControl = control, verbose = FALSE, tuneGrid = grid, metric = "RMSE")
# -------- get the best combo
n_trees = tuner$bestTune$n.trees
interaction_depth = tuner$bestTune$interaction.depth
shrinkage = tuner$bestTune$shrinkage
n_minobsinnode = tuner$bestTune$n.minobsinnode上面的代码运行得很好,除了在某些市场中,缺少值的情况比较频繁。我得到如下所示的错误:
Error in checkForRemoteErrors(val) :
4 nodes produced errors; first error: variable 26: assessor_full_baths has only missing values.assessor_full_baths是我的模型中的一个特性。所以发生的情况是,当算法采样数据进行交叉验证时,一个或多个折叠的变量完全缺失。
如何对caret使用的抽样方案进行分层?也就是说,我如何才能强制每个折叠层具有关于缺失值的相同分布?另外,你们知道如何让gbm函数忽略完全缺失的变量,而不让我们告诉它它们是哪些变量吗?
如果您能提供任何帮助,我将不胜感激。
发布于 2016-09-29 09:01:22
我认为您需要后退一步,考虑如何正确处理数据和拟合模型。
最终的建模数据集不应该有任何缺失值,更不用说在CV折叠(!)中100%缺少特征的这么多缺失值了。
相反,做一些数据清理和功能工程:
如果你不想估算丢失的数据,那么你应该使用上面提到的其他策略。缺失的节点与编码的安娜级别不同。缺少节点只是意味着树将给出与拆分之前相同的预测,其中缺少数据(请参阅R gbm handling of missing values)。您不应该在具有高缺失率的特征上构建模型,并且在具有任何缺失值的数据上构建模型根本不是一个好的实践。在准备数据集时,应该清理这些数据集。
话虽如此,您仍然可以推断出MNAR数据。有大量的策略,可以追溯到赫克曼和鲁宾在70年代的工作。很多人使用mice()和绘制指示器方法。
这可能会有所帮助:http://stefvanbuuren.nl/mi/docs/mnar.pdf
发布于 2016-09-30 04:48:57
您可以使用caret::createFolds自己创建CV折叠。您只需提供一个与结果不同的y变量(即- saleprice)。你需要根据你的分层变量来定义一个新的变量...参见?interaction。然后可以将其传递给caret::trainControl
例如:
library(caret)
y2 <- interaction(df$x1, df$x2)
cv_folds <- createFolds(y2, k= 5)
control = trainControl(index= cv_folds, method= "cv", number= 5)
...或者,您可以避免使用caret,而编写自己的stratified sampling code
也就是说,我同意@Hack-R所说的关于缺少值和推算的特性的实际使用的大部分内容。
https://stackoverflow.com/questions/39758649
复制相似问题