[英]Adding realistic noise to a gaussian distribution while keeping the number of samples above/below a threshold approximately constant
我有一個正態分布和一個閾值函數,該函數確定一個值是否為真。
我想給真值添加噪聲,以便高於或低於閾值的值越不可能被反轉。 因此,在極端情況下,可能有1%的機會發生翻轉,而在閾值處,就有50%的機會發生翻轉。
我還希望在添加噪聲之前和之后將閾值之上和之下的樣本數量保持大致恆定。
我認為下面的代碼在上半年進行,但不確定下半年的方法。 (也許嘗試從rnum中減去一個增量,直到操作前后的真值之和在某個誤差范圍內)
import numpy as np
mean = .5
std_dev = .2
num_points = 10000
arr = np.sort( np.random.normal(loc=mean, scale= std_dev, size=(num_points)) )
threshold = .8
trues = arr >= threshold
temp = np.where(trues, 1-arr, arr)
scaling = max(temp)
temp *= .5/scaling
rnum = np.random.random(size=(num_points))
flip = rnum <= temp
trues = np.logical_xor(trues, flip)
如果我做對了,您想要一個具有以下屬性的輸出向量:
因此,您需要一個概率函數,該函數告訴每個輸入值對輸出值給出True的概率。 使用普通閾值時,概率是在閾值之上1且在閾值之下0。 但是,您需要更輕松一些。
如果沒有輸出向量的最后一個要求(真實數),該算法將非常簡單。 將概率函數輸出與0到1之間的隨機值進行比較,這將是結果。 根據輸入信號分布和概率函數,這可能會產生令人滿意的結果。
只是一個例子:
# threshold at 0.8, below 0.7 always false, above 0.9 always True, linear in between
def prob_f(x):
return np.clip((x - 0.8) / .2 + .5, 0., 1.)
def noisy_threshold(sig):
p = prob_f(sig)
return p > random.random(sig.shape)
但是,如果需要與Trues數量更好的匹配,我們需要事后做一些事情。 我們需要一個函數,該函數給出所需的真實數和概率。 當然,這樣做會改變所得分布的某些屬性,因此沒有“干凈”的方法。
一種可能性是稍微調整我們的概率閾值。 例如:
def_ noisy_threshold(sig, threshold):
# number of Trues with simple thresholding
n_trues = np.asum(sig > threshold)
# difference between random noise and our probability
rdiff = prob_f(sig) - random.random(sig.shape)
# sort the differences
sortdiff = sorted(rdiff)
# a new threshold is used so that the number of Trues is correct:
return rdiff >= sortdiff[-n_trues]
如果我們不是很不幸地得到一些完全相同的隨機差異,這將返回n_trues
Trues。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.