如何使用对数刻度来倾斜归一化?
How to skew normalization using a logarithmic scale?
我正在开发一个程序,该程序从图表中读取数据并以特定频率播放值,该频率已被归一化以显示数据点之间的差异。
在测试中,我发现 "acceptable" 声音范围介于 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 靠得很近,你听不出有什么不同。
试试这个:
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。
我正在开发一个程序,该程序从图表中读取数据并以特定频率播放值,该频率已被归一化以显示数据点之间的差异。
在测试中,我发现 "acceptable" 声音范围介于 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 靠得很近,你听不出有什么不同。
试试这个:
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。