Hallo an alle,
welche Methoden verwendet ihr, um Ausreißer z.B. von einem Sensor weg zu
filtern?
Mit einem Mittelwert kann man zwar Messwerte glätten, aber ein starker
Ausreißer verzieht den Wert trotzdem.
Diesen Filter kenne ich nicht ( Methode nach Grubbs ), macht aber einen
viel versprechenden Eindruck:
http://de.wikihow.com/Ausrei%C3%9Fer-nach-Grubbs-berechnen
Markus schrieb:> Methode nach Grubbs
Das ist im ersten Schritt ein Medianfilter: sortiere eine (am besten
ungerade) Zahl von Messwerten und nimm den in der Mitte. Bei einer
geraden Zahl von Messwerten musst du noch zusätzlich den Mittelwert der
beiden mittleren bilden...
Und alles, was danach kommt, ist nur noch weitere Statistik zur
Zuverlässigkeit des Messwerts. Das ist in der alltäglichen Praxis
unnötig.
Ingo L. schrieb:> int32_t Limit_Spike ( int32_t Value )
Zu deiser Methode gehört aber auch eine gehörige Portion an
"Ausprobieren", um die 4 Konstanten zur Limitierung zu finden.
"Portabel" und "Einfach" schreiben sich anders...
Du behauptest grade das man vorher überlegen sollte was man tut. Das
muss man doch aber immer.
Gerade bei Reglern macht sowas Sinn, damit man immer vorhersagbares
Verhalten hat
Lothar Miller (lkmiller) (Moderator) Benutzerseite
>Und alles, was danach kommt, ist nur noch weitere Statistik zur>Zuverlässigkeit des Messwerts. Das ist in der alltäglichen Praxis>unnötig.
Ich glaube, das ist zu unvollständig. Die Methode nach Grubbs ist näher
an der Matlab-Funktion "trimmean", bei der beispielsweise die oberen
und unteren 10% der sortierten Folge weggelassen werden:
http://de.mathworks.com/help/stats/trimmean.html?requestedDomain=www.mathworks.com
Hall Ingo,
das ist interessant. Ich hatte einen ähnlichen Ansatz. Allerdings passe
ich die Grenzen mittels eines LowPassFilters statt mit konstanter
Schrittweite an.
Ingo L. schrieb:> Du behauptest grade das man vorher überlegen sollte was man tut.
Das ist eine recht freie Interpretation meiner Aussage. Sie stimmt
allerdings.
Nur weiß man gerade bei Ausreißern nicht, wie stark sie ausreißen.
Und deshalb funktioniert ein Medianfilter tendenziell zuverlässiger als
das Begrenzen von Werten jenseits des gewünschten/erwarteten/geplanten
Bereichs.
Allerdings wende ich jede Art von Filterung von Messwerten erst an, wenn
ich sicher weiß(!) whoer die Störungen kommen. Denn sonst ist so ein
Filter einfach nur ein "Schönsaufen"...
chris schrieb:> Ich hatte einen ähnlichen Ansatz. Allerdings passe ich die Grenzen> mittels eines LowPassFilters statt mit konstanter Schrittweite an.
Ich habe herausgefunden, dass je komplexer und "eigenständiger" so ein
Filter ist, um so seltsamer sind die erzielbaren Effekte und
Fehlfunktionen draußen im Feld. Und vor Allem: niemals wieder kann man
diese Effekte oder die Fehlfunktionen im Labor nachstellen und
untersuchen.
>Ich habe herausgefunden, dass je komplexer und "eigenständiger" so ein>Filter ist, um so seltsamer sind die erzielbaren Effekte und>Fehlfunktionen draußen im Feld. Und vor Allem: niemals wieder kann man>diese Effekte oder die Fehlfunktionen im Labor nachstellen und>untersuchen.
Ja, Filterentwurf ist ziemlich schwierig. Eigentlich muss man erst die
Störungen genau analysieren, dann ein Modell des Signals erstellen und
dann den Filter darauf anpassen. Mit jeder Filteraktion gehen natürlich
Daten verloren, da sie weg gefiltert werden, deshalb wäre es besser, man
hätte immer die Rohdaten. Aber es gibt eben auch Fälle, bei denen
Ausreißer ziemlich offensichtlich sind und weggelassen werden können.
Ich wuerde mir erst mal Gedanken ueber den Unsprung der Ausreisser
machen. Dann wuerde ich eine statistik aufnehmen, Fouriertransformieren
und solches Zeug. Falls es tatsaechlich Ausreiiser sind, Wie zb
kosmische Strahlung. Dann muesste man noch ein paar Werte weiter
sampeln, bevor man den ausreisser als solchen erkennen kann. Das waere
dann eine Verzoegerung von ein paar Samples. Wenn das System diese
Massnahme verzeiht...
Lothar M. schrieb:> Nur weiß man gerade bei Ausreißern nicht, wie stark sie ausreißen.> Und deshalb funktioniert ein Medianfilter tendenziell zuverlässiger als> das Begrenzen von Werten jenseits des gewünschten/erwarteten/geplanten> Bereichs.
Ich habe immer vor allen ADC-Kanälen einen analogen Tiefpass. Mit diesen
Parametern und der dem Kennen des Eingangssignals lässt sich ermitteln
wie schnell sich eine Signal von Sample zu Sample maximal ändern kann
oder ob es sich hier um eine Störung handelt.
chris schrieb:> Allerdings passe ich die Grenzen mittels eines LowPassFilters
Ich auch, mit nem analogen (RC) Tiefpass ;)
Vielleicht nicht das allerschnellste, aber für meine Verhältnisse
ausreichend:
Ich schreibe die Sensordaten fortlaufend in ein Array mit 6 Feldern.{1}
Dieses Array kopiere ich in ein zweites, eben so großes Array und lasse
einen Durchlauf eines Bubblesort durch laufen. Dadurch steht die größte
Zahl ganz oben. {2}
Danach kommt ein umgekehrter Bubblesort wodurch die kleinste Zahl ganz
unten steht. {3}
Die mittleren 4 Felder addiere ich {4} und teile das Ergebnis durch 4
{5}
(2 mal rechts schieben erfüllt den selben Zweck, geht aber schneller,
deshalb 6 Felder. Möglich sind auch 4 oder 10 Felder, Hauptsache man
kann das Teilen durch einfaches rechtsverschieben ersetzen)
{1} 63, 54, 102, 59, 11, 61
{2} 54, 63, 59, 11, 61, 102
{3} 11, 54, 63, 59, 61, 102
{4} 54 + 63 + 59 + 61 = 237
{5} 237 / 4 = 59,25 (oder 237 shr 2 = 59)
Wenn natürlich mehrere Ausreisser in eine Richtung vorkommen, fliessen
diese trotzdem in die Rechnung mit ein. Wenn man aber die Daten kennt
und weiß, wie viele Ausreisser in Folge kommen können, kann man das Feld
nach oben und unten noch erweitern. Dann muss man allerdings nicht nur
zweimal sortieren sondern entsprechend öfter um die Maximal- und
Minimalwerte aus der Mitte heraus zu bekommen.
Oder man lässt den Filter mehrmals über die Werte laufen, indem man die
Ergebnisse des ersten Filters wiederum fortlaufend in ein Array schreibt
und filtert.
Das erhöht dann die Latenz und die Gesamtlaufzeit des Filters natürlich
mit jeder Filterstufe mehr als das Array zu erweitern.
Frank B. schrieb:> Dieses Array kopiere ich in ein zweites, eben so großes Array und lasse> einen Durchlauf eines Bubblesort durch laufen. Dadurch steht die größte> Zahl ganz oben. {2}> Danach kommt ein umgekehrter Bubblesort wodurch die kleinste Zahl ganz> unten steht. {3}
Du machst also nur 1 Durchlauf des Bubblesort in jede Richtung. Das ist
eine Art "Medianfilter mit Abkürzung". Dabei verlässt du dich aber
darauf, dass es keine 2 Ausreißer in die selbe Richtung gibt. Wenn
deine Eingangsdaten so aussehen, ist das Ergebnis suboptimal:
{1} 63, 54, 102, 59, 111, 61
Wie schon geschrieben wurde, ist das Medianfilter ein sehr wirksames
Verfahren zur Elimination von Ausreißern. Im Gegensatz zum Tiefpass-
oder Mittelwertfilter dürfen die Ausreißer eine beliebig hohe Amplitude
haben, und die eigentlichen Messdaten werden kaum verwaschen.
Eine sinnvolle Fenstergröße für die Medianbildung ist 5, da damit bei
begrenztem Rechenaufwand auch zwei kurz aufeinanderfolgende Ausreißer
eliminiert werden. Drei Ausreißer innerhalb von fünf Werten in die
gleiche Richtung werden zwar nicht mehr erkannt, aber wenn sie so dicht
liegen, kann man sowieso kaum noch von Ausreißern sprechen.
Hier ist noch ein netter C-Ausdruck, der den Median der 5 Zahlen a, b,
c, d und e mit der minimalen Anzahl von Vergleichen (6) und ohne die
Verwendung temporärer Variablen ermittelt:
1
median5=b<a?d<c?b<d?a<e?a<d?e<d?e:d
2
:c<a?c:a
3
:e<d?a<d?a:d
4
:c<e?c:e
5
:c<e?b<c?a<c?a:c
6
:e<b?e:b
7
:b<e?a<e?a:e
8
:c<b?c:b
9
:b<c?a<e?a<c?e<c?e:c
10
:d<a?d:a
11
:e<c?a<c?a:c
12
:d<e?d:e
13
:d<e?b<d?a<d?a:d
14
:e<b?e:b
15
:b<e?a<e?a:e
16
:d<b?d:b
17
:d<c?a<d?b<e?b<d?e<d?e:d
18
:c<b?c:b
19
:e<d?b<d?b:d
20
:c<e?c:e
21
:c<e?a<c?b<c?b:c
22
:e<a?e:a
23
:a<e?b<e?b:e
24
:c<a?c:a
25
:a<c?b<e?b<c?e<c?e:c
26
:d<b?d:b
27
:e<c?b<c?b:c
28
:d<e?d:e
29
:d<e?a<d?b<d?b:d
30
:e<a?e:a
31
:a<e?b<e?b:e
32
:d<a?d:a;
Die Idee ist nicht von mir, ich kann nur gerade die Webseite, von der
ich den Code geklaut habe, nicht mehr finden.
Lothar M. schrieb:> Dabei verlässt du dich aber> darauf, dass es keine 2 Ausreißer in die selbe Richtung gibt.
In dem Fall ist das richtig.
Ich schrieb ja auch, das man das Array oben und unten erweitern kann.
Dann muss man allerdings Bubblesort auch 2 oder mehrmals über die Daten
laufen lassen, ja nachdem wie weit man es erweitert.
Das kommt ganz auf die Daten an und auf das Messintervall.
Yalu X. schrieb:> Eine sinnvolle Fenstergröße für die Medianbildung ist 5
Ich habe mich bewusst für 6 Werte entschieden von denen ich 2 verwerfe
und somit auf 4 Werte komme, die ich verarbeiten muss, damit ich nicht
dividieren muss sondern das Ergebnis der Addition einfach nach rechts
verschieben kann, weil das Programmspeicher und Rechenschritte spart.
Denn einfache Schiebeoperationen können Mikrocontroller meist schneller
erledigen als eine Division.
Aber ansonsten stimme ich Dir voll und ganz zu.
Frank
Frank B. (frank501)
>Vielleicht nicht das allerschnellste, aber für meine Verhältnisse>ausreichend:>Ich schreibe die Sensordaten fortlaufend in ein Array mit 6 Feldern.{1}
Hallo Frank,
Dein Verfahren entspricht der "trimmean" Funktion in Matlab/Octave.
Du schneidest oben und unten einen Wert ab, also 100%/6.
1
octave:28> a
2
a =
3
4
63 54 102 59 11 61
5
6
octave:29> trimmean(a,100/6)
7
ans = 59.250
Wenn ich die Erklärung auf der Matlab Homepage richtig verstehe, müsste
man als Parameter zwar 2*100/6 angeben, aber in Octave funktioniert
scheinbar mit 100/6.
http://de.mathworks.com/help/stats/trimmean.html
Um aus einer Menge Messwerte einen passenden zu finden: median
Um einen ausreisse ansonsten zu identifizieren: Alle Messwerte (bzw.
eine ausreichend große Teilmenge) speichern, und alle wegwerfen die
jenseits von x-Sigma vom Mittelwert entfernt sind. Das ersprt die ex
ante Kenntnis von DIFMAX
Frank B. schrieb:> Yalu X. schrieb:>> Eine sinnvolle Fenstergröße für die Medianbildung ist 5>> Ich habe mich bewusst für 6 Werte entschieden von denen ich 2 verwerfe> und somit auf 4 Werte komme, die ich verarbeiten muss, damit ich nicht> dividieren muss
Ja, wenn man die Ausreißersuche sowieso mit einer Mittelwertbildung
kombinieren will, sind 2+2**n Werte ideal.
Wenn man lieber ein reines Medianfilter ohne Mittelung will, ist eine
ungerade Anzahl von Werten aus zwei Grunden vorteilhaft:
- Der Median ist klar als einer der n Werte definiert und muss nicht
erst noch durch Mittelung des Unter- und Obermedians berechnet werden.
- Bei einer monotonen Folge von Eingangswerten kommen diese (bis auf ein
paar am Anfang und am Ende) unverändert am Ausgang des Filters wieder
heraus. Das ist dann wichtig, wenn man zwar die Ausreißer entfernen,
aber kleinere Schwankungen in den Messwerten weitgehend beibehalten
und nicht einfach glattbügeln möchte.
Markus schrieb:> welche Methoden verwendet ihr, um Ausreißer z.B. von einem Sensor weg zu> filtern?
3 Sigma-Korrektur. Messwerte ausserhalb 3 Sigma werden gestrichen und
die Standardabweichung neu berechnet, dann wieder die Ausreisser
streichen usw. bis keine mehr auftreten.
Grundlage: es muss sich um eine Standardverteilung der Messwerte
handeln. Ist das der Fall, kommen Messwerte ausserhalb der dreifachen
Standardabweichung so extrem selten vor, dass man sie zu Messfehlern
erklären kann bzw. muss.
Solche Messwerte haben überhaupt keinen Einfluss mehr, andere Filter wie
Medianfilter leisten das nicht.
Georg