我正在开发一个程序,该程序从图表中读取数据并以特定频率播放值,该频率已被标准化以显示数据点之间的差异。
在测试中,我发现“可接受”的声音范围介于 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;
}
这有效,但在某些情况下会带来一个小问题。如果用户在同一个数据集中有一个非常小的值和一个非常大的值。
简单示例:A 公司的利润为 1 美元,B 公司的利润为 10 亿美元,如果 C 公司和 D 公司等......的利润与边缘情况相距甚远,就不会有问题。但是,假设 C 公司的利润为 5000 万美元。这大大超过 1 美元,远低于 10 亿美元,不会有太大问题。但是,如果 D 的利润为 2 万美元,那么我们可能会遇到问题。
归一化后的数字是这样的(最大值为 3800,最小值为 200):
1 = 200.0000036
20,000 = 200.072
5000 万 = 380
10 亿 = 3800
在这里,我们可以看到明显的问题。如果我们使用上面的函数将声音归一化到所需的频率范围,那么具有巨大数据差异的大型数据集可能会扭曲对图形上所表示内容的感知。由于标准化如何将较大的数据压缩到较小的数字范围内,因此只有当最大和最小数字相距很远时,这才会成为问题。
两种可能的解决方案:
它涉及自动解析来自 csv 文件的数据,因为
任何超过上限的东西只会播放最高频率。
我在正确的方向。我认为使用某种对数
缩放以使较大的数据不那么重要将是一个很好的选择
解决方案。我的意思是类似于这里的图表:
原谅我糟糕的绘画技巧,但你能明白我的意思。随着数字变大,它们变得越来越不重要。这不是数字之间的关系,但我认为人类对大数字的感知已经很模糊,所以让大数字听起来比小数字更接近更好。 (例如 1 和 20,000)。
你怎么看?
编辑:
我认为提到以数字为基数 10 的评论之一是在正确的轨道上,但是它不适用于较小的数据点,因为数字会靠得太近。 IE 日志 1 是 1,日志 10 是 2。1 和 2 靠得很近,你听不到任何区别。
最佳答案
试试这个:
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;
}
这应该均匀分布。
使用您提供的相同参数,以下是新值:
1:200
2万:1920.4119982655923
5000万:3279.588001734408
10 亿 = 3800。
这是使用 log10。对于或多或少的对数效果,请使用不同的底数,例如 log2 或 log16。
关于javascript - 如何使用对数刻度偏斜归一化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42562111/