Làm thế nào để có được khu vực hình elip từ dữ liệu phân phối bình thường?


11

Tôi có dữ liệu giống như:

Nhân vật

Tôi đã cố gắng áp dụng phân phối bình thường (ước tính mật độ hạt nhân hoạt động tốt hơn, nhưng tôi không cần độ chính xác cao như vậy) trên đó và nó hoạt động khá tốt. Mật độ âm mưu làm cho một hình elip.

Tôi cần phải có chức năng hình elip đó để quyết định xem một điểm có nằm trong vùng của hình elip hay không. Làm thế nào để làm điều đó?

Mã R hoặc Mathicala được hoan nghênh.

Câu trả lời:


18

Corsario cung cấp một giải pháp tốt trong một nhận xét: sử dụng hàm mật độ nhân để kiểm tra sự bao gồm trong một tập cấp.

Một cách giải thích khác của câu hỏi là nó yêu cầu một thủ tục để kiểm tra sự bao gồm trong các hình elip được tạo bởi một xấp xỉ bình thường hai biến với dữ liệu. Để bắt đầu, hãy tạo một số dữ liệu giống như minh họa trong câu hỏi:

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))

Các hình elip được xác định bởi khoảnh khắc thứ nhất và thứ hai của dữ liệu:

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

Công thức yêu cầu đảo ngược ma trận phương sai hiệp phương sai:

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

Hàm "chiều cao" hình elip là âm của logarit của mật độ chuẩn bivariate :

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

(Tôi đã bỏ qua hằng số phụ gia bằng .)log(2πdet(Σ))

Để kiểm tra điều này , hãy vẽ một số đường viền của nó. Điều đó đòi hỏi phải tạo ra một lưới các điểm theo hướng x và y:

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

Tính toán hàm chiều cao tại lưới này và vẽ đồ thị:

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)

Đường viền

Rõ ràng là nó hoạt động. Do đó, kiểm tra để xác định xem một điểm dối trá bên trong một đường viền hình elip ở mức làc(s,t)c

ellipse(s,t) <= c

Mathematica thực hiện công việc theo cùng một cách: tính toán ma trận phương sai hiệp phương sai của dữ liệu, đảo ngược điều đó, xây dựng ellipsehàm và bạn đã thiết lập xong.


Cảm ơn tất cả các bạn, đặc biệt là @whuber. Đây chính xác là những gì tôi cần.
matejuh

Btw. Có giải pháp đơn giản nào cho các đường viền ước tính mật độ hạt nhân không? Bởi vì nếu tôi muốn nghiêm ngặt hơn, dữ liệu của tôi sẽ trông như: github.com/matejuh/doschecker_wiki_images/raw/master/ đá resp. github.com/matejuh/doschecker_wiki_images/raw/master/ory
matejuh

Tôi không thể tìm thấy một giải pháp đơn giản trong R. Xem xét sử dụng chức năng "SmoothKernelDistribution" của Mathematica 8.
whuber

2
Liệu các cấp độ coresponds đến mức độ tự tin? Tôi không nghĩ vậy. Làm thế nào tôi có thể làm điều đó xin vui lòng?
matejuh

Điều đó cần một câu hỏi mới, bởi vì bạn cần xác định những gì bạn tìm kiếm sự tự tin và - đánh giá từ các âm mưu của bạn - có những lo ngại về việc liệu các dấu chấm lửng như vậy có phải là mô tả đầy đủ về dữ liệu ở vị trí đầu tiên hay không.
whuber

9

Cốt truyện đơn giản với ellipse()chức năng của mixtoolsgói cho R:

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") 

nhập mô tả hình ảnh ở đây


5

Cách tiếp cận đầu tiên

Bạn có thể thử phương pháp này trong Mathematica.

Hãy tạo một số dữ liệu bivariate:

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

Sau đó, chúng ta cần tải gói này:

Needs["MultivariateStatistics`"]

Và bây giờ:

ellPar=EllipsoidQuantile[data, {0.9}]

đưa ra một đầu ra xác định hình elip 90% độ tin cậy. Các giá trị bạn nhận được từ đầu ra này có định dạng sau:

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

x1 và x2 chỉ định điểm tại đó hình elip ở giữa, r1 và r2 chỉ định bán kính bán trục và d1, d2, d3 và d4 chỉ định hướng căn chỉnh.

Bạn cũng có thể vẽ biểu đồ này:

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

Dạng tham số chung của hình elip là:

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]}

Và bạn có thể vẽ nó theo cách này:

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}}]

Bạn có thể thực hiện kiểm tra dựa trên thông tin hình học thuần túy: nếu khoảng cách Euclide giữa tâm hình elip (ellPar [[1,1]]) và điểm dữ liệu của bạn lớn hơn khoảng cách giữa tâm hình elip và đường viền của hình elip (rõ ràng, cùng hướng với điểm của bạn), thì điểm dữ liệu đó nằm ngoài hình elip.

Cách tiếp cận thứ hai

Cách tiếp cận này dựa trên phân phối kernel trơn tru.

Đây là một số dữ liệu được phân phối theo cách tương tự với dữ liệu của bạn:

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];

Chúng tôi có được phân phối kernel trơn tru trên các giá trị dữ liệu này:

skd = SmoothKernelDistribution[data];

Chúng tôi có được kết quả số cho từng điểm dữ liệu:

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

Chúng tôi sửa một ngưỡng và chúng tôi chọn tất cả dữ liệu cao hơn ngưỡng này:

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

Ở đây chúng tôi nhận được dữ liệu nằm ngoài khu vực:

dataOut = Complement[data, dataIn];

Và bây giờ chúng ta có thể vẽ tất cả các dữ liệu:

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]]

Các điểm màu xanh lá cây là những điểm trên ngưỡng và các điểm màu đỏ là những điểm dưới ngưỡng.

nhập mô tả hình ảnh ở đây


Cảm ơn, cách tiếp cận thứ hai của bạn giúp tôi rất nhiều với phân phối Kernel. Tôi là lập trình viên, không thống kê và tôi là người mới học Mathmatica và R nên tôi đánh giá cao sự giúp đỡ của bạn rất nhiều. Trong cách tiếp cận thứ hai của bạn, rõ ràng cho tôi cách kiểm tra một điểm mà nó nằm. Nhưng làm thế nào để làm điều đó trong cách tiếp cận đầu tiên? Tôi cho rằng tôi phải so sánh quan điểm của mình với định nghĩa ellipsoid. Xin vui lòng cung cấp làm thế nào? Bây giờ tôi phải hy vọng rằng có các định nghĩa tương tự trong R, bởi vì tôi cần sử dụng nó trong RinRuby ...
matejuh

@matejuh Tôi chỉ thêm vài dòng về cách tiếp cận đầu tiên có thể hướng bạn đến một giải pháp.
VLC

2

Các ellipsechức năng trong ellipsegói cho R sẽ tạo ra những dấu ba chấm (thực sự là một đa giác xấp xỉ hình elip). Bạn có thể sử dụng hình elip đó.

Điều thực sự có thể dễ dàng hơn là tính chiều cao của mật độ tại điểm của bạn và xem nó cao hơn (bên trong hình elip) hay thấp hơn (bên ngoài hình elip) so với giá trị đường viền ở hình elip. Các ellipsehàm bên trong sử dụng giá trị để tạo hình elip, bạn có thể bắt đầu từ đó để tìm chiều cao để sử dụng.χ2


1

Tôi đã tìm thấy câu trả lời tại: /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)

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.