在我的项目中,我有一个由算法计算的20,000个点的表面。该算法有时会出错,在小区域内错误地计算1个或多个点。
此错误无法在算法中解决,但需要在之后检测。
错误可以在下图中看到:
正如你所看到的,有一个错误的计算点不仅打破了完整的均匀表面,而且还破坏了情节的遗传(在项目中也很重要。)
有时它可能不止一个点,一般不超过5或6.错误总是Z轴,所以不需要检查X和Y
我一直在努力寻找一种“通用”算法来检测这些poitns。 我认为可能会采用表面补片并表示Z,然后检测出方差中的点......但我认为它不会起作用。
有什么想法吗?
注意:我不希望有人为我编写代码,只是一个想法。
PD:avobe图像的相关代码:
[x,y] = meshgrid([-2:.07:2]);
Z = x.*exp(-x.^2-y.^2);
subplot(1,2,1)
surf(x,y,Z,gradient(Z))
subplot(1,2,2)
Z(35,35)=Z(35,35)+0.3;
surf(x,y,Z,gradient(Z))
答案 0 :(得分:3)
标准技巧是使用拉普拉斯算子,寻找最大的异常值。 (这与Mohsen的答案没有什么不同,但实际上有点容易。)你甚至可以用conv2来做,所以它会非常有效。
我可以提供一些方法来实现这个想法。一个简单的方法是使用我在文件交换中找到的gridfit工具。 (Gridfit基本上使用拉普拉斯算子进行平滑操作。)使用包含的所有点拟合曲面,然后查找由拟合最扰动的单个点。排除它,然后重新运行拟合,再次寻找最大的异常值。 (使用gridfit,您可以使用权重来为点赋予零权重,这是一种排除点或点列表的简单方法。)当需要的最大扰动足够小时,您可以决定停止该过程。一个好处是gridfit还会为异常值估算新值,填补所有漏洞。
第二种方法是直接使用拉普拉斯算子,更多的是过滤方法。在这里,您只需计算每个点的值,该值是左,右,上,下各个邻居的平均值。最大程度上与其计算平均值不一致的单个值将替换为新值。或者,您可以使用旧值的加权平均值。再次,迭代直到该过程不生成大于某个容差的任何内容。 (这是我从Fortran IMSL库中回忆起的旧异常值检测和校正方案的基础,但可能追溯到大约30年前。)
答案 1 :(得分:2)
由于您的功能似乎变化平稳,因此可以通过查看衍生物来检测这些突然变化。你可以
这是代码
U=diff(Z);
V=(U-mean(U(:)))/std(U(:));
surf(x(2:end,:),y(2:end,:),V)
V=[zeros(1,size(V,2)); V];
V(abs(V)<10)=0;
V=sign(V);
W=cumsum(V);
[I,J]=find(W);
outliers = [I, J];
对于您的示例,您获得V
的这个图,其峰值在21.7左右,而第二个峰值在1.9528左右,因此可能是10的阈值。
并运行代码返回
outliers =
35 35
cumsum
的需要是针对那些彼此相邻的点不正确的情况。