![](/img/trans.png)
[英]How should I specify argument “prob” when using sample() for resampling?
[英]What happens when prob argument in sample sums to less/greater than 1?
我們知道sample
中的prob
參數用於分配權重的概率。
例如,
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 呢? 它會給出什么輸出? 我認為這會導致錯誤,但它提供了一些價值。
當概率總和大於 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,但它們應該是非負數且不能全為零。 如果 replace 為真,則當存在超過 200 個合理可能值時使用 Walker 的別名方法 (Ripley, 1987):這會產生與 R < 2.2.0 中的結果不兼容的結果。
所以它說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
, 在 src/main/random.c 中定義。
如果您查看此 C 代碼, do_sample
檢查它是否已傳遞一個prob
向量。 如果不是,則在相等權重的假設下進行采樣。 如果prob
存在,該函數確保它是數字而不是 NA。 如果prob
通過這些檢查,則會生成一個指向底層雙精度數組的指針,並將其傳遞給 random.c 中名為FixUpProbs
另一個函數,在此處定義。
此函數檢查prob
每個成員,如果prob
任何元素不是正有限雙精度數,則拋出錯誤。 然后它通過將每個數字除以所有數字的總和來標准化這些數字。 因此,對於代碼中固有的prob
總和為 1,根本沒有偏好。 也就是說,即使輸入中的prob
總和為 1,該函數仍會計算總和並將每個數字除以它。
因此,該參數命名不當。 正如這里的其他人指出的那樣,它應該是“權重”。 公平地說,文檔只說prob
應該是權重向量,而不是絕對概率。
所以我閱讀代碼的prob
參數的行為應該是:
prob
可以完全不存在,在這種情況下,采樣默認為相等的權重。prob
的數字小於零,或者是無限的,或者不適用,該函數將拋出。prob
值不是數字,則應拋出錯誤,因為它們將在傳遞給 C 代碼的 SEXP 中解釋為NA
。prob
的長度必須與x
相同,否則 C 代碼會拋出replace=T
,您可以將零概率作為prob
一個或多個元素傳遞,只要您至少有一個非零概率。replace=F
,則請求的樣本數必須小於或等於prob
的非零元素數。 本質上,如果您要求它以零概率進行采樣, FixUpProbs
會拋出FixUpProbs
。prob
向量將被歸一化為總和為 1 並用作采樣權重。 作為這種行為的一個有趣的副作用,如果您通過設置 probs = c(1, odds)
在 2 個備選方案之間進行選擇,則這允許您使用賠率而不是概率
如前所述,權重被歸一化為總和為 1,可以證明:
> x/sum(x)
[1] 0.15384615 0.38461538 0.38461538 0.07692308
這與您的模擬表格數據相匹配:
# 1 2 3 4
#0.1544 0.3839 0.3848 0.0768
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.