Comment tracer une ellipse à partir de valeurs propres et de vecteurs propres dans R? [fermé]

15

Quelqu'un pourrait-il trouver du code R pour tracer une ellipse à partir des valeurs propres et des vecteurs propres de la matrice suivante

UNE=(2.20,40,42.8)
MYaseen208
la source

Réponses:

16

Vous pouvez extraire les vecteurs propres et les valeurs via eigen(A). Cependant, il est plus simple d'utiliser la décomposition de Cholesky. Notez que lorsque vous tracez des ellipses de confiance pour des données, les axes d'ellipse sont généralement mis à l'échelle pour avoir la longueur = racine carrée des valeurs propres correspondantes, et c'est ce que donne la décomposition de Cholesky.

ctr    <- c(0, 0)                               # data centroid -> colMeans(dataMatrix)
A      <- matrix(c(2.2, 0.4, 0.4, 2.8), nrow=2) # covariance matrix -> cov(dataMatrix)
RR     <- chol(A)                               # Cholesky decomposition
angles <- seq(0, 2*pi, length.out=200)          # angles for ellipse
ell    <- 1 * cbind(cos(angles), sin(angles)) %*% RR  # ellipse scaled with factor 1
ellCtr <- sweep(ell, 2, ctr, "+")               # center ellipse to the data centroid
plot(ellCtr, type="l", lwd=2, asp=1)            # plot ellipse
points(ctr[1], ctr[2], pch=4, lwd=2)            # plot data centroid

library(car)  # verify with car's ellipse() function
ellipse(c(0, 0), shape=A, radius=0.98, col="red", lty=2)

Edit: pour tracer également les vecteurs propres, vous devez utiliser l'approche la plus compliquée. C'est équivalent à la réponse de suncoolsu, il utilise simplement la notation matricielle pour raccourcir le code.

eigVal  <- eigen(A)$values
eigVec  <- eigen(A)$vectors
eigScl  <- eigVec %*% diag(sqrt(eigVal))  # scale eigenvectors to length = square-root
xMat    <- rbind(ctr[1] + eigScl[1, ], ctr[1] - eigScl[1, ])
yMat    <- rbind(ctr[2] + eigScl[2, ], ctr[2] - eigScl[2, ])
ellBase <- cbind(sqrt(eigVal[1])*cos(angles), sqrt(eigVal[2])*sin(angles)) # normal ellipse
ellRot  <- eigVec %*% t(ellBase)                                          # rotated ellipse
plot((ellRot+ctr)[1, ], (ellRot+ctr)[2, ], asp=1, type="l", lwd=2)
matlines(xMat, yMat, lty=1, lwd=2, col="green")
points(ctr[1], ctr[2], pch=4, col="red", lwd=3)

entrez la description de l'image ici

caracal
la source
Pourriez-vous tracer les valeurs propres et les vecteurs propres sur cette ellipse? Merci
MYaseen208
@ MYaseen208 J'ai édité ma réponse pour montrer les vecteurs propres comme les axes de l'ellipse. La moitié de la longueur des axes est égale à la racine carrée des vecteurs propres correspondants.
caracal
7

Je pense que c'est le code R que vous voulez. J'ai emprunté le code R à ce fil sur la liste de diffusion. L'idée est essentiellement: les demi-diamètres majeurs et mineurs sont les deux valeurs propres et vous faites pivoter l'ellipse de la quantité d'angle entre le premier vecteur propre et l'axe des x

mat <- matrix(c(2.2, 0.4, 0.4, 2.8), 2, 2)
eigens <- eigen(mat)
evs <- sqrt(eigens$values)
evecs <- eigens$vectors

a <- evs[1]
b <- evs[2]
x0 <- 0
y0 <- 0
alpha <- atan(evecs[ , 1][2] / evecs[ , 1][1])
theta <- seq(0, 2 * pi, length=(1000))

x <- x0 + a * cos(theta) * cos(alpha) - b * sin(theta) * sin(alpha)
y <- y0 + a * cos(theta) * sin(alpha) + b * sin(theta) * cos(alpha)


png("graph.png")
plot(x, y, type = "l", main = expression("x = a cos " * theta * " + " * x[0] * " and y = b sin " * theta * " + " * y[0]), asp = 1)
arrows(0, 0, a * evecs[ , 1][2], a * evecs[ , 1][2])
arrows(0, 0, b * evecs[ , 2][3], b * evecs[ , 2][2])
dev.off()

entrez la description de l'image ici

suncoolsu
la source
n'hésitez pas à me corriger. Je ne pense pas que les vecs propres soient perpendiculaires (ils doivent l'être en théorie; est-ce que je trace quelque chose de mal?).
suncoolsu
UNE=(1-5-51)
Réglez simplement asp=1pour avoir un rapport d'aspect de 1 et des flèches perpendiculaires. Changer votre code evs <- sqrt(eigens$values)donne la même ellipse que ma réponse.
caracal
3
@ MYaseen208 Votre nouvelle matrice n'est pas définie positive: elle a des valeurs propres négatives et n'est pas une matrice de covariance possible. Je ne sais pas quelle ellipse dessiner dans ce cas.
caracal
@caracal merci! ... ouais - j'ai raté la partie sqrt!
suncoolsu