Quelle serait la manière idéale de trouver la moyenne et l'écart type d'un signal pour une application en temps réel. Je voudrais pouvoir déclencher un contrôleur lorsqu'un signal était à plus de 3 écart-type de la moyenne pendant un certain temps.
Je suppose qu'un DSP dédié ferait cela assez facilement, mais y a-t-il un "raccourci" qui pourrait ne pas nécessiter quelque chose de si compliqué?
statistics
real-time
measurement
jonsca
la source
la source
Réponses:
Il y a une faille dans la réponse de Jason R, qui est discutée dans "Art of Computer Programming" vol. 2. Le problème survient si vous avez un écart-type qui est une petite fraction de la moyenne: le calcul de E (x ^ 2) - (E (x) ^ 2) souffre d'une sensibilité sévère aux erreurs d'arrondi à virgule flottante.
Vous pouvez même essayer cela vous-même dans un script Python:
J'obtiens -128.0 comme réponse, ce qui n'est clairement pas valable pour le calcul, car les mathématiques prédisent que le résultat devrait être non négatif.
Knuth cite une approche (je ne me souviens pas du nom de l'inventeur) pour calculer la moyenne courante et l'écart type qui ressemble à ceci:
puis après chaque étape, la valeur de
m
est la moyenne, et l'écart-type peut être calculé commesqrt(S/n)
ousqrt(S/n-1)
selon votre définition préférée de l'écart-type.L'équation que j'écris ci-dessus est légèrement différente de celle de Knuth, mais elle est équivalente sur le plan des calculs.
Lorsque j'ai encore quelques minutes, je coderai la formule ci-dessus en Python et montrerai que vous obtiendrez une réponse non négative (qui, espérons-le, est proche de la valeur correcte).
mise à jour: le voici.
test1.py:
résultat:
Vous remarquerez qu'il y a encore une erreur d'arrondi, mais ce n'est pas mauvais, alors
naive_stats
que ça vomit.edit: Je viens de remarquer le commentaire de Belisarius citant Wikipedia qui mentionne l'algorithme Knuth.
la source
Dans le domaine des fréquences, une "moyenne mobile exponentiellement pondérée" n'est qu'un pôle réel. Il est simple à mettre en œuvre dans le domaine temporel.
Implémentation du domaine temporel
Soit
mean
etmeansq
soit les estimations actuelles de la moyenne et de la moyenne du carré du signal. À chaque cycle, mettez à jour ces estimations avec le nouvel échantillonx
:Ce qui est exprimé ci-dessus comme un programme impératif peut également être représenté sous forme de diagramme de flux de signal:
Une analyse
En condensant les filtres IIR dans leurs propres blocs, le diagramme ressemble maintenant à ceci:
Les références
la source
0 > a > 1
0 < a < 1
. Si votre système a un échantillonnage tmieT
et que vous souhaitez une constante de temps moyennetau
, choisisseza = 1 - exp (2*pi*T/tau)
.z=1
(DC) enH(z) = a/(1-(1-a)/z)
et vous obtenez 1.Une méthode que j'ai utilisée auparavant dans une application de traitement intégrée consiste à conserver les accumulateurs de la somme et de la somme des carrés du signal d'intérêt:
ou vous pouvez utiliser:
selon la méthode d'estimation de l'écart type que vous préférez . Ces équations sont basées sur la définition de la variance :
Je les ai utilisés avec succès dans le passé (bien que je ne me préoccupe que de l'estimation de la variance, pas de l'écart-type), bien que vous deviez faire attention aux types numériques que vous utilisez pour contenir les accumulateurs si vous voulez résumer une longue période de temps; vous ne voulez pas de débordement.
Edit: En plus du commentaire ci-dessus sur le débordement, il convient de noter que ce n'est pas un algorithme numériquement robuste lorsqu'il est implémenté en arithmétique à virgule flottante, ce qui peut potentiellement provoquer de grandes erreurs dans les statistiques estimées. Regardez la réponse de Jason S pour une meilleure approche dans ce cas.
la source
Semblable à la réponse préférée ci-dessus (Jason S.), et dérivée également de la formule tirée de Knut (Vol.2, p 232), on peut également dériver une formule pour remplacer une valeur, c'est-à-dire supprimer et ajouter une valeur en une seule étape . Selon mes tests, replace offre une meilleure précision que la version supprimer / ajouter en deux étapes.
Le code ci-dessous est en Java,
mean
ets
est mis à jour (variables membres "globales"), comme cim
-s
dessus et dans la publication de Jason. La valeurcount
fait référence à la taille de la fenêtren
.la source
La réponse de Jason et Nibot diffère sur un aspect important: la méthode de Jason calcule le dev std et la moyenne pour le signal entier (puisque y = 0), tandis que Nibot est un calcul "courant", c'est-à-dire qu'il pèse des échantillons plus récents plus forts que les échantillons du passé lointain.
Étant donné que l'application semble nécessiter un dev std et une moyenne en fonction du temps, la méthode de Nibot est probablement la plus appropriée (pour cette application spécifique). Cependant, la vraie partie délicate sera d'obtenir la bonne pondération temporelle. L'exemple de Nibot utilise un simple filtre unipolaire.
Le choix du filtre passe-bas peut être guidé par ce que vous savez sur votre signal et la résolution temporelle dont vous avez besoin pour votre estimation. Des fréquences de coupure plus basses et un ordre plus élevé se traduiront par une meilleure précision mais un temps de réponse plus lent.
Pour compliquer encore les choses, un filtre est appliqué dans le domaine linéaire et un autre dans le domaine carré. La quadrature modifie considérablement le contenu spectral du signal, vous pouvez donc utiliser un filtre différent dans le domaine carré.
Voici un exemple sur la façon d'estimer la moyenne, la valeur efficace et la déviation standard en fonction du temps.
la source
y1 = filter(a,[1 (1-a)],x);
.