首页 > 解决方案 > 转换数据,使中位数周围的范围更准确

问题描述

假设我有一些正态分布在 0 附近的浮点数。我需要将其序列化为 uint8,但我想将 uint8 的“更多”分配给分布的中心,并在边缘周围失去分辨率。

例如:127将对应于0.0和。但不会——相反,它类似于因为我们正在拉伸它,以便大多数数字对应于接近 0 的值。2551.01910.50.3

在实践中,我实际上将uint32生成一个随机数并将其转换为float. 但是在测试线性映射时,极端值(接近 -1.0 和 1.0)出现得太频繁了,我想把它集中在0.0.

我知道我可以使用Box–Muller transform,但这实际上不适合这里,因为:

  1. 我们可以限制在 -1.0 和 1.0,不需要有无限的输出。

  2. 我们只有一个数字可供抽样,而不是两个。

谢谢

标签: algorithmmathrandomnormal-distribution

解决方案


分位数函数(也称为逆 CDF)将 [0, 1] 中的均匀随机数映射到服从分布(例如正态分布)的数字。

但是,在正态分布的情况下,有一些事情需要知道(从现在开始调用分位数函数 Q(u)):

  • 分位数函数的范围是从 0 到 1,而不是从 -1 到 1 或从 0 到 255。
  • 正态分布可以取任何实数。事实上,对于这种分布,Q(0) 和 Q(1) 将等于无穷大。
  • 正态分布的分位数涉及逆误差函数。分位数可能容易实现,也可能不容易实现,具体取决于您的编程环境是否已经具有可用的逆误差函数。
  • 由于上述原因,您必须缩放分位数函数以适合您所需的范围并避免无穷大,例如,从 [0.001, 0.999] 到 [0, 255](其中 128 对应于 Q(0.5),即0 在正态分布的情况下)。下面是一个伪代码示例。
 for k in 0..255
    c=0.001+(0.999-0.001)*(k*1.0/256)
    print([k, Q(c)]) // print the uint8 value followed by the quantile
 end

推荐阅读