Algorithmen zur Berechnung der Varianz - Algorithms for calculating variance

Algorithmen zur Berechnung der Varianz spielen in der Computerstatistik eine große Rolle . Eine Hauptschwierigkeit beim Entwurf guter Algorithmen für dieses Problem besteht darin, dass Formeln für die Varianz Quadratsummen enthalten können, was zu numerischer Instabilität sowie zu arithmetischem Überlauf bei großen Werten führen kann.

Naiver Algorithmus

Eine Formel zur Berechnung der Varianz einer Gesamtpopulation der Größe N lautet:

Unter Verwendung der Bessel-Korrektur zur Berechnung einer unverzerrten Schätzung der Populationsvarianz aus einer endlichen Stichprobe von n Beobachtungen lautet die Formel:

Daher ist ein naiver Algorithmus zur Berechnung der geschätzten Varianz wie folgt gegeben:

  • Sei n ← 0, Summe ← 0, SumSq ← 0
  • Für jedes Datum x :
    • nn + 1
    • Summe ← Summe + x
    • SummeQuadrat ← SummeQuadrat + x × x
  • Var = (SumSq − (Summe × Sum) / n) / (n − 1)

Dieser Algorithmus kann leicht angepasst werden, um die Varianz einer endlichen Population zu berechnen: einfach durch N statt n  − 1 in der letzten Zeile dividieren .

Da SumSq und (Sum×Sum)/ n sehr ähnliche Zahlen sein können, kann die Aufhebung dazu führen, dass die Genauigkeit des Ergebnisses viel geringer ist als die inhärente Genauigkeit der zur Durchführung der Berechnung verwendeten Gleitkommaarithmetik . Daher sollte dieser Algorithmus in der Praxis nicht verwendet werden, und es wurden mehrere alternative, numerisch stabile Algorithmen vorgeschlagen. Dies ist besonders schlimm, wenn die Standardabweichung relativ zum Mittelwert klein ist.

Berechnen von verschobenen Daten

Die Varianz ist invariant in Bezug auf Änderungen eines Standortparameters , eine Eigenschaft, die verwendet werden kann, um die katastrophale Auslöschung in dieser Formel zu vermeiden.

mit beliebiger Konstante, was zu der neuen Formel führt

je näher der Mittelwert ist, desto genauer ist das Ergebnis, aber nur die Auswahl eines Wertes innerhalb des Probenbereichs garantiert die gewünschte Stabilität. Wenn die Werte klein sind, gibt es keine Probleme mit der Summe ihrer Quadrate, im Gegenteil, wenn sie groß sind, bedeutet dies zwangsläufig, dass auch die Varianz groß ist. In jedem Fall ist der zweite Term in der Formel immer kleiner als der erste, daher kann keine Aufhebung erfolgen.

Wenn nur das erste Beispiel genommen wird, kann der Algorithmus in der Programmiersprache Python geschrieben werden als

def shifted_data_variance(data):
    if len(data) < 2:
        return 0.0
    K = data[0]
    n = Ex = Ex2 = 0.0
    for x in data:
        n = n + 1
        Ex += x - K
        Ex2 += (x - K) * (x - K)
    variance = (Ex2 - (Ex * Ex) / n) / (n - 1)
    # use n instead of (n-1) if want to compute the exact variance of the given data
    # use (n-1) if data are samples of a larger population
    return variance

Diese Formel erleichtert auch die inkrementelle Berechnung, die ausgedrückt werden kann als

K = n = Ex = Ex2 = 0.0

def add_variable(x):
    global K, n, Ex, Ex2
    if n == 0:
        K = x
    n += 1
    Ex += x - K
    Ex2 += (x - K) * (x - K)

def remove_variable(x):
    global K, n, Ex, Ex2
    n -= 1
    Ex -= x - K
    Ex2 -= (x - K) * (x - K)

def get_mean():
    global K, n, Ex
    return K + Ex / n

def get_variance():
    global n, Ex, Ex2
    return (Ex2 - (Ex * Ex) / n) / (n - 1)

Zwei-Pass-Algorithmus

Ein alternativer Ansatz, der eine andere Formel für die Varianz verwendet, berechnet zuerst den Stichprobenmittelwert,

und berechnet dann die Summe der Quadrate der Differenzen vom Mittelwert,

wobei s die Standardabweichung ist. Dies ist durch den folgenden Code gegeben:

def two_pass_variance(data):
    n = sum1 = sum2 = 0

    for x in data:
        n += 1
        sum1 += x

    mean = sum1 / n

    for x in data:
        sum2 += (x - mean) * (x - mean)

    variance = sum2 / (n - 1)
    return variance

Dieser Algorithmus ist numerisch stabil, wenn n klein ist. Die Ergebnisse dieser beiden einfachen Algorithmen ("naiv" und "two-pass") können jedoch übermäßig von der Reihenfolge der Daten abhängen und können bei sehr großen Datensätzen aufgrund wiederholter Rundungsfehler bei der Akkumulation der Summen. Techniken wie kompensierte Summation können verwendet werden, um diesen Fehler bis zu einem gewissen Grad zu bekämpfen.

Welfords Online-Algorithmus

Es ist oft nützlich, die Varianz in einem einzigen Durchgang berechnen zu können, indem jeder Wert nur einmal überprüft wird; zum Beispiel, wenn die Daten ohne genügend Speicherplatz gesammelt werden, um alle Werte zu behalten, oder wenn die Kosten für den Speicherzugriff die der Berechnung überwiegen. Für einen solchen Online-Algorithmus ist eine Rekursionsbeziehung zwischen Größen erforderlich, aus der die erforderliche Statistik numerisch stabil berechnet werden kann.

Die folgenden Formeln können verwendet werden, um den Mittelwert und die (geschätzte) Varianz der Sequenz für ein zusätzliches Element x n zu aktualisieren . Hier bezeichnet die Probe Mittelwert der ersten n Proben , deren vorgespannte Stichprobenvarianz , und ihre unvoreingenommenen Stichprobenvarianz .

Diese Formeln leiden unter numerischer Instabilität, da sie wiederholt eine kleine Zahl von einer großen Zahl subtrahieren, die mit n skaliert . Eine bessere Größe für die Aktualisierung ist die Summe der Quadrate der Differenzen vom aktuellen Mittelwert , hier bezeichnet :

Dieser Algorithmus wurde von Welford gefunden und gründlich analysiert. Es ist auch üblich, und zu bezeichnen .

Eine beispielhafte Python-Implementierung für den Welford-Algorithmus ist unten angegeben.

# For a new value newValue, compute the new count, new mean, the new M2.
# mean accumulates the mean of the entire dataset
# M2 aggregates the squared distance from the mean
# count aggregates the number of samples seen so far
def update(existingAggregate, newValue):
    (count, mean, M2) = existingAggregate
    count += 1
    delta = newValue - mean
    mean += delta / count
    delta2 = newValue - mean
    M2 += delta * delta2
    return (count, mean, M2)

# Retrieve the mean, variance and sample variance from an aggregate
def finalize(existingAggregate):
    (count, mean, M2) = existingAggregate
    if count < 2:
        return float("nan")
    else:
        (mean, variance, sampleVariance) = (mean, M2 / count, M2 / (count - 1))
        return (mean, variance, sampleVariance)

Dieser Algorithmus ist viel weniger anfällig für Präzisionsverluste aufgrund einer katastrophalen Aufhebung , ist jedoch möglicherweise aufgrund der Divisionsoperation innerhalb der Schleife nicht so effizient. Für einen besonders robusten Zweidurchgangsalgorithmus zur Berechnung der Varianz kann man zuerst eine Schätzung des Mittelwerts berechnen und subtrahieren und dann diesen Algorithmus auf die Residuen anwenden.

Der folgende parallele Algorithmus veranschaulicht, wie mehrere online berechnete Statistiken zusammengeführt werden.

Gewichteter inkrementeller Algorithmus

Der Algorithmus kann erweitert werden, um ungleiche Stichprobengewichte zu handhaben, indem der einfache Zähler n durch die Summe der bisher gesehenen Gewichte ersetzt wird. West (1979) schlägt diesen inkrementellen Algorithmus vor :

def weighted_incremental_variance(data_weight_pairs):
    w_sum = w_sum2 = mean = S = 0

    for x, w in data_weight_pairs:
        w_sum = w_sum + w
        w_sum2 = w_sum2 + w * w
        mean_old = mean
        mean = mean_old + (w / w_sum) * (x - mean_old)
        S = S + w * (x - mean_old) * (x - mean)

    population_variance = S / w_sum
    # Bessel's correction for weighted samples
    # Frequency weights
    sample_frequency_variance = S / (w_sum - 1)
    # Reliability weights
    sample_reliability_variance = S / (w_sum - w_sum2 / w_sum)

Paralleler Algorithmus

Chanet al. Beachten Sie, dass der oben beschriebene Online-Algorithmus von Welford ein Sonderfall eines Algorithmus ist, der zum Kombinieren beliebiger Mengen und funktioniert :

.

Dies kann nützlich sein, wenn beispielsweise diskreten Teilen der Eingabe mehrere Verarbeitungseinheiten zugewiesen werden können.

Chans Methode zur Schätzung des Mittelwerts ist numerisch instabil, wenn und beide groß sind, da der numerische Fehler in nicht so verkleinert wird, wie es im Fall der Fall ist. In solchen Fällen bevorzugen Sie .

def parallel_variance(n_a, avg_a, M2_a, n_b, avg_b, M2_b):
    n = n_a + n_b
    delta = avg_b - avg_a
    M2 = M2_a + M2_b + delta ** 2 * n_a * n_b / n
    var_ab = M2 / (n - 1)
    return var_ab

Dies kann verallgemeinert werden, um Parallelisierung mit AVX , mit GPUs und Computerclustern und Kovarianz zu ermöglichen.

Beispiel

Angenommen, alle Gleitkommaoperationen verwenden die Standard- IEEE 754- Arithmetik mit doppelter Genauigkeit . Betrachten Sie die Stichprobe (4, 7, 13, 16) aus einer unendlichen Grundgesamtheit. Basierend auf dieser Stichprobe beträgt der geschätzte Populationsmittelwert 10 und die unverzerrte Schätzung der Populationsvarianz 30. Sowohl der naive Algorithmus als auch der Two-Pass-Algorithmus berechnen diese Werte korrekt.

Betrachten Sie als nächstes die Stichprobe ( 10 8  + 4 , 10 8  + 7 , 10 8  + 13 , 10 8  + 16 ), die dieselbe geschätzte Varianz wie die erste Stichprobe ergibt. Der Algorithmus mit zwei Durchläufen berechnet diese Varianzschätzung korrekt, aber der naive Algorithmus gibt 29.33333333333332 statt 30 zurück.

Während dieser Genauigkeitsverlust tolerierbar und als kleiner Fehler des naiven Algorithmus angesehen werden kann, macht eine weitere Erhöhung des Offsets den Fehler katastrophal. Betrachten Sie die Stichprobe ( 10 9  + 4 , 10 9  + 7 , 10 9  + 13 , 10 9  + 16 ). Auch hier wird die geschätzte Populationsvarianz von 30 vom Two-Pass-Algorithmus korrekt berechnet, aber der naive Algorithmus berechnet sie jetzt als −170,66666666666666. Dies ist ein ernstes Problem bei naiven Algorithmen und ist auf eine katastrophale Aufhebung bei der Subtraktion zweier ähnlicher Zahlen in der Endstufe des Algorithmus zurückzuführen.

Statistik höherer Ordnung

Terriberry erweitert Chans Formeln auf die Berechnung des dritten und vierten zentralen Moments , die zum Beispiel bei der Schätzung von Schiefe und Kurtosis benötigt werden :

Hier sind wieder die Summen der Potenzen der Differenzen vom Mittelwert , die ergeben

Für den inkrementellen Fall (dh ) vereinfacht sich dies zu:

Durch Beibehalten des Wertes wird nur eine Divisionsoperation benötigt und die Statistik höherer Ordnung kann somit mit geringen zusätzlichen Kosten berechnet werden.

Ein Beispiel für den wie beschrieben implementierten Online-Algorithmus für Kurtosis ist:

def online_kurtosis(data):
    n = mean = M2 = M3 = M4 = 0

    for x in data:
        n1 = n
        n = n + 1
        delta = x - mean
        delta_n = delta / n
        delta_n2 = delta_n * delta_n
        term1 = delta * delta_n * n1
        mean = mean + delta_n
        M4 = M4 + term1 * delta_n2 * (n*n - 3*n + 3) + 6 * delta_n2 * M2 - 4 * delta_n * M3
        M3 = M3 + term1 * delta_n * (n - 2) - 3 * delta_n * M2
        M2 = M2 + term1

    # Note, you may also calculate variance using M2, and skewness using M3
    # Caution: If all the inputs are the same, M2 will be 0, resulting in a division by 0.
    kurtosis = (n * M4) / (M2 * M2) - 3
    return kurtosis

Pébaÿ erweitert diese Ergebnisse weiter auf Zentralmomente beliebiger Ordnung für den inkrementellen und den paarweisen Fall, und anschließend Pébaÿ et al. für gewichtete und zusammengesetzte Momente. Dort findet man auch ähnliche Formeln für die Kovarianz .

Choi und Sweetman bieten zwei alternative Methoden zum Berechnen der Schiefe und Kurtosis an, von denen jede in bestimmten Anwendungen erheblichen Computerspeicherbedarf und CPU-Zeit einsparen kann. Der erste Ansatz besteht darin, die statistischen Momente zu berechnen, indem die Daten in Bins aufgeteilt werden und dann die Momente aus der Geometrie des resultierenden Histogramms berechnet werden , was effektiv zu einem Algorithmus mit einem Durchgang für höhere Momente wird. Ein Vorteil besteht darin, dass die Berechnungen des statistischen Moments mit beliebiger Genauigkeit durchgeführt werden können, so dass die Berechnungen auf die Genauigkeit beispielsweise des Datenspeicherformats oder der ursprünglichen Messhardware abgestimmt werden können. Ein relatives Histogramm einer Zufallsvariable kann auf herkömmliche Weise konstruiert werden: Der Bereich potenzieller Werte wird in Bins unterteilt und die Anzahl der Vorkommen innerhalb jeder Bin wird gezählt und so aufgetragen, dass die Fläche jedes Rechtecks ​​dem Anteil der Sample-Werte entspricht in diesem Behälter:

wobei und die Häufigkeit und die relative Häufigkeit bei bin darstellen und die Gesamtfläche des Histogramms ist. Nach dieser Normierung können aus dem relativen Histogramm die Rohmomente und Zentralmomente von berechnet werden:

wobei der hochgestellte Index angibt, dass die Momente aus dem Histogramm berechnet werden. Für eine konstante Bin-Breite können diese beiden Ausdrücke mit vereinfacht werden :

Der zweite Ansatz von Choi und Sweetman ist eine analytische Methodik, um statistische Momente aus einzelnen Segmenten einer Zeitgeschichte so zu kombinieren, dass die resultierenden Gesamtmomente die der gesamten Zeitgeschichte sind. Diese Methodik könnte für die parallele Berechnung statistischer Momente mit anschließender Kombination dieser Momente oder für die Kombination von statistischen Momenten, die zu sequentiellen Zeiten berechnet werden, verwendet werden.

Wenn Sätze von statistischen Momenten bekannt sind: für , dann kann jeder durch die äquivalenten Rohmomente ausgedrückt werden :

wobei im Allgemeinen die Dauer des Zeitverlaufs oder die Anzahl der Punkte, wenn konstant ist, angenommen wird.

Der Vorteil, die statistischen Momente in Form von auszudrücken, besteht darin, dass die Sätze durch Addition kombiniert werden können und es keine Obergrenze für den Wert von gibt .

wobei der Index den verketteten Zeitverlauf oder kombinierte . Diese kombinierten Werte von können dann umgekehrt in Rohmomente umgewandelt werden, die die vollständige verkettete Zeitgeschichte darstellen

Bekannte Beziehungen zwischen den Rohmomenten ( ) und den Zentralmomenten ( ) werden dann verwendet, um die Zentralmomente des verketteten Zeitverlaufs zu berechnen. Aus den zentralen Momenten werden schließlich die statistischen Momente der verketteten Geschichte berechnet:

Kovarianz

Sehr ähnliche Algorithmen können verwendet werden, um die Kovarianz zu berechnen .

Naiver Algorithmus

Der naive Algorithmus lautet:

Für den obigen Algorithmus könnte man den folgenden Python-Code verwenden:

def naive_covariance(data1, data2):
    n = len(data1)
    sum12 = 0
    sum1 = sum(data1)
    sum2 = sum(data2)

    for i1, i2 in zip(data1, data2):
        sum12 += i1 * i2

    covariance = (sum12 - sum1 * sum2 / n) / n
    return covariance

Mit Schätzung des Mittelwerts

Was die Varianz betrifft, so ist auch die Kovarianz zweier Zufallsvariablen verschiebungsinvariant, also gegeben zwei konstante Werte und kann geschrieben werden:

und wieder wird die Wahl eines Wertes innerhalb des Wertebereichs die Formel gegen katastrophale Annullierung stabilisieren und sie robuster gegen große Summen machen. Nimmt man den ersten Wert jedes Datensatzes, kann der Algorithmus wie folgt geschrieben werden:

def shifted_data_covariance(data_x, data_y):
    n = len(data_x)
    if n < 2:
        return 0
    kx = data_x[0]
    ky = data_y[0]
    Ex = Ey = Exy = 0
    for ix, iy in zip(data_x, data_y):
        Ex += ix - kx
        Ey += iy - ky
        Exy += (ix - kx) * (iy - ky)
    return (Exy - Ex * Ey / n) / n

Zwei-Pass

Der Two-Pass-Algorithmus berechnet zuerst die Stichprobenmittelwerte und dann die Kovarianz:

Der Algorithmus mit zwei Durchläufen kann wie folgt geschrieben werden:

def two_pass_covariance(data1, data2):
    n = len(data1)

    mean1 = sum(data1) / n
    mean2 = sum(data2) / n

    covariance = 0

    for i1, i2 in zip(data1, data2):
        a = i1 - mean1
        b = i2 - mean2
        covariance += a * b / n
    return covariance

Eine etwas genauere kompensierte Version führt den vollständigen naiven Algorithmus an den Residuen durch. Die Endsummen und sollten null sein, aber der zweite Durchgang kompensiert jeden kleinen Fehler.

Online

Es existiert ein stabiler One-Pass-Algorithmus, ähnlich dem Online-Algorithmus zur Berechnung der Varianz, der das Co-Moment berechnet :

Die scheinbare Asymmetrie in dieser letzten Gleichung ist darauf zurückzuführen, dass also beide Aktualisierungsterme gleich sind . Eine noch größere Genauigkeit kann erreicht werden, indem zuerst die Mittelwerte berechnet werden und dann der stabile Einmal-Algorithmus für die Residuen verwendet wird.

Damit kann die Kovarianz berechnet werden als

def online_covariance(data1, data2):
    meanx = meany = C = n = 0
    for x, y in zip(data1, data2):
        n += 1
        dx = x - meanx
        meanx += dx / n
        meany += (y - meany) / n
        C += dx * (y - meany)

    population_covar = C / n
    # Bessel's correction for sample variance
    sample_covar = C / (n - 1)

Eine kleine Modifikation kann auch vorgenommen werden, um die gewichtete Kovarianz zu berechnen:

def online_weighted_covariance(data1, data2, data3):
    meanx = meany = 0
    wsum = wsum2 = 0
    C = 0
    for x, y, w in zip(data1, data2, data3):
        wsum += w
        wsum2 += w * w
        dx = x - meanx
        meanx += (w / wsum) * dx
        meany += (w / wsum) * (y - meany)
        C += w * dx * (y - meany)

    population_covar = C / wsum
    # Bessel's correction for sample variance
    # Frequency weights
    sample_frequency_covar = C / (wsum - 1)
    # Reliability weights
    sample_reliability_covar = C / (wsum - wsum2 / wsum)

Ebenso gibt es eine Formel zum Kombinieren der Kovarianzen zweier Mengen, die verwendet werden kann, um die Berechnung zu parallelisieren:

Gewichtete Batch-Version

Es gibt auch eine Version des gewichteten Online-Algorithmus, die Batch-Updates durchführt: Bezeichne die Gewichte und schreibe

Die Kovarianz kann dann berechnet werden als

Siehe auch

Verweise

  1. ^ a b Einarsson, Bo (2005). Genauigkeit und Zuverlässigkeit im wissenschaftlichen Rechnen . SIAM. P. 47. ISBN 978-0-89871-584-2.
  2. ^ a b c Chan, Tony F .; Golub, Gene H. ; LeVeque, Randall J. (1983). "Algorithmen zur Berechnung der Stichprobenvarianz: Analyse und Empfehlungen" (PDF) . Der amerikanische Statistiker . 37 (3): 242–247. doi : 10.1080/00031305.1983.10483115 . JSTOR  2683386 .
  3. ^ a b c Schubert, Erich; Gertz, Michael (9. Juli 2018). Numerisch stabile Parallelberechnung der (Ko-)Varianz . ACM. P. 10. doi : 10.1145/3221269.3223036 . ISBN 9781450365055. S2CID  49665540 .
  4. ^ Higham, Nikolaus (2002). Genauigkeit und Stabilität numerischer Algorithmen (2 Aufl.) (Aufgabe 1.10) . SIAM.
  5. ^ Welford, BP (1962). "Anmerkung zu einer Methode zur Berechnung korrigierter Summen von Quadraten und Produkten". Technometrie . 4 (3): 419–420. doi : 10.2307/1266577 . JSTOR  1266577 .
  6. ^ Donald E. Knuth (1998). The Art of Computer Programming , Band 2: Seminumerical Algorithms , 3. Aufl., p. 232. Boston: Addison-Wesley.
  7. ^ Ling, Robert F. (1974). „Vergleich mehrerer Algorithmen zur Berechnung von Stichprobenmitteln und Varianzen“. Zeitschrift der American Statistical Association . 69 (348): 859–866. doi : 10.2307/2286154 . JSTOR  2286154 .
  8. ^ http://www.johndcook.com/standard_deviation.html
  9. ^ Westen, DHD (1979). „Aktualisierung von Mittel- und Varianzschätzungen: Eine verbesserte Methode“. Mitteilungen des ACM . 22 (9): 532–535. doi : 10.1145/359146.359153 . S2CID  30671293 .
  10. ^ Chan, Tony F .; Golub, Gene H. ; LeVeque, Randall J. (1979), "Aktualisieren von Formeln und ein paarweiser Algorithmus zum Berechnen von Stichprobenvarianzen." (PDF) , Technischer Bericht STAN-CS-79-773 , Department of Computer Science, Stanford University.
  11. ^ Terriberry, Timothy B. (2007), Computing Higher-Order Moments Online , archiviert vom Original am 23. April 2014 , abgerufen am 5. Mai 2008
  12. ^ Pébaÿ, Philippe (2008), "Formulas for Robust, One-Pass Parallel Computation of Covariances and Arbitrary-Order Statistical Moments" (PDF) , Technical Report SAND2008-6212 , Sandia National Laboratories
  13. ^ Pébaÿ, Philippe; Terriberry, Timothy; Kolla, Hemanth; Bennett, Janine (2016), "Numerically Stable, Scalable Formulas for Parallel and Online Computation of Higher-Order Multivariate Central Moments with Arbitrary Weights" , Computational Statistics , Springer, 31 (4): 1305–1325, doi : 10.1007/s00180- 015-0637-z , S2CID  124570169
  14. ^ a b Choi, Myoungkeun; Sweetman, Bert (2010), „Efficient Calculation of Statistical Moments for Structural Health Monitoring“, Journal of Structural Health Monitoring , 9 (1): 13–24, doi : 10.1177/1475921709341014 , S2CID  17534100

Externe Links