Python 向高斯分布添加真实噪声,同时保持高于/低于阈值的采样数近似恒定

Python 向高斯分布添加真实噪声,同时保持高于/低于阈值的采样数近似恒定,python,numpy,statistics,normal-distribution,Python,Numpy,Statistics,Normal Distribution,我有一个正态分布和一个阈值函数来确定一个值是否为真 我想给真值加上噪声,这样越是高于/低于阈值,值反转的可能性就越小。因此,在极端情况下,可能有1%的机会发生翻转,而在临界点处,则有50%的可能性 我还希望在添加噪声之前和之后,保持阈值上方和下方的采样数近似恒定 我认为下面的代码可以完成上半部分,但不能确定下半部分的方法。(可能从rnum中尝试减去一个增量,直到运算前后的真值之和在一定误差范围内) 将numpy导入为np 平均值=.5 标准偏差=.2 点数=10000 arr=np.sort(n

我有一个正态分布和一个阈值函数来确定一个值是否为真

我想给真值加上噪声,这样越是高于/低于阈值,值反转的可能性就越小。因此,在极端情况下,可能有1%的机会发生翻转,而在临界点处,则有50%的可能性

我还希望在添加噪声之前和之后,保持阈值上方和下方的采样数近似恒定

我认为下面的代码可以完成上半部分,但不能确定下半部分的方法。(可能从rnum中尝试减去一个增量,直到运算前后的真值之和在一定误差范围内)

将numpy导入为np
平均值=.5
标准偏差=.2
点数=10000
arr=np.sort(np.random.normal(loc=mean,scale=std\u dev,size=num\u points)))
阈值=.8
trues=arr>=阈值
温度=np.其中(真实,1-arr,arr)
缩放=最大值(温度)
温度*=.5/标度
rnum=np.random.random(大小=(点数))

flip=rnum如果我做对了,您希望有一个具有以下属性的输出向量:

  • 布尔向量
  • 与输入向量中的元素数相同
  • 每个元素为真的概率取决于其值w.r.t.阈值
  • Trues的数量与使用简单阈值时的数量相同
所以,你需要一个概率函数,它告诉你每个输入值的概率,让输出值为真。使用普通阈值时,概率高于阈值1,低于阈值0。然而,你需要一些更柔和的东西

如果没有输出向量的最后一个要求(Trues数),算法将非常简单。概率函数输出将与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,以防我们不是非常不幸地得到完全相同的随机差异。

您是否希望在样本中添加特定类型的噪声?如果你加上高斯噪声,加上一个小的平均值,你会得到你想要的效果。该值离阈值越远,其变化的可能性越小。
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]