2010-09-17 12 views
1

J'ai plusieurs séries de points de données à représenter graphiquement. Pour chaque graphique, il peut être nécessaire d'éliminer certains points en raison d'une erreur. Un exemple est le suivant: alt textComment devrais-je filtrer ces données?

Les zones encerclées sont des erreurs dans les données.

Ce que je besoin est un algorithme pour filtrer ces données afin qu'il élimine l'erreur en remplaçant les mauvais points avec des lignes plates, comme ceci:

alt text

Y a-t-il des algorithmes là-bas qui sont particulièrement bon à détecter les points d'erreur? Avez-vous des conseils qui pourraient me diriger dans la bonne direction?

EDIT: Les points d'erreur sont des points qui ne semblent pas cohérents avec les données des deux côtés. Il peut y avoir de gros sauts, tant que les données après le saut semblent toujours cohérentes. Si c'est sur le bord du graphique, les gros sauts devraient probablement être considérés comme des erreurs.

+0

Comment définissez-vous exactement les points d'erreur? – IVlad

+0

@IVlad La réponse est dans l'édition. – Phil

Répondre

2

Il s'agit d'un problème difficile à résoudre de manière générique; Votre solution finale sera très dépendante du processus et unique à votre situation. Cela dit, vous devez commencer par comprendre vos données: d'un échantillon à l'autre, quel genre de variation est possible? En utilisant cela, vous pouvez utiliser des échantillons de données précédents (et peut-être de futurs échantillons de données) pour décider si l'échantillon actuel est faux ou non. Ensuite, vous vous retrouverez avec un filtre qui ressemble à quelque chose comme:

const int MaxQueueLength = 100;   // adjust these two values as necessary 
    const double MaxProjectionError = 5; 

    List<double> FilterData(List<double> rawData) 
    { 
     List<double> toRet = new List<double>(rawData.Count); 
     Queue<double> history = new Queue<double>(MaxQueueLength); // adjust queue length as necessary 
     foreach (double raw_Sample in rawData) 
     { 
      while (history.Count > MaxQueueLength) 
       history.Dequeue(); 
      double ProjectedSample = GuessNext(history, raw_Sample); 
      double CurrentSample = (Math.Abs(ProjectedSample - raw_Sample) > MaxProjectionError) ? ProjectedSample : raw_Sample; 
      toRet.Add(CurrentSample); 
      history.Enqueue(CurrentSample); 
     } 
     return toRet; 
    } 

La magie est donc à venir avec votre fonction GuessNext. Ici, vous aborderez des sujets spécifiques à votre situation et vous devrez tenir compte de tout ce que vous savez du processus de collecte de données. Y a-t-il des limites physiques à la rapidité avec laquelle l'entrée peut changer? Vos données ont-elles de mauvaises valeurs que vous pouvez facilement filtrer?

Voici un exemple simple pour une fonction GuessNext qui fonctionne hors de la dérivée première de vos données (il suppose que vos données est un regard à peu près une ligne droite lorsque vous seulement à une petite partie de celui-ci)

double lastSample = double.NaN; 
double GuessNext(Queue<double> history, double nextSample) 
{ 
    lastSample = double.IsNaN(lastSample) ? nextSample : lastSample; 
    //ignore the history for simple first derivative. Assume that input will always approximate a straight line 
    double toRet = (nextSample + (nextSample - lastSample)); 
    lastSample = nextSample; 
    return toRet; 
} 

Si vos données sont particulièrement bruitées, vous pouvez appliquer un filtre de lissage avant de les transmettre à GuessNext. Vous aurez juste à passer du temps avec l'algorithme pour trouver quelque chose qui a du sens pour vos données.

Vos données d'exemple semblent être paramétriques en ce sens que chaque échantillon définit à la fois une valeur X et une valeur Y. Vous pourriez peut-être appliquer la logique ci-dessus à chaque dimension indépendamment, ce qui serait approprié si une seule dimension est celle qui vous donne de mauvais nombres. Cela peut être particulièrement efficace dans les cas où une dimension est un horodatage, par exemple, et l'horodatage est parfois faux.

0

Si le retrait des valeurs aberrantes n'est pas possible, essayez de kriguer (avec des termes d'erreur) comme dans http://www.ipf.tuwien.ac.at/cb/publications/pipeline.pdf. Cela semble fonctionner assez bien pour traiter automatiquement le bruit extrême occasionnel. Je sais que les météorologistes français utilisent une telle approche pour supprimer les valeurs aberrantes dans leurs données (comme un feu à côté d'un capteur de température ou quelque chose qui frappe un capteur de vent par exemple).

Veuillez noter que c'est un problème difficile en général. Toute information sur les erreurs est précieuse. Quelqu'un a-t-il lancé l'appareil de mesure? Ensuite, vous ne pouvez pas faire grand-chose sauf supprimer les données incriminées à la main. Est-ce que votre bruit est systématique?Vous pouvez faire beaucoup de choses en faisant des hypothèses (raisonnables) à ce sujet.