不同样本量的 k 折交叉验证
k-fold cross validation with different sample sizes
我有一个来自 3 个站点的组合数据集,我想知道通用关系与站点特定关系相比如何。该计划是一个 k 折交叉验证。基于此 cross validated question,我需要从我的不同站点按比例采样,因为它们包含不同数量的观察值。我之前用 caret
做过 k-fold cv:
library(dplyr)
library(caret)
dF=data_frame(y=runif(100,1,6),x1=runif(100),x2=runif(100),site=c(rep('a',20),rep('b',20),rep('c',60)) %>% group_by(site)
train_control<- trainControl(method="repeatedcv", number = 4, repeats = 3, savePredictions = TRUE)
model<- train(y~x1*x2+I(x2^2), data=dF, trControl=train_control, method='glmStepAIC',family=gaussian(link='log'))# no need to preprocess because x1 and x2 both have theoretical values (0,1].
但现在还没有弄清楚如何改变分区,以便具有更多观察值的站点不会不公平地影响模型技能。
所以我想要的最终结果是 r2 的数据帧和站点 a、b 和 c 的平均绝对误差以及所有数据。同样,我想知道每个模型场景中 x1 和 x2 的参数。
编辑
我在插入符号文档中发现 downSample
我认为应该对此有所帮助,但我不断收到错误消息。有谁知道为什么会这样? OSX 10.11.1,R 3.2.2,caret_6.0-58
down_train <- downSample(x = dplyr::select(datadF,-basin), y = as.factor(datadF$basin))
Error in sample.int(length(x), size, replace, prob) :
cannot take a sample larger than the population when 'replace = FALSE'
我最终编写了这些函数来满足我的需要:
我调用的函数partition_data
计算出每个盆地中有多少obs,取所有盆地中的最小值,然后用frac
从每个盆地中取多少样本进行采样.
第二个辅助函数基本上只是从每个盆地的 caret
包中调用 createDataPartition
(使用 dplyr
中的 split/apply/combine),其中 perc
是百分比应该划分以适应每个特定盆地的观察结果。
partition_data = function(dF,frac) {
numobs = dF %>% group_by(basin) %>% summarise(nrw = n()) %>% summarise(frac*min(nrw)) %>% as.numeric
print(numobs)
testdata = dF %>% group_by(basin) %>%
do(site_partition(.,numobs))
}
site_partition = function(dF,numobs) {
perc=numobs/nrow(dF)
print(paste(unique(dF$basin),': perc =', perc))
ind = createDataPartition(dF$snowdepth,
p = perc,
list = FALSE,
times = 1)
return(dF[ind,])
}
datadF=data_frame(y=runif(100,1,6),x1=runif(100),x2=runif(100),site=c(rep('a',20),rep('b',20),rep('c',60)) %>% group_by(site)
testdata = partition_data(datadF,0.6)#fit using this data.
valdata=anti_join(datadF,testdata)#independent validation with this data
我有一个来自 3 个站点的组合数据集,我想知道通用关系与站点特定关系相比如何。该计划是一个 k 折交叉验证。基于此 cross validated question,我需要从我的不同站点按比例采样,因为它们包含不同数量的观察值。我之前用 caret
做过 k-fold cv:
library(dplyr)
library(caret)
dF=data_frame(y=runif(100,1,6),x1=runif(100),x2=runif(100),site=c(rep('a',20),rep('b',20),rep('c',60)) %>% group_by(site)
train_control<- trainControl(method="repeatedcv", number = 4, repeats = 3, savePredictions = TRUE)
model<- train(y~x1*x2+I(x2^2), data=dF, trControl=train_control, method='glmStepAIC',family=gaussian(link='log'))# no need to preprocess because x1 and x2 both have theoretical values (0,1].
但现在还没有弄清楚如何改变分区,以便具有更多观察值的站点不会不公平地影响模型技能。
所以我想要的最终结果是 r2 的数据帧和站点 a、b 和 c 的平均绝对误差以及所有数据。同样,我想知道每个模型场景中 x1 和 x2 的参数。
编辑
我在插入符号文档中发现 downSample
我认为应该对此有所帮助,但我不断收到错误消息。有谁知道为什么会这样? OSX 10.11.1,R 3.2.2,caret_6.0-58
down_train <- downSample(x = dplyr::select(datadF,-basin), y = as.factor(datadF$basin))
Error in sample.int(length(x), size, replace, prob) :
cannot take a sample larger than the population when 'replace = FALSE'
我最终编写了这些函数来满足我的需要:
我调用的函数partition_data
计算出每个盆地中有多少obs,取所有盆地中的最小值,然后用frac
从每个盆地中取多少样本进行采样.
第二个辅助函数基本上只是从每个盆地的 caret
包中调用 createDataPartition
(使用 dplyr
中的 split/apply/combine),其中 perc
是百分比应该划分以适应每个特定盆地的观察结果。
partition_data = function(dF,frac) {
numobs = dF %>% group_by(basin) %>% summarise(nrw = n()) %>% summarise(frac*min(nrw)) %>% as.numeric
print(numobs)
testdata = dF %>% group_by(basin) %>%
do(site_partition(.,numobs))
}
site_partition = function(dF,numobs) {
perc=numobs/nrow(dF)
print(paste(unique(dF$basin),': perc =', perc))
ind = createDataPartition(dF$snowdepth,
p = perc,
list = FALSE,
times = 1)
return(dF[ind,])
}
datadF=data_frame(y=runif(100,1,6),x1=runif(100),x2=runif(100),site=c(rep('a',20),rep('b',20),rep('c',60)) %>% group_by(site)
testdata = partition_data(datadF,0.6)#fit using this data.
valdata=anti_join(datadF,testdata)#independent validation with this data