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.
Comment définissez-vous exactement les points d'erreur? – IVlad
@IVlad La réponse est dans l'édition. – Phil