これはいい質問です。
@amoebaの提案に従い、depth::med()
with を使用して空間中央値をブートストラップしmethod="Spatial"
ます。ただし、少し複雑です。med
データポイントが重複している場合は気に入らないため、簡単なブートストラップは実行できません。代わりに、ブートストラップサンプルを描画し、空間の中央値を計算する前に、各ポイントをわずかな量(元のデータサンプルのと各次元の最小距離未満)だけジッターします。xy
最後に、ブートストラップされた中央値の指定された比率(95%)をカバーする最小の楕円を計算してプロットします。
library(depth) # for med()
library(MASS) # for cov.rob()
library(cluster) # for ellipsoidhull()
# create data
set.seed(1)
df <- data.frame(x = rnorm(200, mean = 4, sd = 1.5),
y = rnorm(200, mean = 1.4, sd = 2.5))
# find minimum distances in each dimension for later jittering
foo <- outer(X=df$x,Y=df$x,FUN=function(xx,yy)abs(xx-yy))
delta.x <- min(foo[upper.tri(foo)])/2
foo <- outer(X=df$y,Y=df$y,FUN=function(xx,yy)abs(xx-yy))
delta.y <- min(foo[upper.tri(foo)])/2
# bootstrap spatial medians, using jittering
n.boot <- 1000
pb <- winProgressBar(max=n.boot)
boot.med <- matrix(NA,nrow=n.boot,ncol=2)
for ( ii in 1:n.boot ) {
setWinProgressBar(pb,ii,paste(ii,"of",n.boot))
index <- sample(1:nrow(df),nrow(df),replace=TRUE)
bar <- df[index,] +
data.frame(x=runif(nrow(df),-delta.x,delta.x),
y=runif(nrow(df),-delta.y,delta.y))
boot.med[ii,] <- med(bar,method="Spatial")$median
}
close(pb)
# specify confidence level
pp <- 0.95
# find smallest ellipse containing the specified proportion of bootstrapped medians
fit <- cov.rob(boot.med, quantile.used = ceiling(pp*n.boot), method = "mve")
best_ellipse <- ellipsoidhull( boot.med[fit$best,] )
plot(df)
points(boot.med,pch=19,col="grey",cex=0.5)
points(df)
lines(predict(best_ellipse), col="red")
legend("bottomright",bg="white",pch=c(21,19,NA),
col=c("black","grey","red"),pt.bg=c("white",NA,NA),lwd=c(0,0,1),
legend=c("Observations","Bootstrapped medians","Confidence ellipse"))
最後に、2変量の空間中央値は漸近的に正規分布していることに注意してください(Brown、1983、JRSS、Series B)。したがって、上記の「ジッターブートストラップ」を省略して、楕円を直接計算し、が「十分に漸近的」であると信頼できます。 」次の日の時間があれば、この投稿を編集して、このパラメトリック信頼楕円を含めることができます。n=200