データセットの変更後の古い標準偏差を使用した新しい標準偏差の計算


16

平均と標準偏差を持つ実数値の配列があります。配列要素が別の要素置き換えられた場合、新しい平均はnμoldσoldxixj

μnew=μold+xjxin

このアプローチの利点は、の値に関係なく一定の計算が必要になることです。を使用した計算のように、を使用してを計算する方法はありますか?nσnewσoldμnewμold


これは宿題ですか?非常によく似たタスクが数理統計学のコースで求められました
...-krlmlr

2
@ user946850:いいえ、宿題ではありません。私は進化的アルゴリズムに関する論文を行っています。人口の多様性の尺度として標準偏差を使用します。より効率的なソリューションを探しています。
ユーザー

1
SDは分散の平方根であり、これは単なる平均平方値です(平方平均の倍数で調整されます。これは既に更新方法を知っています)。したがって、ランニング平均を計算するために使用されるのと同じ方法は、ランニング分散を計算するために根本的な変更なしで適用できます。 実際、同じアイデアを使用して、はるかに洗練された統計をオンラインで計算できます。たとえば、stats.stackexchange.com / questions / 6920およびstats.stackexchange.com/questions/23481のスレッドを参照してください。
whuber

1
@whuber:これは、WikipediaのVarianceの記事で言及されいますが、発生する可能性のある壊滅的なキャンセル(または重要性の喪失)についても注記しています。これは過大評価ですか、それとも実際の分散の問題ですか?
krlmlr

それは素晴らしい質問です。事前にセンタリングせずに単純に分散を累積すると、実際に問題が発生する可能性があります。この問題は、数値が大きいが、分散が小さい場合に発生します。たとえば、299792458.145、299792457.883、299792457.998のように、光速度の一連の正確な測定値をm / sで考えてみましょう:約0.01の分散は、約平方に比べて非常に小さい17、その不注意な計算は(倍精度であっても)分散がゼロになります:すべての有効数字が消えます。1017
whuber

回答:


7

「分散計算するためのアルゴリズム」のWikipediaの記事のセクションの要素は、あなたの観測に追加された場合は分散を計算する方法を示しています。(標準偏差は分散の平方根であることを思い出してください。)を配列に追加してから、xn+1

σnew2=σold2+(xn+1μnew)(xn+1μold).

編集:上記の式は間違っているようです、コメントを参照してください。

現在、要素を置き換えるとは、観測値を追加して別の観測値を削除することを意味します。両方とも上記の式で計算できます。ただし、数値の安定性の問題が発生する可能性があることに注意してください。引用された記事は、数値的に安定したバリアントも提案しています。

、自分で式を導き出す計算するためにサンプル分散及び代替の定義を使用してμをN E wは、あなたが適切な場合が得られた式。これは、得られるσ 2 N E W - σ 2 O のL Dを端に、そしてためしたがって式σ N E W所与σ oをLとD(n1)(σnew2σold2)μnewσnew2σold2σnewσold。私の表記では、要素 x n x nで置き換えると仮定します。μoldxnxn

σ2=(n1)1k(xkμ)2(n1)(σnew2σold2)=k=1n1((xkμnew)2(xkμold)2)+ ((xnμnew)2(xnμold)2)=k=1n1((xkμoldn1(xnxn))2(xkμold)2)+ ((xnμoldn1(xnxn))2(xnμold)2)

総和ではの依存何かに変身μ O L Dが、あなたはきちんとした結果を導き出すためにもう少し方程式を作業する必要があります。これにより、一般的なアイデアが得られます。xkμold


あなたが与えた最初の式が正しいいないようだ、よくその場合は、ことを意味し任意の意味をなさない新旧両方の平均、分散は常に増加から、その後、小さい/大きいです。分布に応じて増減します。xn+1
エメットB

@EmmetB:はい、している権利-これはおそらくあるべき 残念ながら、これはそこからの私の議論全体を無効にしますが、歴史的な目的のためにそれを残しています。ただし、自由に編集してください。σnew2=n1nσold2+1n(xn+1μnew)(xn+1μold).
krlmlr

4

リンクされたウィキペディアの記事を読んでいる思うものに基づいて、「実行中の」標準偏差を維持できます。

real sum = 0;
int count = 0;
real S = 0;
real variance = 0;

real GetRunningStandardDeviation(ref sum, ref count, ref S, x)
{
   real oldMean;

   if (count >= 1)
   {
       real oldMean = sum / count;
       sum = sum + x;
       count = count + 1;
       real newMean = sum / count;

       S = S + (x-oldMean)*(x-newMean)
   }
   else
   {
       sum = x;
       count = 1;
       S = 0;         
   }

   //estimated Variance = (S / (k-1) )
   //estimated Standard Deviation = sqrt(variance)
   if (count > 1)
      return sqrt(S / (count-1) );
   else
      return 0;
}

記事では彼らは別々のランニングsumとを維持しませんcountが、代わりにシングルを持っていmeanます。私が今日やっていることでは、count(統計的な目的で)を維持しているため、毎回平均を計算する方が便利です。


0

x¯snxnxns

s2+1n1(2nΔx¯(xnx¯)+n(n1)(Δx¯)2),
Δx¯=x¯x¯x¯

たぶん、おしゃれな書き方がありますか?

私はこれを小さなテストケースに対してチェックしましたが、うまくいくように見えました。


1
@john /暗闇の中で口tlingを吹く:私はあなたの答えが好きでした、それは私の小さなデータセットで適切に動作するようです。数学的な基礎/参照はありますか?親切に手伝ってもらえますか?
アロクチョードリー

質問はすべて@Whistling in the Darkで、サイト用に整理しました。ここで質問と回答を参照する新しい質問を提示する必要があります。また、そのように感じた場合は、この答えに賛成するべきです。
ジョン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.