So berechnen Sie die Varianz einer Variablenpartition


15

Ich führe ein Experiment durch, bei dem ich (unabhängige) Samples parallel sammle, ich berechne die Varianz jeder Gruppe von Samples und jetzt möchte ich dann alle kombinieren, um die Gesamtvarianz aller Samples zu finden.

Es fällt mir schwer, eine Ableitung dafür zu finden, da ich mir der Terminologie nicht sicher bin. Ich betrachte es als eine Unterteilung eines Wohnmobils.

Ich möchte also Veinr(X) aus , , ... und , wobei = [ X 1 , X 2 , ... , X n ] .V a r ( X 2 ) V a r ( X n ) XVeinr(X1)Veinr(X2)Veinr(Xn)X[X1,X2,,Xn]

EDIT: Die Partitionen haben nicht dieselbe Größe / Kardinalität, aber die Summe der Partitionsgrößen entspricht der Anzahl der Samples im gesamten Sampleset.

EDIT 2: Es gibt hier eine Formel für eine parallele Berechnung , die jedoch nur den Fall einer Partition in zwei Mengen abdeckt, nicht in Mengen.n



Was bedeutet diese letzte Klammer? Und was meinst du mit "total varianz"? Ist es etwas anderes als die Varianz des kombinierten Datensatzes?
whuber

@whuber welche letzte Klammer? "Gesamtvarianz" bedeutet die Varianz des Gesamtdatensatzes.
Gallamine

Der Ausdruck könnte viele Dinge bedeuten (obwohl es sich herkömmlicherweise um einen Vektor handelt): Ich habe nach einer Klarstellung gesucht. [X1,X2,,Xn]
whuber

Antworten:


22

Die Formel ist ziemlich einfach, wenn alle Teilstichproben dieselbe Stichprobengröße haben. Wenn Sie haben Unterproben der Größe k (für eine Gesamtzahl von g k Proben), dann hängt die Varianz der kombinierten Probe auf dem Mittelwert E j und die Varianz V j jede Teilprobe: V einen R ( X 1 , , X g k ) = k - 1gkgkEjVjwobei durchVar(Ej)die Varianz der Probenmittel Mittel.

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

Eine Demonstration in 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

Wenn die Stichprobengrößen nicht gleich sind, ist die Formel nicht so schön.

EDIT: Formel für ungleiche Stichprobengrößen

gkj,j=1,,gn=kj

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

Wieder eine Demonstration:

> 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

(XjiX¯)2X¯j[(Xjich-X¯j)-(X¯j-X¯)]2unter Verwendung der Quadrat-Differenz-Formel und Vereinfachung.


Vielen Dank. Leider kann ich nicht garantieren, dass meine Partitionen alle gleich groß sind. Ich führe einen massiv parallelen Prozess aus, bei dem ich die Varianzen jeder Partition parallel berechnen und dann am Ende kombinieren muss, aber die Ergebnisse / Stichproben von jedem parallelen Prozess sind nicht gleich (es ist eine Monte-Carlo-Simulation empfangener Photonen).
Gallamine

3
Ich kann diese sehr hilfreiche Formel für die parallele Berechnung in einer Data-Warehouse-Umgebung nicht genug +1
Noah Yetter

1

Dies ist einfach ein Add-On zur Antwort von aniko mit einer groben Skizze der Ableitung und etwas Python-Code, sodass alle Credits an aniko gehen.

Ableitung

Lassen XjX={X1,X2,,Xg} be one of g parts of the data where the number of elements in each part is kj=|Xj|. We define the mean and the variance of each part to be

Ej=E[Xj]=1kji=1kjXjiVj=Var[Xj]=1kj1i=1kj(XjiEj)2
respectively. If we set n=j=1gkj, the variance of the total dataset is given by:
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.
If we have the same size k for each part, i.e. j:kj=k, above formula simplifies to
Var[X]=1n1j=1g(k1)Vj+k(g1)Var[Ej]=k1n1j=1gVj+k(g1)k1Var[Ej]

python code

The following python function works for arrays that have been splitted along the first dimension and implements the "more complex" formula for differently sized parts.

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)

It can be used as follows:

# 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))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.