我有一个正态分布和一个阈值函数,该函数确定一个值是否为真。
我想给真值添加噪声,以便高于或低于阈值的值越不可能被反转。因此,在极端情况下,可能有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
如果我们不是很不幸地得到一些完全相同的随机差异,则这将返回True。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句