2017-09-03 60 views
-1

我经常通过数据处理某些数据。为了简单起见,让我们考虑一下数据是一系列相同数量的数字。 当数字不合理时,标准化数据可能会有用。常见的转换之一是减去所有值的平均值。在这个转换之后,转换的数据将具有平均零。尝试规范化数据时出现巨大数值错误

零均值后可以完成的其他常见转换是将数据除以它们的标准偏差。应用此转换后,新数据有单位差异。

当以这种方式对数据进行归一化处理时,我期望数值误差应该更小。但是,我似乎无法做这些转换,因为即使我正在计算标准偏差,也会出现数字错误。

波纹管是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(即我会计算方差而不是标准偏差),那么错误会更高。

原因是什么,如何用smaler数字错误书写这个问题?

回答

1

尽管用于方差的公式在数学上是正确的 - 也就是说,如果您具有无限精度,则可能导致精度有限。

为N个数据X A更好的方式是计算

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,之后每个阶段,均值,方差的确计数,平均值和数据的变化为止。

+0

Thx为伟大的答案。我特别喜欢你一次传球的方式。我明白这个意思是正确的。然而,对于我来说,方差似乎是错误的。以下公式如何?'vaiance =(1.0-f)*方差+ f * d * d *(1.0 + f)'这对我来说会更有意义。 –

+0

我很确定我的公式是正确的。当f = 1时,您的公式不能用于第一个数据项,当f = 1时,公式给出非零值,2 * d * d其中d是第一个数据值(因为均值初始化为0)。但是1件东西的差异是0 – dmuir

+0

你的反例是正确的。你的公式也是如此。我用你的公式编写了程序,并返回期望值。所以我标记你的答案已被接受。但是我仍然不明白它为什么会起作用。 –

-1

我认为你最大/最小可能数(±5.0×10-324到±1.7×10308)与有效数字(15 - 16)有双倍数。

就你而言,我认为你是在浪费数字而不是缩放首先输入,即将你的值转换为1.47834,比例因子为1/10^7你的数字计算。

+0

缩放无关于此。无论如何由FP表示完成并且可以分解或不分解。 –

相关问题