Sunday, February 26, 2017

Php Moyenne Mobile

Une implémentation de moyenne mobile simple en Java Plusieurs fois, j'ai voulu calculer des mesures simples dans mes applications Java, par exemple le nombre de visites par heure ou les erreurs sur une période donnée. Bien que le calcul de métriques simples ne soit pas terriblement difficile, son travail et son ID ne passent pas le temps sur le domaine du problème. J'ai été surpris de ne pas trouver de solutions largement acceptées pour les statistiques en Java. J'ai trouvé Metrics, mais il semblait un peu trop compliqué et pas bien documenté - Tout ce que je voulais vraiment était de calculer une moyenne mobile. J'ai réfléchi un peu plus au problème et décidé que ce n'était pas un problème difficile. Heres my solution Cela fonctionne en créant un tableau de taille de fréquence de mise à jour de fenêtre, puis un thread définit le compte à l'index suivant dans le tableau sur la fréquence de mise à jour. Le comptage de l'intervalle est simplement arrayi-arrayi1, qui est le dernier comptage moins le comptage le plus ancien. Pour un intervalle de 10 minutes, le compte le plus ancien (i1) a exactement 10 minutes. Pour ajouter une moyenne mobile à notre code d'abord bien besoin d'un compteur, en utilisant AtomicLong. Ce compteur doit être incrémenté en fonction des événements intéressés par le calcul (par exemple, les demandes POST pour un service REST). Nous devons fournir la mise en œuvre avec accès au compteur et cela est accompli grâce à l'interface GetCount. Ici Ill créer une moyenne mobile avec une fenêtre de 5 minutes qui met à jour toutes les secondes. Et pour obtenir la moyenne courante, nous appelons simplement la méthode getAverage: Un détail d'implémentation clé est la façon dont la taille du tableau est déterminée: en divisant la fenêtre par la fréquence de mise à jour. Ainsi, une grande fenêtre avec une fréquence de mise à jour fréquente peut consommer une quantité importante de mémoire. Dans cet exemple, la taille du tableau est raisonnable 300. Toutefois, si nous avons créé une moyenne mobile de 24 heures avec un intervalle de 1 seconde la taille serait 86400 Une fréquence de mise à jour plus raisonnable pour une période de 24 heures pourrait être toutes les 5 minutes (taille du tableau 288 ). Une autre considération du choix de la fenêtre et la fréquence de mise à jour est la fenêtre doit être divisible par la fréquence. Par exemple, une fenêtre de 2 minutes avec une fréquence de mise à jour de 6 secondes est correcte, mais une fréquence de mise à jour de 7 secondes n'est pas, puisqu'elle n'est pas divisible par 120. Une exception IllegalArgumentException est lancée si la fréquence de mise à jour du module de fenêtre n'est pas nulle. Cette implémentation nécessite un thread par moyenne mobile, ce qui n'est pas très efficace. Une meilleure solution serait de partager un thread à travers de nombreuses moyennes. Mettre à jour . Ive a mis à jour le code pour partager un thread ici. Enfin, il ya un problème d'état initial: nous n'avons pas encore de données pour la fenêtre entière. Par exemple, si vous avez une fenêtre de 5 minutes et seulement 15 secondes de données. Cette mise en œuvre renvoie null jusqu'à ce que nous ayons 5 minutes de données. Une autre approche consiste à estimer la moyenne. Supposons que nous ayons un compte de 10 en 30 secondes, alors nous pouvons estimer la moyenne de 40 en 2 minutes. Cependant, il existe un risque d'erreur significative en extrapolant des données incomplètes. Par exemple, si nous avons eu un éclat de 20 coups en 2 secondes, wed être estimant 1200 par 2 minutes, ce qui est très probablement way off. En tant que diagnostic, je veux afficher le nombre de cycles par seconde dans mon application. (Pensez aux images par seconde dans une première personne-tireur.) Mais je ne veux pas afficher la valeur la plus récente, ou la moyenne depuis le lancement. Ce que je veux calculer est la moyenne des dernières X valeurs. Ma question est, je suppose, sur la meilleure façon de stocker ces valeurs. Ma première pensée a été de créer un tableau de taille fixe, de sorte que chaque nouvelle valeur pousserait le plus ancien. Est-ce la meilleure façon de le faire Si oui, comment pourrais-je l'implémenter EDIT: Voici la classe que j'ai écrit: RRQueue. Il hérite de la file d'attente, mais applique la capacité et décolle si nécessaire. A demandé Jun 22 10 à 20: 34Votre intérieur pour iterating tout le tableau de sorte thats pourquoi vous obtenez toujours la même moyenne (celui pour le tableau entier), vous devez itérer de 0 au numéro courant de l'externe pour à la place. Votre moyenne mobile est mise à jour en fonction de j de votre intérieur pour que cela signifie qu'il remplace les valeurs précédentes de chaque nouvelle boucle, cela devrait être à l'intérieur de l'extérieur pour au lieu de l'interne en utilisant i comme index. Vous divisez sumj pour calculer des moyennes, chaque nouvelle boucle interne j vous diviserez par 0 la première somme. Je pense que vous avez voulu utiliser j1 à la place, l'index n'est pas le même que la longueur courante Conseils pour résoudre les problèmes: Évitez d'utiliser des variables pour les arrays de boucle, vous devriez utiliser array. length à la place. Pour une question de reproduire votre problème, vous pourriez nous donner le problème isolé au lieu de votre code actuel. C'est-à-dire: Imaginez si l'erreur est dans vos entrées, comment pourrions-nous croire que vous avez réellement utilisé répondus Vous êtes en boucle sur toutes les données à chaque fois. Vous devriez avoir pour (int j (igtaverageLengthi-averageLength2: 0) jlt iaverageLength2 ampamp jltnumDataPoints j) (ou quelque chose de similaire) pour votre moyenne innermost. En outre, movingAverageisumj devrait être modifié pour traiter le cas où j est 0. En particulier, il devrait probablement être movingAverageisumaverageLength et il doit être appliqué à l'emplacement movingAveragei en dehors de la boucle moyennage. Réponse Oct 4 13 at 20:42 La prochaine fois, prenez les commentaires sur la cession de la question avant de la publier. Mais puisque vous semblez assez nouveau à ce sujet, pensez à la façon dont vous alliez à travers les données, et le faire faire cela. Vous devriez essayer de vous assurer que chaque boucle s'arrête au bon endroit et rappelez-vous que si vous arrêtez quand il n'y a plus de nombres (comme lorsque vous faites la boucle interne et vous ne pouvez obtenir que 3 numéros au lieu de 4) Le programme doit aussi s'arrêter. Assurez-vous que votre code vérifie. Répondre Oct 4 13 at 20:56 Sans aucun détail supplémentaire, vous avez probablement besoin d'une moyenne mobile non pondérée. En tout point Ai dans le tableau d'entrée A de longueur N (avec 0ltiltN), c'est simplement la moyenne des entrées K précédentes du tableau, jusqu'à et y compris Ai. S'il n'y a pas de telles valeurs, alors moyenne les valeurs (i1) de A0 à Ai. compris. Un peu de réflexion vous montrera que vous n'avez pas besoin d'ajouter toutes les valeurs de K à chaque fois. Il suffit de garder la somme et, lors du déplacement vers le point suivant (c'est une moyenne mobile), soustraire la valeur qui est remplacé et ajouter la nouvelle valeur qui va le remplacer. (Au cours des premiers points K-1, vous ajoutez simplement la nouvelle valeur à la somme et augmentez votre compteur de 1). À tout moment de ce processus, la moyenne mobile est la somme courante divisée par la valeur de comptage actuelle. Répondre Oct 13 13:05 Dans une moyenne mobile, vous devez avoir une sorte de taille de la fenêtre. La taille de votre fenêtre est moyenne, donc elle ressemblera à ceci: La boucle for démarre à partir des données actuelles et retourne les points de données moyenneLength et les ajoute. Vous aurez seulement une moyenne mobile quand vous avez vous avez quand vous avez assez de points de données et la moyenne sera la somme divisée par la longueur moyenne. Note: Non testé juste le code sudo, mais c'est l'idée. Réponse 2017 Stack Exchange, Inc


No comments:

Post a Comment