O Corsario fornece uma boa solução em um comentário: use a função de densidade do kernel para testar a inclusão em um conjunto de níveis.
Outra interpretação da questão é que ela solicita um procedimento para testar a inclusão nas elipses criadas por uma aproximação normal bivariada dos dados. Para começar, vamos gerar alguns dados que se parecem com a ilustração na pergunta:
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))
As elipses são determinadas pelo primeiro e segundo momentos dos dados:
center <- apply(p, 2, mean)
sigma <- cov(p)
A fórmula requer inversão da matriz de variância-covariância:
sigma.inv = solve(sigma, matrix(c(1,0,0,1),2,2))
A função "altura" da elipse é negativa do logaritmo da densidade normal bivariada :
ellipse <- function(s,t) {u<-c(s,t)-center; u %*% sigma.inv %*% u / 2}
(Eu ignorei uma constante aditiva igual a .)log(2πdet(Σ)−−−−−−√)
Para testar isso , vamos desenhar alguns de seus contornos. Isso requer a geração de uma grade de pontos nas direções x e y:
n <- 50
x <- (0:(n-1)) * (500000/(n-1))
y <- (0:(n-1)) * (50000/(n-1))
Calcule a função de altura nesta grade e plote-a:
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)
Evidentemente, funciona. Portanto, o teste para determinar se um ponto está dentro de um contorno elíptico no nível é(s,t)c
ellipse(s,t) <= c
O Mathematica faz o trabalho da mesma maneira: calcule a matriz de variância-covariância dos dados, inverta isso, construa a ellipse
função e está tudo pronto.
A plotagem é direta com a
ellipse()
função domixtools
pacote para R:fonte
Primeira abordagem
Você pode tentar essa abordagem no Mathematica.
Vamos gerar alguns dados bivariados:
Então precisamos carregar este pacote:
E agora:
fornece uma saída que define uma elipse de confiança de 90%. Os valores que você obtém dessa saída estão no seguinte formato:
x1 e x2 especificam o ponto no qual a elipse no centro, r1 e r2 especificam os raios do semi-eixo, e d1, d2, d3 e d4 especificam a direção do alinhamento.
Você também pode traçar isso:
A forma paramétrica geral da elipse é:
E você pode plotá-lo desta maneira:
Você pode executar uma verificação com base em informações geométricas puras: se a distância euclidiana entre o centro da elipse (ellPar [[1,1]]) e seu ponto de dados for maior que a distância entre o centro da elipse e a borda da elipse a elipse (obviamente, na mesma direção em que seu ponto está localizado), esse ponto de dados está fora da elipse.
Segunda abordagem
Essa abordagem é baseada na distribuição suave do kernel.
Estes são alguns dados distribuídos de maneira semelhante aos seus dados:
Obtemos uma distribuição suave do kernel nesses valores de dados:
Obtemos um resultado numérico para cada ponto de dados:
Fixamos um limite e selecionamos todos os dados que são maiores que esse limite:
Aqui temos os dados que ficam fora da região:
E agora podemos plotar todos os dados:
Os pontos de cor verde são aqueles acima do limite e os pontos de cor vermelha são aqueles abaixo do limite.
fonte
A
ellipse
função noellipse
pacote para R gerará essas elipses (na verdade, um polígono que se aproxima da elipse). Você poderia usar essa elipse.O que pode ser realmente mais fácil é calcular a altura da densidade no seu ponto e ver se ela é maior (dentro da elipse) ou mais baixa (fora da elipse) do que o valor do contorno na elipse. Asχ2
ellipse
funções internas usam um valor para criar a elipse, você pode começar por lá para encontrar a altura a ser usada.fonte
Encontrei a resposta em: /programming/2397097/how-can-a-data-ellipse-be-superimposed-on-a-ggplot2-scatterplot
fonte