组合学:在不重复元素的情况下随机化,我是在尝试做一些不可能的事情吗?
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
这个新数据框仍然符合所有规范。
对标题的措辞表示歉意,如果答案非常明显,我们深表歉意。我的量化背景不强,可能会问一个愚蠢的问题。
我有一组 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
这个新数据框仍然符合所有规范。