Ein einfaches Moving Average Implementierung in Java Bei mehreren Gelegenheiten wollte ich einfache Metriken in meinem Java-Anwendungen, zum Beispiel die Anzahl der Treffer pro Stunde, oder Fehler während eines Zeitraums zu berechnen. Während die Berechnung einfacher Metriken ist nicht schrecklich schwierig, seine nur extra Arbeit und Id eher verbringen diese Zeit auf der Problem-Domain. Ich war überrascht, keine allgemein akzeptierten Lösungen für Metriken in Java zu finden. Ich fand Metrics, aber es schien ein wenig zu kompliziert und nicht gut dokumentiert - Alles, was ich wollte, war es, einen gleitenden Durchschnitt zu berechnen. Ich dachte über das Problem einiges mehr und entschied es nicht ein schwieriges Problem. Heres meine Lösung Dies funktioniert durch die Schaffung eines Arrays von Fenster / Update Frequenz Größe, dann ein Thread setzt die Zählung auf den nächsten Index im Array auf die Aktualisierungsfrequenz. Die Zählung für das Intervall ist einfach arrayi - arrayi1, das ist die jüngste Zählung minus der ältesten Zählung. Für ein 10-Minuten-Intervall ist die älteste Zählung (i1) genau 10 Minuten alt. Um einen gleitenden Durchschnitt zu unserem Code hinzuzufügen, benötigen Sie zunächst einen Zähler mit AtomicLong. Dieser Zähler sollte basierend auf den Ereignissen inkrementiert werden, die für das Berechnen interessant sind (z. B. POST-Anforderungen für einen REST-Dienst). Wir müssen die Implementierung mit Zugriff auf den Zähler bereitstellen und das wird durch die GetCount-Schnittstelle erreicht. Hier Ill erstellen einen gleitenden Durchschnitt mit einem 5-Minuten-Fenster, das jede Sekunde aktualisiert. Und um den aktuellen Durchschnitt zu erhalten, rufen wir einfach die getAverage-Methode auf: Ein Schlüsselimplementierungsdetail ist, wie die Arraygröße bestimmt wird: indem das Fenster durch die Aktualisierungshäufigkeit dividiert wird. So kann ein großes Fenster mit einer häufigen Aktualisierungshäufigkeit eine beträchtliche Menge an Speicher verbrauchen. In diesem Beispiel ist die Array-Größe vernünftig 300. Wenn wir jedoch einen 24-Stunden-gleitenden Durchschnitt mit einem Intervall von 1 Sekunde erstellt haben, wäre die Größe 86400 Eine vernünftigere Aktualisierungsfrequenz für einen Zeitraum von 24 Stunden kann alle 5 Minuten betragen (Arraygröße von 288 ). Eine weitere Überlegung der Auswahl der Fenster-und Update-Frequenz ist das Fenster muss durch die Frequenz teilbar. Zum Beispiel ist ein 2-minütiges Fenster mit einer 6-Sekunden-Aktualisierungsfrequenz ok, aber eine 7-Sekunden-Aktualisierungsfrequenz ist nicht vorhanden, da es nicht durch 120 teilbar ist. Eine IllegalArgumentException wird geworfen, wenn die Fenstermodul-Aktualisierungsfrequenz nicht Null ist. Diese Implementierung erfordert einen Thread pro gleitenden Durchschnitt, was nicht sehr effizient ist. Eine bessere Lösung wäre, einen Thread über viele Durchschnitte zu teilen. Aktualisieren. Ich habe den Code aktualisiert, um einen Thread hier zu teilen. Schließlich theres ein Anfangszustandproblem: wir dont haben Daten noch für das gesamte Fenster. Zum Beispiel, wenn Sie ein 5-Minuten-Fenster und nur 15 Sekunden Daten haben. Diese Implementierung gibt null zurück, bis wir 5 Minuten Daten haben. Ein anderer Ansatz ist, den Durchschnitt abzuschätzen. Angenommen, wir haben eine Zählung von 10 in 30 Sekunden, dann können wir den Durchschnitt als 40 in 2 Minuten abschätzen. Es besteht jedoch das Risiko eines signifikanten Fehlers, indem unvollständige Daten extrapoliert werden. ZB wenn wir einen Sprung von 20 Treffern in 2 Sekunden hatten, würden wir 1200 pro 2 Minuten schätzen, die in aller Wahrscheinlichkeit Weise weg ist. Ihre innere für iterating die ganze Reihe also thats, warum Sie immer den gleichen Durchschnitt erhalten (das Eine für das gesamte Array), sollten Sie stattdessen von 0 bis zur aktuellen Nummer des äußeren Feldes iterieren. Ihre gleitenden Durchschnitt aktualisiert in j Ihrer inneren Basis wird für das bedeutet, es wird die vorherigen Werte jede neue Schleife überschreibt, sollte dies für anstelle der inneren innerhalb der äußeren sein i als Index. Sie teilen sum / j, um Mittelwerte zu berechnen, jede neue innere Schleife j Sie teilen durch 0 die erste Summe. Ich glaube, Sie wollten j1 verwenden, Index ist nicht das gleiche wie aktuelle Länge Tipps zur Fehlerbehebung: Vermeiden Sie die Verwendung von Variablen zu Loop-Arrays, sollten Sie array. length stattdessen verwenden. Für eine Frage der Reproduktion Ihres Problems könnten Sie uns das isolierte Problem anstelle des aktuellen Codes. dh: Stellen Sie sich vor, wenn der Fehler in Ihrer Eingaben ist, wie könnten wir wirklich glauben, Sie verwendet antwortete ihnen 4. Oktober 13 um 20:54 Uhr Sie sind Schleifen über alle jedes Mal Daten. Für den innersten Durchschnitt sollten Sie für (int j (igtaverageLengthi-averageLength / 2: 0) jlt iaverageLength / 2 ampamp jltnumDataPoints j) (oder etwas ähnliches) haben. Außerdem sollte movingAverageisum / j modifiziert werden, um den Fall zu bewältigen, wenn j 0 ist. Insbesondere sollte es sich wahrscheinlich um MovingAverageisum / averageLength handeln und es sollte auf den movingAveragei-Slot außerhalb der Mittelungsschleife angewendet werden. Antwortete Oct 4 13 am 20:42 Nächstes Mal, nehmen Sie die Kommentare über die Zuweisung aus der Frage, bevor Sie es. Aber da Sie scheinen ziemlich neu in diesem, darüber nachzudenken, wie würden Sie durch die Daten gehen, und machen es tun. Sie sollten sicherstellen, dass jede Schleife an dem richtigen Punkt stoppt, und denken Sie daran, dass wenn Sie stoppen würden, wenn es keine Zahlen mehr gibt (wie wenn Sie die innere Schleife machen und nur 3 weitere Zahlen anstelle von 4 erhalten können) Muss das Programm auch stoppen. Stellen Sie sicher, dass Ihr Code für diese Überprüfung ist. Antwortete ohne weitere Details, benötigen Sie wahrscheinlich einen ungewichteten gleitenden Durchschnitt. An jedem Punkt Ai im Eingabefeld A der Länge N (mit 0ltiltN), das ist einfach der Mittelwert der vorherigen K Einträge des Arrays, bis einschließlich Ai. Wenn es arent K solche Werte, dann die durchschnittlichen (i1) Werte von A0 bis Ai. Einschließlich. Ein wenig Gedanke zeigt Ihnen, dass Sie nicht alle K-Werte addieren müssen jedes Mal. Halten Sie einfach die Summe und die, wenn sie auf den nächsten Punkt zu bewegen (dies ist ein gleitender Durchschnitt), subtrahieren die Wert, der den neuen Wert ersetzt werden und hinzufügen, die sie ersetzen wird. (Bei den ersten K-1 Punkten fügen Sie einfach den neuen Wert zur Summe hinzu und erhöhen Sie den Zähler um 1.) Der gleitende Durchschnitt ist an jedem Punkt der aktuelle Summe dividiert durch den aktuellen Zählwert. In einem gleitenden Durchschnitt, müssen Sie eine Art von Fenstergröße haben. Ihre Fenstergröße ist averageLength, so dass es so etwas wie folgt aussehen: Die for-Schleife beginnt bei den aktuellen Daten und geht zurück averageLength Datenpunkte und fügt sie auf. Sie haben nur einen gleitenden Durchschnitt, wenn Sie haben, wenn Sie genügend Datenpunkte haben und der Durchschnitt wird die Summe geteilt durch die durchschnittliche Länge haben. Hinweis: Nicht getestet nur Sudo-Code, aber das ist die Idee. (Tsobj, s, lag) liefert den einfachen gleitenden Durchschnitt für finanziellen Zeitreihen-Objekt, tsobj. Verzögerung gibt die Anzahl der vorherigen Datenpunkte an, die beim Berechnen des gleitenden Mittelwerts mit dem aktuellen Datenpunkt verwendet werden. Ausgabe tsmovavg (Vektor, s, lag, dim) gibt den einfachen gleitenden Durchschnitt für einen Vektor zurück. Verzögerung gibt die Anzahl der vorherigen Datenpunkte an, die beim Berechnen des gleitenden Mittelwerts mit dem aktuellen Datenpunkt verwendet werden. Ausgang tsmovavg (tsobj, e, Zeitfenster) gibt die exponentielle gewichteten gleitenden Durchschnitt für Finanzzeitreihen Objekt, tsobj. Der exponentielle gleitende Durchschnitt ist ein gewichteter gleitender Durchschnitt, wobei die Zeitperiode den Zeitraum angibt. Exponentielle gleitende Durchschnitte reduzieren die Verzögerung durch mehr Gewicht auf die jüngsten Preise. Zum Beispiel gewichtet ein 10-Perioden-exponentieller gleitender Durchschnitt den jüngsten Preis um 18,18. Exponentialprozent 2 / (TIMEPER 1) oder 2 / (WINDOWSIZE 1). Output tsmovavg (Vektor, e, timeperiod, dim) gibt den exponentiell gewichteten gleitenden Durchschnitt für einen Vektor zurück. Der exponentielle gleitende Durchschnitt ist ein gewichteter gleitender Durchschnitt, wobei die Zeitperiode den Zeitraum angibt. Exponentielle gleitende Durchschnitte reduzieren die Verzögerung durch mehr Gewicht auf die jüngsten Preise. Zum Beispiel gewichtet ein 10-Perioden-exponentieller gleitender Durchschnitt den jüngsten Preis um 18,18. (2 / (Zeitabschnitt 1)). Ausgabe tsmovavg (tsobj, t, numperiod) gibt den dreieckigen gleitenden Durchschnitt für das finanzielle Zeitreihenobjekt tsobj zurück. Der dreieckige gleitende Durchschnitt doppelt glättet die Daten. Tsmovavg berechnet den ersten einfachen gleitenden Durchschnitt mit Fensterbreite von ceil (numperiod 1) / 2. Dann berechnet es einen zweiten einfachen gleitenden Durchschnitt auf dem ersten gleitenden Durchschnitt mit der gleichen Fenstergröße. Ausgabe tsmovavg (Vektor, t, numperiod, dim) gibt den dreieckigen gleitenden Durchschnitt für einen Vektor zurück. Der dreieckige gleitende Durchschnitt doppelt glättet die Daten. Tsmovavg berechnet den ersten einfachen gleitenden Durchschnitt mit Fensterbreite von ceil (numperiod 1) / 2. Dann berechnet es einen zweiten einfachen gleitenden Durchschnitt auf dem ersten gleitenden Durchschnitt mit der gleichen Fenstergröße. Output tsmovavg (tsobj, w, gewichte) liefert den gewichteten gleitenden Durchschnitt für das finanzielle Zeitreihenobjekt tsobj. Indem Gewichte für jedes Element in dem sich bewegenden Fenster bereitgestellt werden. Die Länge des Gewichtsvektors bestimmt die Größe des Fensters. Wenn größere Gewichtungsfaktoren für neuere Preise und kleinere Faktoren für frühere Preise verwendet werden, ist der Trend eher auf die jüngsten Veränderungen ansprechen. Ausgabe tsmovavg (Vektor, w, Gewichte, dim) gibt den gewichteten gleitenden Durchschnitt für den Vektor zurück, indem Gewichte für jedes Element in dem sich bewegenden Fenster geliefert werden. Die Länge des Gewichtsvektors bestimmt die Größe des Fensters. Wenn größere Gewichtungsfaktoren für neuere Preise und kleinere Faktoren für frühere Preise verwendet werden, ist der Trend eher auf die jüngsten Veränderungen ansprechen. Output tsmovavg (tsobj, m, numperiod) gibt den modifizierten gleitenden Durchschnitt für das finanzielle Zeitreihenobjekt tsobj zurück. Der modifizierte gleitende Durchschnitt ist ähnlich dem einfachen gleitenden Durchschnitt. Betrachten Sie das Argument numperiod als die Verzögerung des einfachen gleitenden Mittelwerts. Der erste modifizierte gleitende Durchschnitt wird wie ein einfacher gleitender Durchschnitt berechnet. Nachfolgende Werte werden durch Addition des neuen Preises und Subtrahieren des letzten Durchschnitts aus der resultierenden Summe berechnet. Ausgabe tsmovavg (Vektor, m, numperiod, dim) gibt den modifizierten gleitenden Durchschnitt für den Vektor zurück. Der modifizierte gleitende Durchschnitt ist ähnlich dem einfachen gleitenden Durchschnitt. Betrachten Sie das Argument numperiod als die Verzögerung des einfachen gleitenden Mittelwerts. Der erste modifizierte gleitende Durchschnitt wird wie ein einfacher gleitender Durchschnitt berechnet. Nachfolgende Werte werden durch Addition des neuen Preises und Subtrahieren des letzten Durchschnitts aus der resultierenden Summe berechnet. Dim 8212 Dimension, um auf positive ganze Zahl mit dem Wert 1 oder 2 arbeiten Dimension zu arbeiten, als eine positive Ganzzahl mit einem Wert von 1 oder 2 angegeben. Dim ist ein optionales Eingabeargument, und wenn es nicht als eine Eingabe enthalten ist, die Standardeinstellung Wert 2 wird angenommen. Der Standardwert von dim 2 gibt eine zeilenorientierte Matrix an, wobei jede Zeile eine Variable ist und jede Spalte eine Beobachtung ist. Wenn dim 1. die Eingabe als Spaltenvektor oder spaltenorientierte Matrix angenommen wird, wobei jede Spalte eine Variable und jede Zeile eine Beobachtung ist. E 8212 Indikator für exponentiell gleitenden durchschnittlichen Charaktervektor Der exponentielle gleitende Durchschnitt ist ein gewichteter gleitender Durchschnitt, wobei der Zeitabschnitt der Zeitraum des exponentiellen gleitenden Durchschnitts ist. Exponentielle gleitende Durchschnitte reduzieren die Verzögerung durch mehr Gewicht auf die jüngsten Preise. Zum Beispiel gewichtet ein 10-Perioden-exponentieller gleitender Durchschnitt den jüngsten Preis um 18,18. Exponentialprozent 2 / (TIMEPER 1) oder 2 / (WINDOWSIZE 1) timeperiod 8212 Zeitdauer nonnegative integer Wählen Sie Ihr Land aus
No comments:
Post a Comment