r-我如何制作一个函数,对线性模型进行K折叠交叉验证



我正试图开发一个函数,对任何线性回归模型进行k次交叉验证。我能够开发以下的代码

K.CV.2<-function(numberOfFolds, inputData){
index <- sample(1:numberOfFolds, nrow(inputData), replace = T)
inputData$index <- index
mse.all <- c()
for (n in 1:numberOfFolds) {
training.data <- inputData[inputData$index!=n,]
testing.data <- inputData[inputData$index==n,]
model.hold <- lm(earn~height+sex+race+ed, data = training.data)
predictions <- predict(model.hold, newdata=testing.data)
mse.hold <- mean((testing.data$earn-predictions)^2)
mse.all <- c(mse.all,mse.hold)
}
return(mse.all)
}
K.CV.2(numberOfFolds, Inputdata)

我对这个函数不满意,因为我正在努力使它更通用。我想要function(numberOfFolds, y, x, InputData)

我希望能够使用c()函数传递y变量的列以及我将在x中用作解释变量的所有其他列。

有人能帮助/指引我朝正确的方向走吗?

我想是这样的。一些注意事项:

  • 提供示例数据更容易提供帮助。我已经为这个案子生成了一些伪造的数据,但以后要记住。一般来说,我强烈建议您练习模拟数据来测试您的模型和假设
  • 不要使用T。它不是保留值。你可以在你的脚本中写T <- FALSE,得到可以预见的搞笑结果
  • 简单地传入要使用的xy会更容易。这就是我在这里所做的。然后,您可以循环通过一个数据帧,并传入子集x和您想要的任何y,但它使CV函数更干净
  • 除非绝对必要,否则不要生长对象。参见R地狱之书
  • 最好在代码中避免使用1:n。如果n为零,它会创建向量c(1, 0),这通常会导致意外的结果
npred <- 10
nobs <- 100
mat <- matrix(rnorm(npred * nobs), ncol = npred, nrow = nobs)
beta <- rnorm(npred, sd = 2)
y <- (mat %*% beta + rnorm(100, sd=0.2))[, 1]
x <- as.data.frame(mat)
cv_lm <- function(x, y, nfolds) {
## don't use T; it's dangerous.
index <- sample(seq_len(nfolds), nrow(x), replace = TRUE)
stopifnot(nrow(x) == length(y)) ## check to make sure the input is valid
## declare output as a vector of length nfolds
mse <- numeric(nfolds)
## use seq_len(nfolds) instead of 1:nfolds
for (n in seq_len(nfolds)) {
## create x and y training/test split
x_training <- x[index != n, ]
x_testing <- x[index == n, ]
y_training <- y[index != n]
y_testing <- y[index == n]
## fit model (y ~ . means "y against everything")
fit <- lm(y_training ~ ., data = x_training)
predictions <- predict(fit, newdata = x_testing)
## don't grow vectors
mse[[n]] <- mean((y_testing-predictions)^2)
}
return(mse)
}
## predict y with x (true predictors)
cv_lm(x = x, y = y, nfolds = 10)
#>  [1] 0.07503477 0.02913210 0.03467926 0.03762000 0.03291574 0.05687162
#>  [7] 0.01023195 0.06304727 0.02435436 0.06634923
## predict first predictor in x with the other 9 (no true relationship, hence larger MSE)
cv_lm(x = x[, 2:10], y = x[, 1], nfolds = 10)
#>  [1] 0.7447689 1.4850093 1.0964575 2.5117445 1.1037217 1.0684408 1.7798122
#>  [8] 0.9962255 1.0208430 1.3867716

最新更新