วิธีการคำนวณความแปรปรวนของพาร์ติชันของตัวแปร


15

ฉันกำลังทำการทดลองที่ฉันรวบรวมตัวอย่าง (อิสระ) แบบขนานฉันคำนวณความแปรปรวนของกลุ่มตัวอย่างแต่ละกลุ่มและตอนนี้ฉันต้องการรวมแล้วทั้งหมดเพื่อค้นหาความแปรปรวนรวมของตัวอย่างทั้งหมด

ฉันมีเวลายากที่จะหาที่มาของเรื่องนี้เพราะฉันไม่แน่ใจว่าคำศัพท์ ฉันคิดว่ามันเป็นพาร์ติชันของ RV หนึ่งอัน

ดังนั้นฉันต้องการหาVar(X)จากVar(X1) , Var(X2) , ... , และVar(Xn)โดยที่X = [X1,X2,,Xn] ]

แก้ไข: พาร์ทิชันไม่ได้มีขนาด / cardinality เดียวกัน แต่ผลรวมของขนาดพาร์ทิชันเท่ากับจำนวนตัวอย่างในชุดตัวอย่างโดยรวม

แก้ไข 2: มีสูตรสำหรับการคำนวณแบบขนานที่นี่แต่ครอบคลุมเฉพาะกรณีของพาร์ติชันเป็นสองชุดไม่ใช่ชุดn


นี่เป็นคำถามเดียวกับฉันที่นี่: mathoverflow.net/questions/64120/…

วงเล็บสุดท้ายหมายความว่าอะไร และคุณหมายถึงอะไรโดย "ความแปรปรวนรวม"? มันเป็นอะไรนอกเหนือจากความแปรปรวนของชุดข้อมูลรวม?
whuber

@ เมื่อไหร่วงเล็บสุดท้าย? "ผลต่างทั้งหมด" หมายถึงความแปรปรวนของชุดข้อมูลทั้งหมด
gallamine

การแสดงออกอาจหมายถึงหลายสิ่งหลายอย่าง (แม้ว่าโดยทั่วไปแล้วมันจะเป็นเวกเตอร์): ฉันกำลังมองหาการชี้แจง [X1,X2,,Xn]
whuber

คำตอบ:


22

สูตรนั้นค่อนข้างตรงไปตรงมาหากตัวอย่างย่อยทั้งหมดมีขนาดตัวอย่างเท่ากัน หากคุณมีตัวอย่างย่อยของขนาดk (สำหรับตัวอย่างทั้งหมดg k ) ความแปรปรวนของตัวอย่างรวมขึ้นอยู่กับค่าเฉลี่ยE jและความแปรปรวนV jของแต่ละตัวอย่างย่อย: V a r ( X 1 , , X g k ) = k - 1gkgkEjVjโดยที่VR(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

หากขนาดตัวอย่างไม่เท่ากันสูตรจะไม่ดี

แก้ไข: สูตรสำหรับขนาดตัวอย่างที่ไม่เท่ากัน

หากมีตัวอย่างย่อยแต่ละชิ้นมีk j , j = 1 , ,องค์ประกอบgสำหรับผลรวมของn = k jค่าจากนั้น V a r (gkj,j=1,,gn=kj ที่ ˉ X =( g j = 1 k

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


ขอบคุณ น่าเสียดายที่ฉันไม่สามารถรับประกันได้ว่าพาร์ติชันของฉันจะมีขนาดเท่ากันทั้งหมด ฉันใช้กระบวนการแบบขนานอย่างหนาแน่นที่ฉันต้องการคำนวณความแปรปรวนของแต่ละพาร์ติชันแบบขนานแล้วรวมกันในตอนท้าย แต่ผลลัพธ์ / ตัวอย่างจากกระบวนการแบบขนานแต่ละอันไม่เท่ากัน (เป็นแบบจำลองมอนติคาร์โลของโฟตอนที่ได้รับ)
gallamine

3
ฉันไม่สามารถ +1 สูตรที่มีประโยชน์และยอดเยี่ยมที่สุดสำหรับการคำนวณแบบขนานในสภาพแวดล้อมคลังข้อมูล
Noah Yetter

1

นี่เป็นเพียงส่วนเสริมของคำตอบของ aniko ที่มีภาพร่างคร่าวๆของรหัสต้นฉบับและรหัสไพ ธ อนบางส่วนดังนั้นเครดิตทั้งหมดไปที่ aniko

รากศัพท์

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

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))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.