J'ai un petit problème qui me fait paniquer. Je dois écrire une procédure pour un processus d'acquisition en ligne d'une série temporelle multivariée. À chaque intervalle de temps (par exemple 1 seconde), j'obtiens un nouvel échantillon, qui est essentiellement un vecteur à virgule flottante de taille N. L'opération que je dois faire est un peu délicate:
Pour chaque nouvel échantillon, je calcule les pourcentages pour cet échantillon (en normalisant le vecteur pour que les éléments totalisent 1).
Je calcule le vecteur des pourcentages moyens de la même manière, mais en utilisant les valeurs passées.
Pour chaque valeur passée, je calcule l'écart absolu du vecteur de pourcentages lié à cet échantillon avec le vecteur de pourcentages moyen global calculé à l'étape 2. De cette façon, l'écart absolu est toujours un nombre compris entre 0 (lorsque le vecteur est égal à la moyenne vecteur) et 2 (quand il est totalement différent).
En utilisant la moyenne des écarts pour tous les échantillons précédents, je calcule l'écart absolu moyen, qui est à nouveau un nombre compris entre 0 et 2.
J'utilise l'écart absolu moyen pour détecter si un nouvel échantillon est compatible avec les autres échantillons (en comparant son écart absolu avec l'écart absolu moyen de l'ensemble calculé à l'étape 4).
Étant donné que chaque fois qu'un nouvel échantillon est collecté, les variations moyennes globales (et donc l'écart absolu moyen change également), existe-t-il un moyen de calculer cette valeur sans analyser plusieurs fois l'ensemble des données? (une fois pour le calcul des pourcentages moyens mondiaux et une fois pour la collecte des écarts absolus). Ok, je sais qu'il est absolument facile de calculer les moyennes globales sans balayer l'ensemble, car je n'ai qu'à utiliser un vecteur temporaire pour stocker la somme de chaque dimension, mais qu'en est-il de l'écart absolu moyen? Son calcul inclut l' abs()
opérateur, j'ai donc besoin d'accéder à toutes les données passées!
Merci de votre aide.
la source
J'ai utilisé l'approche suivante dans le passé pour calculer la déviation d'absolution de manière modérément efficace (notez que c'est une approche de programmeurs, pas de statisticiens, donc il est indubitable qu'il peut y avoir des astuces intelligentes comme celles de shabbychef qui pourraient être plus efficaces).
AVERTISSEMENT: ce n'est pas un algorithme en ligne. Cela nécessite de la
O(n)
mémoire. De plus, il présente les performances les plus défavorables deO(n)
, pour des ensembles de données comme[1, -2, 4, -8, 16, -32, ...]
(c'est-à-dire les mêmes que pour le recalcul complet). [1]Cependant, comme il fonctionne toujours bien dans de nombreux cas d'utilisation, il peut être utile de le publier ici. Par exemple, afin de calculer la déviance absolue de 10000 nombres aléatoires entre -100 et 100 à l'arrivée de chaque élément, mon algorithme prend moins d'une seconde, tandis que le recalcul complet prend plus de 17 secondes (sur ma machine, variera selon la machine et selon les données d'entrée). Cependant, vous devez conserver le vecteur entier en mémoire, ce qui peut être une contrainte pour certaines utilisations. Le contour de l'algorithme est le suivant:
O(n)
opérations de déplacement, pour de nombreux cas d'utilisation, ce n'est pas le cas.Un exemple de code, en python, est ci-dessous. Notez qu'il permet uniquement d'ajouter des éléments à la liste, pas de les supprimer. Cela pourrait facilement être ajouté, mais au moment où j'ai écrit cela, je n'en avais pas besoin. Plutôt que d'implémenter moi-même les files d'attente prioritaires, j'ai utilisé la liste de tri de l'excellent package blist de Daniel Stutzbach , qui utilise B + Tree s en interne.
Considérez ce code sous licence MIT . Il n'a pas été optimisé ou poli de manière significative, mais a fonctionné pour moi dans le passé. De nouvelles versions seront disponibles ici . Faites-moi savoir si vous avez des questions ou si vous trouvez des bugs.
[1] Si les symptômes persistent, consultez votre médecin.
la source
O(n)
mémoire et, dans le pire des cas, prend du temps O (n) pour chaque élément ajouté. Dans les données normalement distribuées (et probablement d'autres distributions), cela fonctionne assez efficacement.la source
MAD (x) n'est que deux calculs médians simultanés, chacun pouvant être effectué en ligne via l' algorithme binmédian .
Vous pouvez trouver le papier associé ainsi que le code C et FORTRAN en ligne ici .
(c'est juste l'utilisation d'une astuce intelligente en plus de l'astuce intelligente de Shabbychef, pour économiser de la mémoire).
Addenda:
Il existe une multitude d'anciennes méthodes multi-passes pour le calcul des quantiles. Une approche populaire consiste à maintenir / mettre à jour un réservoir d'observations de taille déterministe sélectionné au hasard dans le cours d'eau et à calculer récursivement des quantiles (voir cette revue) sur ce réservoir. Cette approche (et connexe) est remplacée par celle proposée ci-dessus.
la source
The following provides an inaccurate approximation, although the inaccuracy will depend on the distribution of the input data. It is an online algorithm, but only approximates the absolute deviance. It is based on a well known algorithm for calculating variance online, described by Welford in the 1960s. His algorithm, translated into R, looks like:
It performs very similarly to R's builtin variance function:
Modifying the algorithm to calculate absolute deviation simply involves an additional
sqrt
call. However, thesqrt
introduces inaccuracies that are reflected in the result:The errors, calculated as above, are much greater than for the variance calculation:
However, depending on your use case, this magnitude of error might be acceptable.
la source
n
grandit, leerror/n
devient extrêmement petit, étonnamment rapidement.sqrt
imprecision. It is because it uses the running mean estimate. To see when this will break, tryxs <- sort(rnorm(n.testitems))
When I try this with your code (after fixing it to returna.dev / n
), I get relative errors on the order of 9%-16%. So this method is not permutation invariant, which could cause havoc...