尝试规范化数据时出现巨大的数字错误

时间:2017-09-03 22:39:25

标签: c# math statistics average numerical-methods

我经常按照数据的程序处理一些数据。为简单起见,让我们考虑数据是一系列相同数量的数字。 当数字不合理地高时,标准化数据可能是有用的。常见变换之一是减去所有值的平均值。在此转换之后,转换后的数据将具有平均值零。

在平均值为零之后可以进行的其他常见变换是将数据除以它们的标准偏差。在应用此转换后,新数据具有单位差异。

当使用这种方式归一化数据时,我希望数值误差应该更小。但是我似乎无法进行这些转换,因为即使在我尝试计算标准偏差时也会出现数值误差。

Bellow是c#中的示例代码,我尝试计算标准偏差。即使没有(公式的)统计知识,程序的输出应为零,也可以很容易地看到它。 (如果数据是常数数组,则数据平方的平均值等于平均值​​的平方。)

static double standardDeviation(double[] data)
{
    double sum = 0;
    double sumOfSquares = 0;
    foreach (double number in data)
    {
        sum += number;
        sumOfSquares += number * number;
    }
    double average = sum / data.Length;
    double averageOfSquares = sumOfSquares / data.Length;
    return Math.Sqrt(averageOfSquares - average * average);
}
static void Main(string[] args)
{
    double bigNumber = 1478340000000;
    double[] data = Enumerable.Repeat(bigNumber, 83283).ToArray();
    Console.WriteLine(standardDeviation(data));
}

而不是零,程序输出由数字错误引起的巨大数字:2133383.0308878

请注意,如果我省略Math.Sqrt(即我会计算方差而不是标准偏差),那么错误会更高。

原因是什么以及如何用更精确的数字错误来写这个?

2 个答案:

答案 0 :(得分:1)

虽然用于方差的公式在数学上是正确的 - 即如果你有无限的精度 - 它可能导致有限精度的麻烦。

N数据X的更好方法是计算

variance = Sum{ square( X[i] - mean) }/ N

,其中

mean = Sum{ X[i] } /N

如上所述,这需要两次通过数据。如果这很尴尬,你实际上可以一次性完成。您需要保留三个变量,n(到目前为止看到的数据项数)均值和方差。这些都应该初始化为0(又名0.0)。然后当你得到下一个数据项x:

n = n + 1
f = 1.0/n
d = x-mean
mean = mean + f*d
variance = (1.0-f)*(variance + f*d*d)

在处理数据项n后的每个阶段,均值,方差确实是到目前为止数据的计数,均值和方差。

答案 1 :(得分:-1)

我认为您将最大/最小数量(±5.0×10-324至±1.7×10308)与可用的有效数字(15 - 16)混淆为双倍。< / p>

在你的情况下,我会说你先浪费数字而不是缩放输入,即将你的值转换为1.47834,比例系数为1/10 ^ 7数值计算。