4 回答

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊
您可以為正值和負(fù)值創(chuàng)建兩個(gè)不同的數(shù)組。確保正側(cè)加起來(lái)為 1,負(fù)側(cè)加起來(lái)為 0。
import numpy as np
size = 10
x_pos = np.random.uniform(0, 1, int(np.floor(size/2)))
x_pos = x_pos/x_pos.sum()
x_neg = np.random.uniform(0, 1, int(np.ceil(size/2)))
x_neg = x_neg - x_neg.mean()
x = np.concatenate([x_pos, x_neg])
np.random.shuffle(x)
print(x.sum(), x.max(), x.min())
>>> 0.9999999999999998 0.4928358768227867 -0.3265210342316333
print(x)
>>>[ 0.49283588 0.33974127 -0.26079784 0.28127281 0.23749531 -0.32652103
0.12651658 0.01497403 -0.03823131 0.13271431]

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超7個(gè)贊
在這種情況下,讓我們讓均勻分布開始該過(guò)程,但調(diào)整值以使總和為 1。為了便于說(shuō)明,我將使用初始步驟這給我們總和為 -0.5,但我們需要[-1, -0.75, 0, 0.25, 1] 1.0
第 1 步:計(jì)算所需的總找零金額:1.0 - (-0.5) = 1.5。
現(xiàn)在,我們將分配元素之間的變化是某種適當(dāng)?shù)姆绞健N沂褂玫囊环N簡(jiǎn)單方法是最大程度地移動(dòng)中間元素,同時(shí)保持端點(diǎn)穩(wěn)定。
步驟 2:計(jì)算每個(gè)元素與較近端點(diǎn)的差異。對(duì)于您的不錯(cuò)的范圍,這是1 - abs(x)
第 3 步:總結(jié)這些差異。分成所需的變化。這給出了調(diào)整每個(gè)元素的量。
將這些內(nèi)容放入圖表中:
x diff adjust
-1.0 0.00 0.0
-0.75 0.25 0.1875
0.0 1.0 0.75
0.25 0.75 0.5625
1.0 0.0 0.0
現(xiàn)在,只需添加x和adjust列即可獲取新值:
x adjust new
-1.0 0.0 -1.0
-0.75 0.1875 -0.5625
0 0.75 0.75
0.25 0.5625 0.8125
1.0 0.0 1.0
這是您調(diào)整后的數(shù)據(jù)集:總和為 1.0,端點(diǎn)完好無(wú)損。
簡(jiǎn)單的Python代碼:
x = [-1, -0.75, 0, 0.25, 1.0]
total = sum(x)
diff = [1 - abs(q) for q in x]
total_diff = sum(diff)
needed = 1.0 - sum(x)
adjust = [q * needed / total_diff for q in diff]
new = [x[i] + adjust[i] for i in range(len(x))]
for i in range(len(x)):
print(f'{x[i]:8} {diff[i]:8} {adjust[i]:8} {new[i]:8}')
print (new, sum(new))
輸出:
-1 0 0.0 -1.0
-0.75 0.25 0.1875 -0.5625
0 1 0.75 0.75
0.25 0.75 0.5625 0.8125
1.0 0.0 0.0 1.0
[-1.0, -0.5625, 0.75, 0.8125, 1.0] 1.0
我會(huì)讓你在 NumPy 中對(duì)其進(jìn)行向量化。

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
拒絕抽樣
您可以使用拒絕抽樣。下面的方法通過(guò)在比原始空間小 1 維的空間中進(jìn)行采樣來(lái)實(shí)現(xiàn)此目的。
第 1 步:通過(guò)從均勻分布中對(duì)每個(gè) x(i) 進(jìn)行采樣來(lái)隨機(jī)采樣 x(1)、x(2)、...、x(n-1)
步驟 2:如果總和 S = x(1) + x(2) + ... + x(n-1) 低于 0 或高于 2,則拒絕并重新開始步驟 1。
步驟 3:計(jì)算第 n 個(gè)變量 x(n) = 1-S
直覺(jué)
您可以在笛卡爾坐標(biāo) ±1、±1、.. 的 n 維立方體內(nèi)部查看向量 x(1)、x(2)、...、x(n-1)、x(n)。 . , ±1.?這樣您就遵循約束 -1 <= x(i) <= 1。
坐標(biāo)之和必須等于 1 的附加約束將坐標(biāo)限制到比超立方體更小的空間,并且將是維度為n-1 的超平面。
如果您定期進(jìn)行拒絕采樣,即從所有坐標(biāo)的均勻分布中采樣,那么您將永遠(yuǎn)不會(huì)遇到約束。采樣點(diǎn)永遠(yuǎn)不會(huì)在超平面內(nèi)。因此,您考慮 n-1 個(gè)坐標(biāo)的子空間?,F(xiàn)在您可以使用拒絕采樣。
視覺(jué)上
假設(shè)您的維度為 4,那么您可以繪制 4 的坐標(biāo)中的 3。該圖(均勻地)填充了一個(gè)多面體。下面通過(guò)以切片形式繪制多面體來(lái)說(shuō)明這一點(diǎn)。每個(gè)切片對(duì)應(yīng)于不同的總和 S = x(1) + x(2) + ... + x(n-1) 以及不同的 x(n) 值。
圖像:3 個(gè)坐標(biāo)的域。每個(gè)彩色表面都與第四個(gè)坐標(biāo)的不同值相關(guān)。
邊際分布
對(duì)于大維度,拒絕采樣的效率將變得較低,因?yàn)榫芙^的比例隨著維度的數(shù)量而增長(zhǎng)。
“解決”這個(gè)問(wèn)題的一種方法是從邊際分布中抽樣。然而,計(jì)算這些邊際分布有點(diǎn)乏味。比較:對(duì)于從狄利克雷分布生成樣本,存在類似的算法,但在這種情況下,邊際分布相對(duì)容易。(但是,導(dǎo)出這些分布也不是不可能,請(qǐng)參見(jiàn)下文“與歐文霍爾分布的關(guān)系”)
在上面的示例中,x(4) 坐標(biāo)的邊緣分布對(duì)應(yīng)于切口的表面積。因此,對(duì)于 4 維,您可能能夠根據(jù)該數(shù)字計(jì)算出計(jì)算結(jié)果(您需要計(jì)算這些不規(guī)則多邊形的面積),但對(duì)于更大的維度,它開始變得更加復(fù)雜。
與歐文·霍爾分布的關(guān)系
要獲得邊際分布,您可以使用截?cái)嗟臍W文霍爾分布。歐文霍爾分布是均勻分布變量之和的分布,并且遵循某些分段多項(xiàng)式形狀。下面通過(guò)一個(gè)示例對(duì)此進(jìn)行了演示。
代碼
由于我的 python 生銹了,所以我主要添加 R 代碼。該算法非?;A(chǔ),因此我想任何 Python 編碼人員都可以輕松地將其改編為 Python 代碼。在我看來(lái),這個(gè)問(wèn)題的困難部分更多地是關(guān)于算法,而不是關(guān)于如何用 Python 編碼(盡管我不是 Python 編碼員,所以我把這個(gè)問(wèn)題留給其他人)。
圖像:采樣的輸出。4 條黑色曲線是四個(gè)坐標(biāo)的邊緣分布。紅色曲線是基于歐文霍爾分布的計(jì)算。這可以擴(kuò)展到通過(guò)直接計(jì)算而不是拒絕采樣的采樣方法。
python中的拒絕采樣
import numpy as np
def sampler(size):
? ?reject = 1
? ?while reject:
? ? ? x = np.random.rand(size - 1) # step 1
? ? ? S = np.sum(x)
? ? ? reject = (S<0) or (S>2)? ? ? # step 2
? ?x = np.append(x,1-S)? ? ? ? ? ? # step 3
? ?return[x]
y = sampler(5)?
print(y, np.sum(y))
R 中的更多代碼,包括與 Irwin Hall 分布的比較。該分布可用于計(jì)算邊際分布,并可用于設(shè)計(jì)一種比拒絕采樣更有效的算法。
### function to do rejection sample
samp <- function(n) {
? S <- -1
? ## a while loop that performs step 1 (sample) and 2 (compare sum)
? while((S<0) || (S>2) ) {?
? ? x <- runif(n-1,-1,1)
? ? S <- sum(x)
? }
? x <- c(x,1-S) ## step 3 (generate n-th coordinate)
? x
}
### compute 10^5 samples
y <- replicate(10^5,samp(4))
### plot histograms
h1 <- hist(y[1,], breaks = seq(-1,1,0.05))
h2 <- hist(y[2,], breaks = seq(-1,1,0.05))
h3 <- hist(y[3,], breaks = seq(-1,1,0.05))
h4 <- hist(y[4,], breaks = seq(-1,1,0.05))
### histograms together in a line plot
plot(h1$mids,h1$density, type = 'l', ylim = c(0,1),
? ? ?xlab = "x[i]", ylab = "frequency", main = "marginal distributions")
lines(h2$mids,h2$density)
lines(h3$mids,h3$density)
lines(h4$mids,h4$density)
### add distribution based on Irwin Hall distribution
### Irwin Hall PDF
dih <- function(x,n=3) {
? k <- 0:(floor(x))? ?
? terms <- (-1)^k * choose(n,k) *(x-k)^(n-1)
? sum(terms)/prod(1:(n-1))
}
dih <- Vectorize(dih)
### Irwin Hall CDF
pih <- function(x,n=3) {
? k <- 0:(floor(x))? ?
? terms <- (-1)^k * choose(n,k) *(x-k)^n
? sum(terms)/prod(1:(n))
}
pih <- Vectorize(pih)
### adding the line?
### (note we need to scale the variable for the Erwin Hall distribution)
xn <- seq(-1,1,0.001)
range <- c(-1,1)
cum <- pih(1.5+(1-range)/2,3)
scale <- 0.5/(cum[1]-cum[2]) ### renormalize
? ? ? ? ? ? ? ? ? ? ? ? ? ?### (the factor 0.5 is due to the scale difference)
lines(xn,scale*dih(1.5+(1-xn)/2,3),col = 2)

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超3個(gè)贊
您已經(jīng)編寫了代數(shù)矛盾的代碼。您引用的問(wèn)題的假設(shè)是隨機(jī)樣本將大約填充范圍 [-1, 1]。如果線性重新縮放,從代數(shù)角度來(lái)說(shuō)不可能維持該范圍,除非在縮放之前總和為 1 ,這樣縮放不會(huì)發(fā)生任何變化。
您在這里有兩個(gè)直接選擇:
放棄范圍的想法。進(jìn)行簡(jiǎn)單的更改以確??偤?em>至少為1,并在縮放后接受更小的范圍。你可以用任何你喜歡的方式來(lái)做到這一點(diǎn),使選擇偏向積極的一面。
更改原始的“隨機(jī)”選擇算法,使其總和趨于接近 1,然后添加一個(gè)最終元素,使其恰好返回 1.0。那么你就不必重新縮放。
考慮基本的區(qū)間代數(shù)。如果您以 的間隔(范圍)開始[-1,1]
并乘以a
(這適合1/sum(x)
您),則所得間隔為[-a,a]
。如果a > 1
,就像您的情況一樣,所得的間隔更大。如果a < 0
,則交換區(qū)間的兩端。
從您的評(píng)論中,我推斷您的概念問(wèn)題更加微妙。您試圖強(qiáng)制預(yù)期值為 的分布0
產(chǎn)生總和為 1 的分布。這是不現(xiàn)實(shí)的,除非您同意以某種方式在沒(méi)有特定界限的情況下扭曲該分布。到目前為止,你拒絕了我的建議,但還沒(méi)有提出任何你愿意接受的建議。在您確定這一點(diǎn)之前,我無(wú)法合理地為您建議解決方案。
添加回答
舉報(bào)