2017-09-03 6 views
-1

私はしばしばプログラムによっていくつかのデータを処理します。単純にすると、データは同じ大きさの一連の数字であると考えてください。 数値が不当に高い場合は、データを正規化すると便利です。一般的な変換の1つは、すべての値から平均を差し引くことです。この変換の後、変換されたデータは平均ゼロを有する。データを正規化しようとすると巨大な数値エラーが発生する

平均が0になった後に実行できるその他の一般的な変換では、データを標準偏差で除算しています。この変換を適用した後、新しいデータには単位分散があります。

このようにデータを正規化すると、数値エラーが小さくなるはずです。しかし、私は標準偏差を計算しようとしているときにも数値エラーが表示されるため、これらの変換を実行できないようです。

ベローは、標準偏差を計算しようとする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は

注場合、そのI Math.Sqrtを省略します(つまり、私は標準偏差ではなく分散を計算します)。誤差はもっと大きくなります。

原因とは何ですか?また、これをより小さな数値エラーでどのように書きますか?

答えて

1

分散に使用する数式は数学的に正しいですが、無限の精度を持つ場合は、有限精度で問題を引き起こす可能性があります。

N個のデータXのためのより良い方法は、これは、データを介して2回のパスを必要と書かれたよう

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

ここ

mean = Sum{ X[i] } /N 

を計算することです。これは厄介な場合は、実際には1回のパスでそれを行うことができます。あなたは3つの変数、n(これまで見たデータ項目の数)の平均と分散を保つ必要があります。これらはすべて0(別名0.0)に初期化する必要があります。あなたは、次のデータ項目X得るとき次に:データ項目nを処理した後の各段階で

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

を、平均、分散を意味し、これまでのデータの分散、実際のカウントです。

+0

素晴らしい答えのためのThx。私は特にあなたが1回のパスでそれをやるのが好きです。私は意味が正しいことを理解しています。しかし、分散の式は私には間違っているようです。次の公式はどうですか?'vaiance =(1.0-f)* variance + f * d * d *(1.0 + f)'それは私にとって理にかなっています。 –

+0

私は公式が正しいと確信しています。最初のデータ項目の後には、f = 1の場合、数式はゼロではない2 * d * dの値をとることはできません.dは最初のデータ値です(平均値は0に初期化されているためです)。しかし1つの物のコレクションの分散は0です。 – dmuir

+0

あなたの反例は正しいです。あなたの数式もそうです。私はあなたの数式でプログラムをコーディングし、期待値を返します。だから私はあなたの答えを受け入れたとマークした。しかし、私はまだそれが動作する理由を見ていない。 –

-1

有効数字の桁数が(15〜16)で、最大/最小値(±5.0×10-324〜±1.7×10308)を混乱させると思います。

あなたの数値計算では、スケーリングの値を1.47834に変換する入力が最初に入力されていないため、数字の浪費が1/10^7であると言います。

+0

スケーリングはここでは何もしません。とにかくFP表現によって行われ、因数分解することができます。 –

関連する問題