如何从R中的特征值和特征向量绘制椭圆?[关闭]


15

有人可以拿出R代码从下面矩阵A = 2.2 0.4 0.4 2.8的特征值和特征向量绘制椭圆

一种=2.20.40.42.8

Answers:


16

您可以通过提取特征向量和-值eigen(A)。但是,使用Cholesky分解更为简单。请注意,在绘制数据的置信椭圆时,通常将椭圆轴缩放为长度=对应特征值的平方根,这就是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)

编辑:为了同时绘制特征向量,您必须使用更复杂的方法。这等效于suncoolsu的答案,它只是使用矩阵符号来缩短代码。

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)

在此处输入图片说明


您介意在此椭圆上绘制特征值和特征向量吗?谢谢
MYaseen208

@ MYaseen208我编辑了答案以将特征向量显示为椭圆的轴。轴长度的一半等于相应特征向量的平方根。
caracal

7

我认为这是您想要的R代码。我从R -mailing列表上的该线程借来了R-code 。这个想法基本上是:主要和次要半直径是两个特征值,然后将椭圆旋转第一个特征向量和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()

在此处输入图片说明


请随时纠正我。我不认为本征vecs是垂直的(它们必须在理论上;可能是我在绘制错误的东西?)。
suncoolsu 2011年

一种=1个-5-51个

只需将asp=1其长宽比设置为1并垂直箭头即可。将代码更改evs <- sqrt(eigens$values)为与我的答案相同。
caracal

3
@ MYaseen208您的新矩阵不是正定的:它具有负特征值,并且不是可能的协方差矩阵。在这种情况下,我不知道绘制什么椭圆。
caracal

@caracal谢谢!是的-我错过了sqrt部分!
suncoolsu 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.