Ich habe ein kleines Problem, das mich ausflippen lässt. Ich muss eine Prozedur für einen Online-Erfassungsprozess einer multivariaten Zeitreihe schreiben. In jedem Zeitintervall (zum Beispiel 1 Sekunde) erhalte ich eine neue Stichprobe, die im Grunde genommen ein Gleitkomma-Vektor der Größe N ist. Die Operation, die ich ausführen muss, ist etwas schwierig:
Für jede neue Stichprobe berechne ich die Prozentsätze für diese Stichprobe (indem ich den Vektor so normalisiere, dass die Elemente zu 1 summieren).
Ich berechne den durchschnittlichen prozentualen Vektor auf die gleiche Weise, aber unter Verwendung der vergangenen Werte.
Für jeden vergangenen Wert berechne ich die absolute Abweichung des mit dieser Stichprobe verbundenen Prozentvektors mit dem in Schritt 2 berechneten globalen durchschnittlichen Prozentvektor. Auf diese Weise ist die absolute Abweichung immer eine Zahl zwischen 0 (wenn der Vektor dem Durchschnitt entspricht) Vektor) und 2 (wenn es total verschieden ist).
Aus dem Durchschnitt der Abweichungen aller vorhergehenden Stichproben berechne ich die mittlere absolute Abweichung, die wiederum eine Zahl zwischen 0 und 2 ist.
Ich verwende die mittlere absolute Abweichung, um festzustellen, ob eine neue Probe mit den anderen Proben kompatibel ist (indem ich ihre absolute Abweichung mit der mittleren absoluten Abweichung des gesamten in Schritt 4 berechneten Satzes vergleiche).
Gibt es eine Möglichkeit, diesen Wert zu berechnen, ohne den gesamten Datensatz mehrmals zu scannen, da sich jedes Mal, wenn eine neue Stichprobe erfasst wird, der globale Durchschnitt ändert (und sich somit auch die mittlere absolute Abweichung ändert)? (einmal für die Berechnung der globalen Durchschnittsprozentsätze und einmal für die Erfassung der absoluten Abweichungen). Ok, ich weiß, dass es absolut einfach ist, die globalen Mittelwerte zu berechnen, ohne den gesamten Satz abzutasten, da ich nur einen temporären Vektor zum Speichern der Summe jeder Dimension verwenden muss, aber was ist mit der mittleren absoluten Abweichung? abs()
Da die Berechnung den Operator einschließt , muss ich auf alle früheren Daten zugreifen können!
Danke für Ihre Hilfe.
quelle
Ich habe in der Vergangenheit den folgenden Ansatz verwendet, um die Absolutionsabweichung mäßig effizient zu berechnen (beachten Sie, dass dies ein Programmieransatz ist, kein Statistiker, so dass es zweifellos clevere Tricks wie Shabbychefs gibt , die effizienter sein könnten).
WARNUNG: Dies ist kein Online-Algorithmus. Es erfordert
O(n)
Speicher. Darüber hinaus hat es eine Worst-Case-Performance vonO(n)
, für Datensätze wie[1, -2, 4, -8, 16, -32, ...]
(dh die gleiche wie die vollständige Neuberechnung). [1]Da es jedoch in vielen Anwendungsfällen immer noch eine gute Leistung bringt, kann es sich lohnen, es hier zu veröffentlichen. Um zum Beispiel die absolute Abweichung von 10000 Zufallszahlen zwischen -100 und 100 zu berechnen , benötigt mein Algorithmus weniger als eine Sekunde, während die vollständige Neuberechnung über 17 Sekunden dauert (auf meinem Computer variieren je nach Computer und entsprechend den eingegebenen Daten). Sie müssen jedoch den gesamten Vektor im Speicher behalten, was für einige Anwendungen eine Einschränkung sein kann. Der Umriss des Algorithmus lautet wie folgt:
O(n)
Verschiebevorgänge erfordert, ist dies in vielen Anwendungsfällen nicht der Fall.Einige Beispielcodes in Python finden Sie weiter unten. Beachten Sie, dass nur Elemente zur Liste hinzugefügt und nicht entfernt werden können. Dies könnte leicht hinzugefügt werden, aber zu dem Zeitpunkt, als ich dies schrieb, hatte ich keine Notwendigkeit dafür. Anstatt die Priority Queues selbst zu implementieren, habe ich die sortierte Liste aus Daniel Stutzbachs exzellentem Blist-Paket verwendet , die intern B + Tree s verwendet.
Betrachten Sie diesen Code als unter der MIT-Lizenz lizenziert . Es wurde nicht wesentlich optimiert oder poliert, hat aber in der Vergangenheit für mich funktioniert. Neue Versionen verfügbar sein hier . Lassen Sie mich wissen, wenn Sie Fragen haben oder Fehler finden.
[1] Wenn die Symptome anhalten, wenden Sie sich an Ihren Arzt.
quelle
O(n)
Speicher und im schlimmsten Fall O (n) Zeit für jedes hinzugefügte Element. Bei normalverteilten Daten (und wahrscheinlich auch bei anderen Distributionen) funktioniert dies jedoch recht effizient.quelle
MAD (x) ist nur zwei gleichzeitige Median-Berechnungen, von denen jede online über den Binmedian- Algorithmus durchgeführt werden kann.
Den dazugehörigen Artikel sowie den C- und FORTRAN-Code finden Sie hier online .
(Dies ist nur die Verwendung eines cleveren Tricks zusätzlich zu Shabbychefs cleverem Trick, um Speicherplatz zu sparen).
Nachtrag:
Es gibt eine Vielzahl älterer Multi-Pass-Methoden zur Berechnung von Quantilen. Ein gängiger Ansatz besteht darin, ein deterministisch großes Reservoir von Beobachtungen zu verwalten / zu aktualisieren, die zufällig aus dem Datenstrom ausgewählt wurden, und Quantile (siehe diese Übersicht) auf diesem Reservoir rekursiv zu berechnen . Dieser (und verwandte) Ansatz wird durch den oben vorgeschlagenen ersetzt.
quelle
Das Folgende liefert eine ungenaue Annäherung, obwohl die Ungenauigkeit von der Verteilung der Eingabedaten abhängt. Es ist ein Online-Algorithmus, der sich jedoch nur der absoluten Abweichung annähert. Es basiert auf einem bekannten Algorithmus zur Online- Varianzberechnung , der von Welford in den 1960er Jahren beschrieben wurde. Sein in R übersetzter Algorithmus sieht folgendermaßen aus:
Es funktioniert sehr ähnlich wie die in R integrierte Varianzfunktion:
Das Ändern des Algorithmus zur Berechnung der absoluten Abweichung erfordert lediglich einen zusätzlichen
sqrt
Aufruf. Diesqrt
führt jedoch zu Ungenauigkeiten, die sich im Ergebnis widerspiegeln:Die wie oben berechneten Fehler sind viel größer als bei der Varianzberechnung:
Abhängig von Ihrem Anwendungsfall kann diese Fehlergröße jedoch akzeptabel sein.
quelle
n
groß wird, dererror/n
bekommt verschwindend klein, überraschend schnell.sqrt
Ungenauigkeit. Dies liegt daran, dass die Schätzung des laufenden Mittels verwendet wird. Um zu sehen, wann dies fehlschlägt, versuchen Sie Folgendes:xs <- sort(rnorm(n.testitems))
Wenn ich dies mit Ihrem Code versuche (nachdem ich ihn repariert habe, um zurückzukehrena.dev / n
), erhalte ich relative Fehler in der Größenordnung von 9% -16%. Diese Methode ist also nicht permutationsinvariant, was zu Chaos führen könnte ...