A questão pede maneiras de usar vizinhos mais próximos em uma robusta forma de identificar e valores atípicos localizados corretos. Por que não fazer exatamente isso?
O procedimento é calcular um bom local robusto, avaliar os resíduos e zerar qualquer que seja muito grande. Isso satisfaz todos os requisitos diretamente e é flexível o suficiente para se ajustar a diferentes aplicativos, porque é possível variar o tamanho da vizinhança local e o limite para a identificação de valores extremos.
(Por que a flexibilidade é tão importante? Como qualquer procedimento desse tipo tem uma boa chance de identificar certos comportamentos localizados como sendo "periféricos". Como tal, todos esses procedimentos podem ser considerados " smoothers" . Eles eliminam alguns detalhes juntamente com os aparentemente estranhos. precisa de algum controle sobre o compromisso entre reter os detalhes e não detectar os outliers locais.)
Outra vantagem desse procedimento é que ele não requer uma matriz retangular de valores. De fato, ele pode ser aplicado a dados irregulares usando um local mais adequado para esses dados.
R
, assim como a maioria dos pacotes de estatísticas com todos os recursos, possui vários smoothers locais robustos incorporados, como loess
. O exemplo a seguir foi processado usando-o. A matriz possui linhas e 49 colunas - quase 4000 entradas. Representa uma função complicada com vários extremos locais, bem como uma linha inteira de pontos onde não é diferenciável (um "vinco"). Para um pouco mais do que 5 % dos pontos - uma proporção muito elevada para ser considerada "periféricas" - foram adicionados erros Gaussianas cujo desvio padrão é de apenas 1 / 20 do desvio padrão dos dados originais. Este conjunto de dados sintético apresenta, portanto, muitos dos recursos desafiadores de dados realistas.794940005%1/20
Observe que (conforme R
convenções) as linhas da matriz são desenhadas como faixas verticais. Todas as imagens, exceto os resíduos, são sombreadas para ajudar a exibir pequenas variações em seus valores. Sem isso, quase todos os outliers locais seriam invisíveis!
(0,79)(49,30)
As manchas na trama "Residuais" mostram os óbvios outliers locais isolados. Esse gráfico também exibe outra estrutura (como a faixa diagonal) atribuível aos dados subjacentes. Alguém poderia melhorar esse procedimento usando um modelo espacial dos dados ( por métodos geoestatísticos), mas descrever isso e ilustrá-lo nos levaria muito longe aqui.
1022003600
#
# Create data.
#
set.seed(17)
rows <- 2:80; cols <- 2:50
y <- outer(rows, cols,
function(x,y) 100 * exp((abs(x-y)/50)^(0.9)) * sin(x/10) * cos(y/20))
y.real <- y
#
# Contaminate with iid noise.
#
n.out <- 200
cat(round(100 * n.out / (length(rows)*length(cols)), 2), "% errors\n", sep="")
i.out <- sample.int(length(rows)*length(cols), n.out)
y[i.out] <- y[i.out] + rnorm(n.out, sd=0.05 * sd(y))
#
# Process the data into a data frame for loess.
#
d <- expand.grid(i=1:length(rows), j=1:length(cols))
d$y <- as.vector(y)
#
# Compute the robust local smooth.
# (Adjusting `span` changes the neighborhood size.)
#
fit <- with(d, loess(y ~ i + j, span=min(1/2, 125/(length(rows)*length(cols)))))
#
# Display what happened.
#
require(raster)
show <- function(y, nrows, ncols, hillshade=TRUE, ...) {
x <- raster(y, xmn=0, xmx=ncols, ymn=0, ymx=nrows)
crs(x) <- "+proj=lcc +ellps=WGS84"
if (hillshade) {
slope <- terrain(x, opt='slope')
aspect <- terrain(x, opt='aspect')
hill <- hillShade(slope, aspect, 10, 60)
plot(hill, col=grey(0:100/100), legend=FALSE, ...)
alpha <- 0.5; add <- TRUE
} else {
alpha <- 1; add <- FALSE
}
plot(x, col=rainbow(127, alpha=alpha), add=add, ...)
}
par(mfrow=c(1,4))
show(y, length(rows), length(cols), main="Data")
y.res <- matrix(residuals(fit), nrow=length(rows))
show(y.res, length(rows), length(cols), hillshade=FALSE, main="Residuals")
#hist(y.res, main="Histogram of Residuals", ylab="", xlab="Value")
# Increase the `8` to find fewer local outliers; decrease it to find more.
sigma <- 8 * diff(quantile(y.res, c(1/4, 3/4)))
mu <- median(y.res)
outlier <- abs(y.res - mu) > sigma
cat(sum(outlier), "outliers found.\n")
# Fix up the data (impute the values at the outlying locations).
y.imp <- matrix(predict(fit), nrow=length(rows))
y.imp[outlier] <- y[outlier] - y.res[outlier]
show(y.imp, length(rows), length(cols), main="Imputed")
show(y.real, length(rows), length(cols), main="Real")