Як обчислити дисперсію розділу змінних


15

Я провожу експеримент, де паралельно збираю (незалежні) зразки, обчислюю дисперсію кожної групи зразків і тепер хочу об'єднати потім усі, щоб знайти загальну дисперсію всіх зразків.

Мені важко знайти вихід для цього, оскільки я не впевнений у термінології. Я думаю про це як про розділ одного РВ.

Тому я хочу знайти від , , ... і Var (X_n) , де X = [X_1, X_2, \ точки, X_n] .Var(X)Var(X1)Var(X2)Var(Xn)X[X1,X2,,Xn]

EDIT: Розділи не мають однаковий розмір / кардинальність, але сума розмірів розділів дорівнює кількості вибірок у загальному наборі вибірки.

EDIT 2: Тут є формула паралельного обчислення , але вона охоплює лише випадок поділу на два набори, а не множин.n


Це те саме, що і моє запитання тут: mathoverflow.net/questions/64120/…

Що означає ця остання дужка? А що ви маєте на увазі під загальною дисперсією? Це щось інше, ніж дисперсія комбінованого набору даних?
whuber

@whuber, яка остання дужка? "загальна дисперсія" означає дисперсію загального набору даних.
галамін

Вираз може означати багато речей (хоча умовно це був би вектор): я шукав уточнення. [X1,X2,,Xn]
whuber

Відповіді:


22

Формула досить проста, якщо всі субпроби мають однаковий розмір вибірки. Якщо у вас були -зразки розміром k (для загальної кількості g k зразків), то дисперсія комбінованого зразка залежить від середнього E j та дисперсії V j кожного підпроби: V a r ( X 1 , , X g k ) = k - 1gkgkEjVjде підVar(Ej)означає дисперсію зразка означає.

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

Якщо розміри вибірки не рівні, формула не така приємна.

EDIT: формула для неоднакових розмірів вибірки

Якщо є підрозділів, кожен з яких k j , j = 1 , , g елементів для загальної n = k j значень, то V a r ( X 1 , , X 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

(XjiX¯)2X¯j[(XjiX¯j)(X¯jX¯)]2


Спасибі. На жаль, я не можу гарантувати, що мої розділи однакового розміру. Я запускаю масово паралельний процес, де мені потрібно обчислити відхилення кожної секції паралельно, а потім об'єднати в кінці, але результати / зразки кожного паралельного процесу не рівні (це моделювання Монте-Карло отриманих фотонів).
галамін

3
Я не можу оцінити +1 достатньою, надзвичайно корисною формулою для паралельних обчислень у середовищі сховища даних
Ной Ітер,

1

Це просто доповнення до відповіді аніко з грубим ескізом виведення та деяким кодом 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.
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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.