基于Caret训练模型的R语言0.632+ Bootstrap预测区间实现问题
基于Caret模型的0.632+ Bootstrap预测区间实现问题
我正在编写一个R函数,目标是基于Caret训练得到的train对象,使用0.632+ Bootstrap方法计算中心预测值及上下预测区间。参考了Python示例进行复现,但在R中实现时遇到了困难——当前函数输出的预测区间结果完全不正确。
根据Mark Rieke的评论,我知道其中一个问题是:每个Bootstrap拆分都需要执行完整的0.632+流程,但我的代码并没有做到这一点。
当前实现代码
library(caret) # Set the random seed for reproducibility set.seed(123) # Generate data n <- 100 explainer <- runif(n) y <- 1 + 0.2 * explainer + rnorm(n) data <- data.frame(explainer, y) # Fit linear regression models fit_simple <- lm(y ~ explainer) # A plain old linear model fit_caret <- train( y = y, x = data.frame(explainer), method = "lm" ) # An identical model, but fit using caret new_data <- data.frame(explainer = runif(15, min = -10, max = 10)) # Function to calculate prediction intervals using 0.632+ Bootstrap calculate_prediction_intervals <- function(model, new_data, alpha = 0.05) { # Extract training data and outcomes from the model X_train <- base::subset(model$trainingData, select = -c(.outcome)) y_train <- as.numeric(model$trainingData$.outcome) n <- nrow(X_train) nbootstraps <- as.integer(sqrt(n)) # Initialize matrices to store bootstrap predictions and validation residuals bootstrap_preds <- matrix(0, nrow(new_data), nbootstraps) val_residuals <- matrix(0, n, nbootstraps) for (b in 1:nbootstraps) { train_idxs <- sample(1:n, n, replace = TRUE) val_idxs <- setdiff(1:n, train_idxs) # Fit a bootstrap sample of the model fit_b <- train( y = y_train[train_idxs], x = X_train[train_idxs, , drop = FALSE], method = model$method, tuneGrid = model$bestTune, trControl = trainControl(method = "none", savePredictions = FALSE) ) # Compute validation set predictions and residuals preds_val <- predict(fit_b, newdata = X_train[val_idxs, , drop = FALSE]) val_residuals[val_idxs, b] <- y_train[val_idxs] - preds_val # Compute bootstrap predictions on new data preds_new <- predict(fit_b, newdata = new_data) bootstrap_preds[, b] <- preds_new } # Center the bootstrap predictions and residuals bootstrap_preds <- bootstrap_preds - colMeans(bootstrap_preds) val_residuals <- val_residuals - colMeans(val_residuals) # Fit the original model to the full training data fit <- train( y = y_train, x = X_train, method = model$method, tuneGrid = model$bestTune, trControl = trainControl(method = "none", savePredictions = FALSE) ) preds <- predict(fit, newdata = X_train) train_residuals <- y_train - preds # Calculate various values needed for 0.632+ Bootstrap no_information_error <- mean(abs(sample(y_train) - sample(preds))) generalization <- abs(colMeans(val_residuals) - mean(train_residuals)) no_information_val <- abs(no_information_error - train_residuals) relative_overfitting_rate <- mean(generalization / no_information_val) weight <- 0.632 / (1 - 0.368 * relative_overfitting_rate) # Calculate prediction residuals residuals <- (1 - weight) * train_residuals + weight * colMeans(val_residuals) # Calculate prediction percentiles percentiles <- apply(bootstrap_preds, 1, function(x) { quantile(x + residuals, probs = c(alpha / 2, 1 - alpha / 2)) }) # Create a data frame with predictions, lower, and upper limits result <- data.frame( fit = predict(fit, newdata = new_data), lwr = percentiles[1, ], upr = percentiles[2, ] ) return(result) }
我的需求
- 找出当前代码中的错误,修复后能正确生成符合预期的预测区间(即使增加Bootstrap重采样次数也无法解决当前问题)
- 必须实现特定的0.632+ Bootstrap方法,复现指定论文的思路(类似tidymodels及workboots包的实现逻辑)
- 函数需要支持通过Caret的
x和y参数训练的多变量复杂模型,不能只适用于线性模型 - 已知存在conformal inference、直接添加原始残差等替代方案,但我坚持要实现0.632+ Bootstrap方法
内容的提问来源于stack exchange,提问作者m.s.bolton
相关产品推荐
相关产品推荐

