如何使用对数刻度偏斜归一化?

Rem*_*ixt 3 javascript normalization

我正在开发一个程序,该程序从图表中读取数据并以特定频率播放值,该频率已被标准化以显示数据点之间的差异。 

在测试中,我发现“可接受”的声音范围介于 200 到 ~3800 之间,因为频率范围不会太高或太低而无法使用。这意味着我需要将所有数据转换为该数字范围。鉴于这些指导方针,这里有一个解决方案。

function normalize(enteredValue, minEntry, maxEntry, normalizedMin, normalizedMax) {

var mx = (enteredValue-minEntry)/(maxEntry-minEntry);
var preshiftNormalized = mx*(normalizedMax-normalizedMin);
var shiftedNormalized = preshiftNormalized + normalizedMin;

return shiftedNormalized;

}
Run Code Online (Sandbox Code Playgroud)

这有效,但在某些情况下会带来一个小问题。如果用户在同一个数据集中有一个非常小的值和一个非常大的值。

简单示例:A 公司的利润为 1 美元,B 公司的利润为 10 亿美元,如果公司 C 和 D 等的利润与边缘情况相距甚远,就不会有问题。但是,假设 C 公司的利润为 5000 万美元。这大大超过 1 美元,远低于 10 亿美元,不会有太大问题。但是,如果 D 的利润为 2 万美元,那么我们可能会遇到问题。

归一化后的数字是这样的(使用 3800 作为最大值,使用 200 作为最小值):

1 = 200.0000036

20000 = 200.072

5000 万 = 380

10 亿 = 3800

在这里,我们可以看到明显的问题。如果我们使用上面的函数将声音归一化到所需的频率范围,那么具有巨大数据差异的大型数据集可能会扭曲对图形上所表示内容的感知。由于归一化如何将较大的数据压缩到较小的数字范围内,因此只有当最大和最小数字相距很远时才会出现问题。

两种可能的解决方案:

  • 设置用户可以在数据集中拥有的最大数量。这是一个简单的解决方法,但在自动解析 csv 文件中的数据时,它会限制程序的功能,因为任何超过上限的内容只会播放最高频率。 

  • 第二个解决方案很复杂,我还不确定如何去做,这就是我希望从您或其他人那里得到的启发,为我指明正确的方向。我认为使用某种对数缩放使较大的数据不那么重要将是一个很好的解决方案。我的意思是类似于这里的图表:

原谅我糟糕的绘画技巧,但你能明白我的意思。随着数字变大,它们变得越来越不重要。这不是数字之间的关系,但我认为人类对大数字的感知已经很模糊,所以让大数字听起来比小数字更接近更好。(例如 1 和 20,000)。

你怎么认为?

编辑:我认为提到以数字为基数 10 的评论之一是正确的,但是它不适用于较小的数据点,因为数字靠得太近。IE 日志 1 是 1,日志 10 是 2。1 和 2 靠得很近,你听不到任何区别。

パスカ*_*スカル 7

尝试这个:

    function normalize(enteredValue, minEntry, maxEntry, normalizedMin, normalizedMax) {

var mx = (Math.log((enteredValue-minEntry))/(Math.log(maxEntry-minEntry)));
var preshiftNormalized = mx*(normalizedMax-normalizedMin);
var shiftedNormalized = preshiftNormalized + normalizedMin;

return shiftedNormalized;

}
Run Code Online (Sandbox Code Playgroud)

这应该均匀分布。

使用您提供的相同参数,以下是新值:

1:200

2万:1920.4119982655923

5000万:3279.588001734408

10 亿 = 3800。

这是使用 log10。对于或多或少的对数效果,请使用不同的底数,例如 log2 或 log16。