이변 량 정규 분포 데이터에서 타원 영역을 얻는 방법은 무엇입니까?


13

다음과 같은 데이터가 있습니다.

그림

나는 정규 분포 (커널 밀도 추정은 더 잘 작동하지만 그렇게 큰 정밀도는 필요하지 않음)를 적용하려고 시도했으며 꽤 잘 작동합니다. 밀도 플롯은 타원을 만듭니다.

점이 타원 영역 내에 있는지 여부를 결정하려면 타원 함수를 가져와야합니다. 그렇게하는 방법?

R 또는 Mathematica 코드는 환영합니다.

답변:


18

Corsario는 주석에서 좋은 솔루션을 제공합니다. 커널 밀도 함수를 사용하여 레벨 세트에 포함되는지 테스트하십시오.

이 질문에 대한 또 다른 해석은 데이터 에 대한 이변 량 정규 근사에 의해 생성 된 타원에 포함되는지 테스트하는 절차를 요청한다는 것 입니다. 시작하려면 질문의 그림처럼 보이는 데이터를 생성 해 보겠습니다.

library(mvtnorm) # References rmvnorm()
set.seed(17)
p <- rmvnorm(1000, c(250000, 20000), matrix(c(100000^2, 22000^2, 22000^2, 6000^2),2,2))

타원은 데이터의 첫 번째 순간과 두 번째 순간에 의해 결정됩니다.

center <- apply(p, 2, mean)
sigma <- cov(p)

이 수식 에는 분산 공분산 행렬의 반전이 필요합니다.

sigma.inv = solve(sigma, matrix(c(1,0,0,1),2,2))

타원 "높이"함수는 이변 량 정규 밀도 의 로그의 음수입니다 .

ellipse <- function(s,t) {u<-c(s,t)-center; u %*% sigma.inv %*% u / 2}

( 같은 추가 상수를 무시했습니다 .)log(2πdet(Σ))

이것을 테스트하기 위해 윤곽선을 그려 봅시다. x 및 y 방향으로 점 그리드를 생성해야합니다.

n <- 50
x <- (0:(n-1)) * (500000/(n-1))
y <- (0:(n-1)) * (50000/(n-1))

이 그리드에서 높이 함수를 계산하고 플로팅하십시오.

z <- mapply(ellipse, as.vector(rep(x,n)), as.vector(outer(rep(0,n), y, `+`)))
plot(p, pch=20, xlim=c(0,500000), ylim=c(0,50000), xlab="Packets", ylab="Flows")
contour(x,y,matrix(z,n,n), levels=(0:10), col = terrain.colors(11), add=TRUE)

등고선 플롯

분명히 작동합니다. 따라서 점 이 레벨의 타원형 윤곽 안에 있는지 여부를 확인하는 테스트 는 다음과 같습니다.(s,t)c

ellipse(s,t) <= c

Mathematica 는 같은 방식으로 작업을 수행합니다. 데이터의 분산 공분산 행렬을 계산하고, 반전하고, ellipse함수를 구성하면 모든 준비가 완료됩니다.


감사합니다. 특히 @whuber. 이것이 바로 내가 필요한 것입니다.
matejuh

Btw. 커널 밀도 추정 윤곽선에 대한 간단한 해결책이 있습니까? 좀 더 엄격하게하려면 내 데이터는 다음과 같습니다. github.com/matejuh/doschecker_wiki_images/raw/master/… resp. github.com/matejuh/doschecker_wiki_images/raw/master/…
matejuh

R에서 간단한 해결책을 찾을 수 없습니다. Mathematica 8의 "SmoothKernelDistribution"기능 사용을 고려하십시오 .
whuber

2
수준이 신뢰 수준에 해당합니까? 나는 그렇게 생각하지 않습니다. 어떻게하면 좋을까요?
matejuh

새로운 질문이 필요합니다. 왜냐하면 자신이 원하는 것을 명시 하고 플롯에서 판단 할 필요가 있기 때문에 그러한 타원이 데이터에 대한 적절한 설명인지에 대한 우려가 있습니다.
whuber

10

플롯은 R ellipse()에 대한 mixtools패키지 의 기능으로 간단합니다 .

library(mixtools)
library(mvtnorm) 
set.seed(17)
p <- rmvnorm(1000, c(250000, 20000), matrix(c(100000^2, 22000^2, 22000^2, 6000^2),2,2))
plot(p, pch=20, xlim=c(0,500000), ylim=c(0,50000), xlab="Packets", ylab="Flows")
ellipse(mu=colMeans(p), sigma=cov(p), alpha = .05, npoints = 250, col="red") 

여기에 이미지 설명을 입력하십시오


5

첫 번째 접근법

Mathematica에서이 접근법을 시도 할 수 있습니다.

이변 량 데이터를 생성 해 봅시다 :

data = Table[RandomVariate[BinormalDistribution[{50, 50}, {5, 10}, .8]], {1000}];

그런 다음이 패키지를로드해야합니다.

Needs["MultivariateStatistics`"]

그리고 지금:

ellPar=EllipsoidQuantile[data, {0.9}]

90 % 신뢰 타원을 정의하는 출력을 제공합니다. 이 출력에서 ​​얻은 값은 다음 형식입니다.

{Ellipsoid[{x1, x2}, {r1, r2}, {{d1, d2}, {d3, d4}}]}

x1 및 x2는 타원이 중심이되는 지점을 지정하고 r1 및 r2는 반축 반경을 지정하고 d1, d2, d3 및 d4는 정렬 방향을 지정합니다.

이것을 플롯 할 수도 있습니다.

Show[{ListPlot[data, PlotRange -> {{0, 100}, {0, 100}}, AspectRatio -> 1],  Graphics[EllipsoidQuantile[data, 0.9]]}]

타원의 일반적인 파라 메트릭 형태는 다음과 같습니다.

ell[t_, xc_, yc_, a_, b_, angle_] := {xc + a Cos[t] Cos[angle] - b Sin[t] Sin[angle],
    yc + a Cos[t] Sin[angle] + b Sin[t] Cos[angle]}

그리고 당신은 이런 식으로 그것을 그릴 수 있습니다 :

ParametricPlot[
    ell[t, ellPar[[1, 1, 1]], ellPar[[1, 1, 2]], ellPar[[1, 2, 1]], ellPar[[1, 2, 2]],
    ArcTan[ellPar[[1, 3, 1, 2]]/ellPar[[1, 3, 1, 1]]]], {t, 0, 2 \[Pi]},
    PlotRange -> {{0, 100}, {0, 100}}]

순수한 기하 정보를 기반으로 검사를 수행 할 수 있습니다. 타원 중심 (ellPar [[1,1]])과 데이터 점 사이의 유클리드 거리가 타원 중심과 경계 사이의 거리보다 큰 경우 타원 (분명히 포인트가 위치한 방향과 동일)에 해당 데이터 포인트가 타원 외부에 있습니다.

두 번째 접근법

이 방법은 원활한 커널 배포를 기반으로합니다.

다음은 데이터와 유사한 방식으로 배포 된 일부 데이터입니다.

data1 = RandomVariate[BinormalDistribution[{.3, .7}, {.2, .3}, .8], 500];
data2 = RandomVariate[BinormalDistribution[{.6, .3}, {.4, .15}, .8], 500];
data = Partition[Flatten[Join[{data1, data2}]], 2];

이러한 데이터 값에 대한 원활한 커널 분포를 얻습니다.

skd = SmoothKernelDistribution[data];

각 데이터 포인트에 대한 숫자 결과를 얻습니다.

eval = Table[{data[[i]], PDF[skd, data[[i]]]}, {i, Length[data]}];

임계 값을 수정하고이 임계 값보다 높은 모든 데이터를 선택합니다.

threshold = 1.2;
dataIn = Select[eval, #1[[2]] > threshold &][[All, 1]];

다음은 해당 지역을 벗어난 데이터를 얻습니다.

dataOut = Complement[data, dataIn];

이제 모든 데이터를 플로팅 할 수 있습니다.

Show[ContourPlot[Evaluate@PDF[skd, {x, y}], {x, 0, 1}, {y, 0, 1}, PlotRange -> {{0, 1}, {0, 1}}, PlotPoints -> 50],
ListPlot[dataIn, PlotStyle -> Darker[Green]],
ListPlot[dataOut, PlotStyle -> Red]]

녹색 점은 임계 값보다 높은 점이고 빨간색 점은 임계 값보다 낮은 점입니다.

여기에 이미지 설명을 입력하십시오


감사합니다. 두 번째 방법은 커널 배포에 많은 도움이됩니다. 나는 통계가 아닌 프로그래머이고 Mathmatica와 R의 초보자이므로 도움을 많이 주셔서 감사합니다. 두 번째 접근 방식에서는 한 지점을 테스트하는 방법이 분명합니다. 그러나 첫 번째 접근 방식에서 어떻게해야합니까? 내 포인트를 타원체 정의와 비교해야한다고 가정합니다. 어떻게 제공 할 수 있습니까? RinRuby에서 사용해야하기 때문에 R에 동일한 정의가 있기를 바랍니다.
matejuh

@matejuh 방금 솔루션으로 안내하는 첫 번째 접근 방식에 대해 몇 줄을 더 추가했습니다.
VLC

2

R 패키지 의 ellipse함수는 ellipse이러한 타원 (실제로 타원에 가까운 다각형)을 생성합니다. 그 타원을 사용할 수 있습니다.

실제로 더 쉬운 것은 점에서 밀도의 높이를 계산하고 타원의 윤곽 값보다 높은지 (타원 내부) 또는 낮은 지 (타원 외부)인지 확인하는 것입니다. ellipse기능 내부는 사용 는 사용 높이를 찾는이 시작할 수, 타원을 만들 값입니다.χ2


1

/programming/2397097/how-can-a-data-ellipse-be-superimposed-on-a-ggplot2-scatterplot 에서 답을 찾았습니다.

#bootstrap
set.seed(101)
n <- 1000
x <- rnorm(n, mean=2)
y <- 1.5 + 0.4*x + rnorm(n)
df <- data.frame(x=x, y=y, group="A")
x <- rnorm(n, mean=2)
y <- 1.5*x + 0.4 + rnorm(n)
df <- rbind(df, data.frame(x=x, y=y, group="B"))

#calculating ellipses
library(ellipse)
df_ell <- data.frame()
for(g in levels(df$group)){
df_ell <- rbind(df_ell, cbind(as.data.frame(with(df[df$group==g,], ellipse(cor(x, y), 
                                         scale=c(sd(x),sd(y)), 
                                         centre=c(mean(x),mean(y))))),group=g))
}
#drawing
library(ggplot2)
p <- ggplot(data=df, aes(x=x, y=y,colour=group)) + geom_point(size=1.5, alpha=.6) +
  geom_path(data=df_ell, aes(x=x, y=y,colour=group), size=1, linetype=2)

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.