我有几个数据点需要用图表表示对于每个图,由于错误,可能需要抛出一些点一个例子如下:
带圆圈的区域是数据中的错误。
我需要的是一个算法来过滤这些数据,这样它就可以通过用平线替换坏点来消除错误,如下所示:
有没有什么算法特别擅长检测错误点?你有什么能给我指点正确方向的建议吗?
编辑:错误点是任何看起来与两边的数据不一致的点。只要跳转后的数据看起来仍然一致,就可能出现较大的跳转。如果它在图的边缘,大的跳跃应该被认为是错误的。

最佳答案

这是一个很难一般性地解决的问题;最终的解决方案将非常依赖于流程,并且是您的情况所独有的。
也就是说,你需要从理解你的数据开始:从一个样本到下一个样本,什么样的变化是可能的使用它,您可以使用以前的数据样本(可能还有将来的数据样本)来确定当前样本是否是假的然后,你会得到一个过滤器,看起来像:

    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;
    }

那么,神奇之处就在于你的猜测功能。在这里,您将进入特定于您的情况的内容,并且应该考虑您所知道的有关收集数据的过程的所有信息。输入变化的速度有物理限制吗您的数据是否知道可以轻松筛选的错误值?
下面是一个简单的例子,它是根据数据的一阶导数(即,当你只看一小段数据时,它假设你的数据是一条大致的直线)
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;
}

如果您的数据特别嘈杂,在将其传递给GuessNext之前,您可能需要对其应用平滑过滤器。你只需要花点时间研究一下算法,就可以想出一些对你的数据有意义的东西。
示例数据似乎是参数化的,因为每个示例都定义x和y值。您可能能够独立地将上述逻辑应用于每个维度,如果只有一个维度给出了错误的数字,这将是合适的。例如,在一维是时间戳,而时间戳有时是假的情况下,这种方法尤其成功。

10-08 06:39
查看更多