我正在开发一个程序,该程序从图形中读取数据,并以已经标准化的特定频率播放值,以显示数据点之间的差异。
在测试中,我发现对于不太高或太低而无法使用的频率范围,“可接受的”声音范围介于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
2万= 200.072
5000万= 380
10亿= 3800
在这里我们可以看到明显的问题。如果我们使用上述函数将声音归一化到所需的频率范围,那么数据差异很大的大数据集可能会扭曲对图表中所表示内容的感知。由于规范化将较大的数据压缩到较小的数字范围内,只有当最大和最小的数字相距很远时才会成为问题。
两种可能的解决方案:
设置用户可以在数据集中拥有的最大数量。这是一个简单的修复,但它会限制程序的功能 它来自csv文件自动解析数据,因为 超过上限的任何东西都只会发挥最高频率。
第二个解决方案很复杂,我不知道该怎么做,这是我希望从你或某人那里得到的。 我在正确的方向。我认为使用某种对数 缩放以使较大的数据不太重要将是一件好事 解。我的意思是这里的图形如下:
请原谅我糟糕的绘画技巧,但你可以看出我的意思。随着数字变大,它们变得越来越不重要。这不是数字相互作用的方式,但我认为人类对大数字的感知已经很模糊,所以最好让较大的数字听起来比较小的数字更接近。 (例如1和20,000)。
您怎么看?
编辑: 我认为其中一条提到采用数字的基数为10的评论是在正确的轨道上,但是它不适用于较小的数据点,因为数字太靠近了。 IE Log 1为1,log 10为2. 1和2非常接近,您不会听到差异。
答案 0 :(得分:3)
试试这个:
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。