Rの固有値と固有ベクトルから楕円をプロットする方法は?[閉まっている]


15

誰かが次の行列の固有値と固有ベクトルから楕円をプロットするRコードを思い付くことができます

A=2.20.40.42.8

回答:


16

を介して固有ベクトルと値を抽出できeigen(A)ます。ただし、コレスキー分解を使用する方が簡単です。データの信頼楕円をプロットする場合、楕円軸は通常、対応する固有値の長さ=平方根を持つようにスケーリングされることに注意してください。これがコレスキー分解の結果です。

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回答を編集して、固有ベクトルを楕円の軸として表示しました。軸の長さの半分は、対応する固有ベクトルの平方根に等しくなります。
カラカル

7

これがあなたが望むRコードだと思います。rメーリングリストのこのスレッドからRコードを借りました。基本的な考え方は次のとおりです。長径と短径は2つの固有値であり、最初の固有ベクトルと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()

ここに画像の説明を入力してください


私を修正してください。固有ベクトルは垂直であるとは思わない(理論上でなければならない。何か間違ったことをプロットしているのかもしれない)。
-suncoolsu

お返事をありがとうございます。この楕円はきれいに見えますが、そこに何かが欠けています。このマトリックスで指定されたコードを試しました A=1551そして、それは正しい楕円を与えました。なぜマトリックスのさまざまな分散に対して正しい楕円が提供されないのか疑問に思っています。任意のコメント!
MYaseen208

asp=1縦横比が1に設定され、矢印が垂直になるように設定するだけです。コードをに変更するevs <- sqrt(eigens$values)と、私の答えと同じ楕円が得られます。
カラカル

3
@ MYaseen208新しい行列は正定値ではありません。負の固有値を持ち、可能な共分散行列ではありません。その場合、どの楕円を描くべきかわかりません。
カラカル

@カラカルありがとう!...ええ-sqrtの部分を見逃しました!
-suncoolsu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.