2016-03-04 49 views
4

我有一些分組數據,每個項目有一行。 我想按組進行分層抽樣,有兩個限制:(1)總樣本量一定; (2)樣本應儘可能均勻分配(即組樣本量最小的sd)。限制分層採樣:固定總大小在組間均勻分區

理想情況下,我們從每個組中挑選相同(固定)數量的項目,當所有組的組大小爲>=所需的size時,這是沒有問題的。但是,有時組的大小小於size。儘管如此,項目總數總是高於總樣本量。例如,具有12的總樣本大小,和四個不同的基團,我們非常希望從每個組挑3項

size_tot <- 12 
n_grp <- 4 
size <- size_tot/n_grp 

一些數據:

d2 <- data.table(id = 1:16, 
       grp = rep(c("a", "b", "c", "d"), c(9, 4, 2, 1))) 
d2 
#  id grp 
# 1: 1 a 
# 2: 2 a 
# 3: 3 a 
# 4: 4 a 
# 5: 5 a 
# 6: 6 a 
# 7: 7 a 
# 8: 8 a 
# 9: 9 a 
# 10: 10 b 
# 11: 11 b 
# 12: 12 b 
# 13: 13 b 
# 14: 14 c 
# 15: 15 c 
# 16: 16 d 

我原來的邏輯是「如果物品數量等於或大於size,樣本size物品來自組別,否則僅選擇組中的所有物品「。另見here,herehere

set.seed(1) 
d2[ , if(.N >= size) .SD[sample(x = .N, size = size)] else .SD, by = "grp"] 

# grp id 
# 1: a 3 
# 2: a 9 
# 3: a 5 
# 4: b 13 
# 5: b 10 
# 6: b 11 
# 7: c 14 
# 8: c 15 
# 9: d 16 

在具有足夠數量的項目(a和b)的兩個組中,我們從每個項目中採樣3個項目。在小組(c和d)中,我們只是選擇了全部,即分別爲2和1。這導致總樣本大小爲9,即小於期望的總大小12.因此,我們需要從具有剩餘項目的較大羣組中取樣其他項目以實現期望的總樣本大小。在這種情況下,期望的採樣將是來自「b」的1個附加項目和來自「a」的兩個附加項目。

以下是我如何看待最低sd的分區。總樣本大小可以被劃分爲四組這樣的:

library(partitions) 
cmp <- compositions(n = size_tot, m = 4) 

的分區然後可以從低sd(等於樣本大小組間 - 期望的)命令高sd

std <- apply(cmp, 2, sd) 
cmp2 <- cmp[ , order(std)] 

cmp2[ , 1:10] 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
# [1,] 3 4 3 3 4 3 4 2 3  2 
# [2,] 3 3 4 3 3 4 2 4 2  3 
# [3,] 3 3 3 4 2 2 3 3 4  4 
# [4,] 3 2 2 2 3 3 3 3 3  3 

而組的大小:

d1[ , .(n = .N), by = "grp"] 
# grp n 
# 1: a 9 
# 2: b 4 
# 3: c 2 
# 4: d 1 

但如何匹配此分區(其中總和爲12)對組樣本大小(它不一定總和t o 12)?有沒有人在這裏聞到XY-問題?因此,我有忽略的替代方法嗎?


PS:我已考慮比例分配(比例抽樣),但 當組的尺寸分佈是充分偏斜,這種採樣並明顯不尊重絕對總樣本大小,並且不組間均勻地分佈的樣品(例如caret::createDataPartitionstrata::balancedstratification

+0

它爲什麼會做錯過採樣中最小類(通過bootstrap或SMOTE)而不是在大多數類中重新採樣? – agenis

+0

@agenis我必須做抽樣沒有替換,所以我不能過度抽樣最小的類(如果我正確地理解你的術語)。 – Henrik

回答

3

我想你的答案几乎就在那裏。你只需要在CMP2過濾得到滿足,採樣大小低於或等於組大小的標準第一取樣組:

#Create a set of indices of sampling sizes that fit the criteria 
original_groups <- d2[, .N, by = grp][,N] 
valid_indexes <- apply(cmp2, 2, function(x) all(x <= original_groups)) 

#Take the first of these valid indices (lowest variance) 
sampling_sizes <- cmp2[,which(valid_indexes)[1]] 

#Create a sampling size variable on the datatable 
d2[, sampling_size := rep(sampling_sizes, original_groups)] 

#Sample as before 
d2[ , .SD[sample(x = .N, size = sampling_size)], by = "grp"] 
在烏拉圭回合的情況下