我应该如何平滑 3D 表面上的异常值?

How should I smooth the outliers on a 3D surface?

我从包裹 akima 中取出了一个 3D 表面。

library(akima)
data(akima)
matrix_1 <- akima::interp(x = akima$x, y = akima$y, z = akima$z)
persp(matrix_1$x, matrix_1$y, matrix_1$z)

在这个表面上,我添加了一些异常数据点。

# Add outliers
akima$x = c(akima$x, 11, 12, 13)
akima$y = c(akima$y, 11, 12, 13)
akima$z = c(akima$z, 70, 80, 75)
matrix_2 <- akima::interp(x = akima$x, y = akima$y, z = akima$z)
persp(x = matrix_2$x, y = matrix_2$y, z = matrix_2$z)

新表面看起来像 -

现在,我想在不干扰原始表面的情况下将这些异常值平滑到原始表面,但我无法做到这一点。这是我尝试过的方法,如果有人能告诉我如何做到这一点,我将不胜感激。

# Trying to smooth and remove outliers
library(mgcv)
mod <- gam(z ~ te(x) + te(y) + ti(x, y), data = akima)
akima$new = predict(mod, akima)

matrix_3 <- akima::interp(x = akima$x, y = akima$y, z = akima$new)
persp(matrix_3$x, matrix_3$y, matrix_3$z)

这里是用gam平滑后的表面,这不是预期的输出。预期输出是第一个具有异常值新值的图表。

这更像是一个统计问题而不是计算问题,但一种方法是查看 gam() 拟合的残差大小,并且仅在以下情况下修改 z 坐标残差特别大

例如:

library(akima)
data(akima)

akima$x <- c(akima$x, 11, 12, 13)
akima$y <- c(akima$y, 11, 12, 13)
akima$z <- c(akima$z, 70, 80, 75)

# Trying to smooth and remove outliers
library(mgcv)
#> Warning: package 'mgcv' was built under R version 4.1.2
#> Loading required package: nlme
#> Warning: package 'nlme' was built under R version 4.1.2
#> This is mgcv 1.8-39. For overview type 'help("mgcv-package")'.
mod <- gam(z ~ te(x) + te(y) + ti(x, y), data = akima)
akima$pred <- predict(mod, akima)
akima$resid <- akima$z - akima$pred
hist(akima$resid)

akima$new <- ifelse(akima$resid < 25, akima$z, akima$pred)
matrix_3 <- akima::interp(x = akima$x, y = akima$y, z = akima$new)
persp(matrix_3$x, matrix_3$y, matrix_3$z)

reprex package (v2.0.1)

于 2022-03-29 创建

我只是目测选择了25这个截止点;如果您想使用更自动的方法,您需要在 stats.stackexchange.com 上询问。您还可以进行一些迭代,以获得更好的预测而不包括异常值。同样,这是一个统计问题。