変数のパーティションの分散を計算する方法


15

(独立した)サンプルを並行して収集する実験を実行しています。サンプルの各グループの分散を計算し、それからすべてを組み合わせて、すべてのサンプルの合計分散を見つけます。

用語がわからないので、これの派生を見つけるのに苦労しています。1つのRVのパーティションと考えています。

だから私は、、...、およびからを見つけたいと思う、ここで =。Var(X)Var(X1)Var(X2)Var(Xn)X[X1,X2,,Xn]

編集:パーティションは同じサイズ/カーディナリティではありませんが、パーティションサイズの合計はサンプルセット全体のサンプル数に等しくなります。

編集2:ここ並列計算のための式がありますが、それはセットではなく、2セットへのパーティションの場合のみをカバーしています。n


これは、ここで私の質問と同じです:mathoverflow.net/questions/64120/...

最後の括弧はどういう意味ですか?そして、「総分散」とはどういう意味ですか?結合されたデータセットの分散以外のものですか?
whuber

@whuber最後の括弧は?「総分散」とは、総データセットの分散を意味します。
ガラミン

という表現[X1,X2,,Xn]は、多くのことを意味する可能性があります(従来はベクトルですが)。説明を探していました。
whuber

回答:


22

すべてのサブサンプルのサンプルサイズが同じである場合、式は非常に簡単です。サイズサブサンプルが(合計サンプル)、結合サンプルの分散は、各サブサンプルの平均および分散に依存します: ここでは、サンプル平均の分散を意味します。gkgkEjVjVarEj

Var(X1,,Xgk)=k1gk1(j=1gVj+k(g1)k1Var(Ej)),
Var(Ej)

Rでのデモ:

> x <- rnorm(100)
> g <- gl(10,10)
> mns <- tapply(x, g, mean)
> vs <- tapply(x, g, var)
> 9/99*(sum(vs) + 10*var(mns))
[1] 1.033749
> var(x)
[1] 1.033749

サンプルサイズが等しくない場合、式はあまり良くありません。

編集:等しくないサンプルサイズの式

サブサンプルが個あり、それぞれがk jj = 1 g要素で合計n = k j値の場合、 V a r X 1X n= 1gkj,j=1,,gn=kj ˉ X =Σの G J = 1つの KJ ˉ X j/nは、すべての平均の加重平均です(すべての値の平均に等しい)。

Var(X1,,Xn)=1n1(j=1g(kj1)Vj+j=1gkj(X¯jX¯)2),
X¯=(j=1gkjX¯j)/n

繰り返しますが、デモ:

> k <- rpois(10, lambda=10)
> n <- sum(k)
> g <- factor(rep(1:10, k))
> x <- rnorm(n)
> mns <- tapply(x, g, mean)
> vs <- tapply(x, g, var)
> 1/(n-1)*(sum((k-1)*vs) + sum(k*(mns-weighted.mean(mns,k))^2))
[1] 1.108966
> var(x)
[1] 1.108966

ところで、これらの式は、スケーリングされた和として所望の分散を書き込むことによって導出することが容易である、次いで導入ˉ X J[ X J I - ˉ X J- ˉ X J - ˉ X] 2、差分式の平方を用いて、そして単純化。(XjiX¯)2X¯j[(XjiX¯j)(X¯jX¯)]2


ありがとう。残念ながら、パーティションがすべて同じサイズであることを保証することはできません。私は各パーティションの分散を並列で計算し、最終的に結合する必要がある超並列プロセスを実行していますが、各並列プロセスの結果/サンプルは等しくありません(受信光子のモンテカルロシミュレーションです)。
ガラミン

3
データウェアハウス環境での並列計算にこれほど十分な、非常に役立つ公式を+1することはできません
ノアYetter

1

これは、aniko答えの単なるアドオンであり、派生の大まかなスケッチといくつかのpythonコードがあるため、すべてのクレジットはanikoに渡されます。

導出

XjX={X1,X2,,Xg}gkj=|Xj|

Ej=E[Xj]=1kji=1kjXjiVj=Var[Xj]=1kj1i=1kj(XjiEj)2
n=j=1gkj
Var[X]=1n1j=1gi=1kj(XjiE[X])2=1n1j=1gi=1kj((XjiEj)(E[X]Ej))2=1n1j=1gi=1kj(XjiEj)22(XjiEj)(E[X]Ej)+(E[X]Ej)2=1n1j=1g(kj1)Vj+kj(E[X]Ej)2.
kj:kj=k
Var[X]=1n1j=1g(k1)Vj+k(g1)Var[Ej]=k1n1j=1gVj+k(g1)k1Var[Ej]

Pythonコード

次のpython関数は、最初の次元に沿って分割された配列に対して機能し、異なるサイズのパーツに対して「より複雑な」式を実装します。

import numpy as np

def combine(averages, variances, counts, size=None):
    """
    Combine averages and variances to one single average and variance.

    # Arguments
        averages: List of averages for each part.
        variances: List of variances for each part.
        counts: List of number of elements in each part.
        size: Total number of elements in all of the parts.
    # Returns
        average: Average over all parts.
        variance: Variance over all parts.
    """
    average = np.average(averages, weights=counts)

    # necessary for correct variance in case of multidimensional arrays
    if size is not None:
        counts = counts * size // np.sum(counts, dtype='int')

    squares = (counts - 1) * variances + counts * (averages - average)**2
    return average, np.sum(squares) / (size - 1)

次のように使用できます。

# sizes k_j and n
ks = np.random.poisson(10, 10)
n = np.sum(ks)

# create data
x = np.random.randn(n, 20)
parts = np.split(x, np.cumsum(ks[:-1]))

# compute statistics on parts
ms = [np.mean(p) for p in parts]
vs = [np.var(p, ddof=1) for p in parts]

# combine and compare
combined = combine(ms, vs, ks, x.size)
numpied = np.mean(x), np.var(x, ddof=1)
distance = np.abs(np.array(combined) - np.array(numpied))
print('combined --- mean:{: .9f} - var:{: .9f}'.format(*combined))
print('numpied  --- mean:{: .9f} - var:{: .9f}'.format(*numpied))
print('distance --- mean:{: .5e} - var:{: .5e}'.format(*distance))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.