Die Lösung wurde in einem Buch von 1972 gefunden (George R. Price, Ann. Hum. Genet., Lond, S. 485-490, Erweiterung der Kovarianzauswahlmathematik, 1972) .
Verzerrte gewichtete Probenkovarianz:
Σ = 1∑N.i = 1wich∑N.i = 1wich( xich- μ∗)T.( xich- μ∗)
Und die unvoreingenommene gewichtete Probenkovarianz, die durch Anwendung der Bessel-Korrektur gegeben ist:
Σ = 1∑N.i = 1wich- 1∑N.i = 1wich( xich- μ∗)T.( xich- μ∗)
Wobei der (unverzerrte) gewichtete Stichprobenmittelwert ist:μ∗
μ∗= ∑N.i = 1wichxich∑N.i = 1wich
Wichtiger Hinweis: Dies funktioniert nur, wenn die Gewichte Gewichte vom Typ "Wiederholung" sind, was bedeutet, dass jedes Gewicht die Anzahl der Vorkommen einer Beobachtung darstellt und dass wobeiN ∗∑N.i = 1wich= N.∗N.∗ stellen die tatsächliche Stichprobengröße dar (tatsächliche Gesamtzahl der Stichproben unter Berücksichtigung der Gewichte).
Ich habe den Artikel auf Wikipedia aktualisiert, wo Sie auch die Gleichung für die unvoreingenommene gewichtete Stichprobenvarianz finden:
https://en.wikipedia.org/wiki/Weighted_arithmetic_mean#Weighted_sample_covariance
wich( xich- μ∗)( xich- μ∗)
import pandas as pd
import numpy as np
# X is the dataset, as a Pandas' DataFrame
mean = mean = np.ma.average(X, axis=0, weights=weights) # Computing the weighted sample mean (fast, efficient and precise)
mean = pd.Series(mean, index=list(X.keys())) # Convert to a Pandas' Series (it's just aesthetic and more ergonomic, no differenc in computed values)
xm = X-mean # xm = X diff to mean
xm = xm.fillna(0) # fill NaN with 0 (because anyway a variance of 0 is just void, but at least it keeps the other covariance's values computed correctly))
sigma2 = 1./(w.sum()-1) * xm.mul(w, axis=0).T.dot(xm); # Compute the unbiased weighted sample covariance
Habe ein paar Sanity Checks mit einem nicht gewichteten Datensatz und einem gleichwertigen gewichteten Datensatz durchgeführt, und es funktioniert korrekt.