组合学:在不重复元素的情况下随机化,我是在尝试做一些不可能的事情吗?

Combinatorics: randomise without repetition of elements, am I trying to do something impossible?

对标题的措辞表示歉意,如果答案非常明显,我们深表歉意。我的量化背景不强,可能会问一个愚蠢的问题。

我有一组 24 个我们可以想象成图片的项目,以及这些图片的 24 个标签。这意味着我有 552 个可能的 picture-label 对。

我想为这些 picture-label 对中的每一对收集 10 个评分,因此总共有 5520 个评分,我想从 460 个参与者中收集它们,每个参与者给出 12 个评分。

当我尝试不重复地生成输入文件(select 12 picture-label 对)时出现问题。我可以在不重复 的情况下执行此操作,但我也不希望任何图片在任何给定参与者的输入中出现两次,也不希望任何标签出现两次。

我试图通过从一个包含 5520 行的数据框开始来做到这一点,其中包含我要为其收集评级的所有 picture-label 对。然后我从此数据框中采样 12 行,直到找到不包含任何重复的样本,从数据框中删除这些行并继续。 当我到达一个点时,如果不从剩余的行中重复,就无法再对 df 进行采样,这会导致陷入无限的 while 循环。

这是因为我的方法不对,还是我想做一些不可能的事情?


pairs <- as.data.frame(permutations(n = 24, r = 2, v = seq(1:24), repeats.allowed=F))
nrow(pairs)

for (i in seq(1, to =552, by =12)) {

#get sample
s <- sample(nrow(shuffled_pairs),12)
d <- shuffled_pairs[s,]

#check for repetitions of either V1 (pic) or V2 (label)
while (length(unique(d$V1))<12 | length(unique(d$V1))<12) {
    s <- sample(nrow(shuffled_pairs),12)
    d <- shuffled_pairs[s,]    
}

shuffled_pairs <- shuffled_pairs[-s,]

}

答案是,这对于 46 个评分员来说是不可能的:您需要 48 个评分员,每个评分员进行 12 个评分,以覆盖您需要的 10 * 24 * 24 或 5760 个样本。但是,有了这个警告,就可以在所需的约束范围内获得所需的所有样本。代码本身很短:

mod24 <- function(x) (x + 0:11 - 1) %% 24 + 1

df <- data.frame(picture = rep(c(rep(1:12, 24), rep(13:24, 24)), 10),
                 label = rep(do.call("c", lapply(1:24, mod24)), 20),
                 rater   = rep(c(rep(1:48, each = 12)), 10) + rep(0:9 * 48, each = 576))

然而,这需要相当多的解释。

你可以让你的问题更简单一点,注意无论你做什么,你都可以将你的 480 人分成十组,每组 48 人,每组做同样的事情,即在他们之间给每个人评分 picture/label 恰好组合一次,每个组合恰好使用 12 个评分。因此,您可以专注于一组 48 个人将如何执行此任务以恰好涵盖所有 576 种可能性。

还有一点需要注意的是,由于每个人都要挑选12幅画,所以你可以进一步简化,将48人的小组分成两组,每组24人,每组24人,他们要么得到前12幅,要么得到后12幅。这样,您就可以保证每个评估者不会有任何重复的绘画。

现在您需要做的就是确保每幅画的每个标签都恰好出现一次。您可以通过给第一个参与者的绘画标签 1:12,然后给第二个参与者的绘画标签 2:13 等等,直到达到 13:24,之后标签变成 c(14:24, 1) , 然后是 c(15:24, 1:2) 等等。这确保了在有绘画 1:12 的组中,每幅画都会为每个标签分配一次且仅分配一次。现在对绘画 13:24 做同样的事情。您将有 48 个人,每个人有 12 个评分,一次涵盖所有可能的组合。

对每组 48 人进行同样的操作,每个独特的图片/标签对将有 10 个评分,每个评分者将给出 12 个评分,没有评分者会对同一幅画或标签评分两次。

回到我们的代码,我们可以看到 df 包含 5760 个样本:

nrow(df)
#> [1] 5760

它有576种独特的图片和标签组合,每一种重复10次:

table(df$picture, df$label)
#>     
#>       1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#>   1  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   2  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   3  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   4  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   5  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   6  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   7  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   8  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   9  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   11 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   13 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   15 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   16 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   17 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   18 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   19 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   20 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   21 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   22 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   23 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
#>   24 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10

并且 480 位评分者中的每一位都有 12 对要评分

table(table(df$rater))

#>  12 
#> 480 

所有这些都是独一无二的:

table(sapply(split(df, df$rater), function(x) nrow(unique(x))))

#>  12 
#> 480

编辑

OP 担心图片组的不断同时出现可能会引入偏差。解决方法是将图片 1:12 组中的第一个人和 13:24 组中的第一个人配对,并允许他们随机交易他们的一些分配。他们的照片不会重复,因为他们的照片没有重叠,他们的标签不会重复,因为他们总是交换相同的标签:

swaps <- do.call(c, lapply(1:10, function(x) c(rbinom(24 * 12, 1, 0.5), rep(0, 24 * 12))))
swap_out <- df[swaps == 1, ]
df[swaps == 1, ] <- df[which(swaps == 1) + 24 * 12, ]
df[which(swaps == 1) + 24 * 12, ] <- swap_out

这个新数据框仍然符合所有规范。