我正在嘗試建立測驗和培訓組來進行交叉驗證。我總共有 95 個個人 ID,并試影像這樣完成任務:
# create 95 unique IDs as individuals
set.seed(1)
indv <- stringi::stri_rand_strings(95, 4)
# specify Kfold
n.folds <- 5
folds <- cut(1:length(indv), breaks = n.folds, labels = FALSE)
# randomise the folds
folds <- sample(folds, length(folds))
samples.train <- list()
samples.test <- list()
foldSet <- list()
kfold.df <- data.frame("IID" = indv)
for (f in 1:n.folds) {
samples.train[[f]] <- indv[folds != f]
samples.test[[f]] <- indv[folds == f]
# replace to x (test) if the corresponding value is TRUE, and to y (train) if it is FALSE.
foldSet[[f]] <- ifelse(kfold.df$IID %in%
samples.test[[f]], "test", "train")
# combine foldSet to datafarme.
kfold.df[[f]] <- cbind(kfold.df, foldSet[[f]])
}
目標是準備 5 組測驗和訓練樣本來進行建模。但我遇到了這個錯誤資訊:
Error in data.frame(..., check.names = FALSE) :
arguments imply differing number of rows: 95, 2
此外,foldSet輸出并不像預期的那樣,雖然samples.train并且samples.test是正確的。你能幫我使這個回圈作業嗎?
更新:這是在創建時不使用通配符的 for 回圈foldSet:
for (f in 1:n.folds) {
samples.train[[f]] <- indv[folds != f]
samples.test[[f]] <- indv[folds == f]
foldSet <<- ifelse(kfold.df$IID %in% samples.test[[f]], "test", "train")
# combine foldSet to datafarme.
kfold.df <<- cbind(kfold.df, foldSet)
}
通過執行回圈,您會發現kfold.df一個資料框列出了所有五折測驗/訓練隨機集。我希望每次迭代都創建與 對應的測驗和訓練集f,因此,在五次迭代之后,我將可以訪問每個折疊的訓練/測驗集以進行回圈內的下一個操作,例如kfold.df[foldSet == "train", "IID"]. 我需要這個訪問 bcoz 我想用它來根據invd每個折疊的訓練和測驗對另一個更大的矩陣進行子集化,準備將其應用于回歸模型。這就是為什么我使用通配符foldSet來使回圈能夠自行創建但我未能管理它。
uj5u.com熱心網友回復:
我認為您可能使事情過于復雜(這是我一直在做的事情......)
你不需要竭盡全力去做你想做的事。這個答案分為三個部分。
- 構建您正在尋找的資料框(我認為!)
- 為什么你真的不需要構建這個資料框
- 為什么不使用已經存在的東西?
第1部分
如果我理解正確,這就是您要查找的內容(減去字串)。我還包括了如何將它與實際資料一起使用。
library(tidyverse)
giveMe <- function(rowCt, nfolds){
# set.seed(235) # removed seed after establishing working function to incite
# the expected randomness
folds <- cut(1:rowCt, breaks = nfolds, labels = F)
# randomise the folds
folds <- sample(folds, length(folds))
# create the folds' sets
kfold.df <- map_dfc(1:nfolds,
~ifelse(folds != .x, T, F)) %>%
setNames(., paste0("foldSet_",1:nfolds)) %>% # name each field
add_column(IID = 1:rowCt, .before = 1) # add indices to the left
return(kfold.df) # return a data frame
}
given <- giveMe(95, 5)
giveMore <- giveMe(nrow(iris), 5) # uses the built-in iris data set
第2部分
您可以創建隨機折疊序列并將其與模型一起使用,您無需將它們堆疊在資料框中。你必須回圈遍歷模型相同的次數,為什么不同時做呢?
folds <- sample(cut(1:nrow(iris), 5, # no seed-- random on purpose
labels = F))
tellMe <- map(1:5, # the folds start in col 2
~lm(Sepal.Length~.,
iris[ifelse(folds != .x,
T, F),
1:4])) # dropped 'Species' groups' issue
要檢查模型性能:
map_dfr(1:5, .f = function(x){
y = tellMe[[x]]
sigma = sigma(y)
rsq = summary(y)$adj.r.squared
c(sigma = sigma, rsq = rsq)
})
# # A tibble: 5 × 2
# sigma rsq
# <dbl> <dbl>
# 1 0.334 0.844
# 2 0.309 0.869
# 3 0.302 0.846
# 4 0.330 0.847
# 5 0.295 0.872
預測和檢查測驗性能
# create a list of the predictec values from the test data
showMe <- map(1:5,
~predict(tellMe[[.x]],
iris[ifelse(folds == .x,
T, F), 1:4]))
# Grab comparable metrics like those from the models
map_dfr(1:5,
.f = function(x){
A = iris[ifelse(folds == x, T, F), ]$Sepal.Length
P = showMe[[x]]
sigma = sqrt(sum((A - P)^2) / length(A))
rsq = cor(A, P)^2
c(sigma = sigma, rsq = rsq)
})
# # A tibble: 5 × 2
# sigma rsq
# <dbl> <dbl>
# 1 0.232 0.919
# 2 0.342 0.774
# 3 0.366 0.884
# 4 0.250 0.906
# 5 0.384 0.790
第 3 部分
在這里,我將使用caret圖書館。但是,還有很多其他選擇。
library(caret)
set.seed(1)
# split training and testing 70/30%
tr <- createDataPartition(iris$Species, p = .7, list = F)
# set up 5-fold val
trC <- trainControl(method = "cv", number = 5)
# train the model
fit <- train(Sepal.Length~., iris[tr, ],
method = "lm",
trControl = trC)
summary(fit)
# truncated results best model:
# Residual standard error: 0.2754 on 39 degrees of freedom
# Multiple R-squared: 0.9062, Adjusted R-squared: 0.8941
fit.p <- predict(fit, iris[-tr,])
postResample(fit.p, iris[-tr, ]$Sepal.Length)
# RMSE Rsquared MAE
# 0.2795920 0.8925574 0.2302402
如果您想查看每個折疊的性能,您也可以這樣做。
fit$resample
# RMSE Rsquared MAE Resample
# 1 0.3629901 0.7911634 0.2822708 Fold1
# 2 0.3680954 0.8888947 0.2960464 Fold2
# 3 0.3508317 0.8394489 0.2709989 Fold3
# 4 0.2548549 0.8954633 0.1960375 Fold4
# 5 0.3396910 0.8661239 0.3187768 Fold5
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/433036.html
上一篇:在PHP中使用回圈列印多維陣列
