我们知道prob
中的sample
参数用于分配权重概率。
例如,
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.4, 0.3, 0.1)))/1e6
# 1 2 3 4
#0.2 0.4 0.3 0.1
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.4, 0.3, 0.1)))/1e6
# 1 2 3 4
#0.200 0.400 0.299 0.100
在此示例中,概率之和恰好为1(0.2 + 0.4 + 0.3 + 0.1),因此它给出了预期的比率,但是如果概率之和不等于1怎么办?它会给出什么输出?我以为会导致错误,但可以提供一些值(value)。
当概率总和大于1时。
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.5, 0.5, 0.1)))/1e6
# 1 2 3 4
#0.1544 0.3839 0.3848 0.0768
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.2, 0.5, 0.5, 0.1)))/1e6
# 1 2 3 4
#0.1544 0.3842 0.3848 0.0767
当概率总和小于1时
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.1, 0.1, 0.5, 0.1)))/1e6
# 1 2 3 4
#0.124 0.125 0.625 0.125
table(sample(1:4, 1e6, replace = TRUE, prob = c(0.1, 0.1, 0.5, 0.1)))/1e6
# 1 2 3 4
#0.125 0.125 0.625 0.125
如我们所见,多次运行会得到不等于
prob
的输出,但结果也不是随机的。在这种情况下,数字如何分配?它在哪里记录?我尝试在互联网上搜索,但未找到任何相关信息。我浏览了
?sample
的文档,该文档具有因此,它说
prob
参数不必求和为1,但是当不求和为1时却不告诉期望什么?我不确定是否缺少文档的任何部分。有人有什么主意吗? 最佳答案
好问题。文档尚不清楚,但是可以通过查看源代码来回答问题。
如果查看R代码,sample
始终调用另一个R函数sample.int
如果将单个数字x
传递给sample
,它将使用sample.int
创建一个小于或等于该数字的整数向量,而如果x
是一个向量,它使用sample.int
生成一个小于或等于length(x)
的整数样本,然后使用该样本对x进行子集化。
现在,如果您检查函数sample.int
,它看起来像这样:
function (n, size = n, replace = FALSE, prob = NULL, useHash = (!replace &&
is.null(prob) && size <= n/2 && n > 1e+07))
{
if (useHash)
.Internal(sample2(n, size))
else .Internal(sample(n, size, replace, prob))
}
.Internal
表示可以通过调用用C编写的已编译代码来完成任何采样:在这种情况下,它是do_sample
函数,定义为here in src/main/random.c。如果查看此C代码,
do_sample
将检查是否已将其传递给prob
向量。如果不是,则在权重相等的假设下进行采样。如果prob
存在,该函数将确保它是数字而不是NA。如果prob
通过了这些检查,则将生成指向基础 double 数组的指针,并将其传递给random.c中另一个称为FixUpProbs
的函数,已定义为here。此函数检查
prob
的每个成员,如果prob
的任何元素不是正有限 double 数,则将引发错误。然后通过将每个数除以所有总和来归一化这些数字。因此,根本没有偏好将prob
总和为1的固有代码。也就是说,即使输入中的prob
总和为1,该函数仍会计算总和并将每个数字除以总和。因此,该参数的命名不正确。正如这里其他人所指出的,它应该是“重量”。公平地说,文档只说
prob
应该是权重的向量,而不是绝对概率。因此,根据我对代码的阅读,
prob
参数的行为应为:prob
可能完全不存在,在这种情况下,默认情况下采样权重相等。 prob
的任何数字小于零,无穷大或不适用,则函数将抛出。 prob
值是非数字的,则应该引发错误,因为它们在传递给C代码的SEXP中将被解释为NA
。 prob
的长度必须与x
相同,否则C代码会抛出prob
,则可以将零概率作为replace=T
的一个或多个元素传递,只要您具有至少一个非零概率即可。 replace=F
,则请求的样本数必须小于或等于prob
中的非零元素数。本质上,如果您要求FixUpProbs
进行采样的概率为零,则将抛出prob
。 c(1, odds)
向量将被归一化为1,并用作采样权重。 作为此行为的一个有趣的副作用,如果您通过设置probs = ojit_code在2个备选方案之间进行选择,则可以使用赔率代替概率
关于r - 样本中的prob参数总和小于/大于1时会发生什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59918865/