Trực quan hóa PCA trong R: điểm dữ liệu, hàm riêng, hình chiếu, hình elip tự tin


8

Tôi có một bộ dữ liệu gồm 17 người, xếp hạng 77 báo cáo. Tôi muốn trích xuất các thành phần chính trên một ma trận tương quan chuyển vị của các mối tương quan giữa mọi người (dưới dạng các biến) qua các câu lệnh (như các trường hợp). Tôi biết, kỳ quặc, nó được gọi là nó Q Phương pháp .

Tôi muốn minh họa cách PCA hoạt động trong bối cảnh này, bằng cách trích xuất và trực quan hóa các giá trị / vectơ chỉ cho một cặp dữ liệu. (Bởi vì rất ít người trong ngành học của tôi PCA, hãy để một mình ứng dụng cho Q, bao gồm cả bản thân tôi).

Tôi muốn hình dung từ hướng dẫn tuyệt vời này , chỉ cho dữ liệu thực sự của tôi .

Hình dung tuyệt vời

Hãy để điều này là một tập hợp con của dữ liệu của tôi:

Person1 <- c(-3,1,1,-3,0,-1,-1,0,-1,-1,3,4,5,-2,1,2,-2,-1,1,-2,1,-3,4,-6,1,-3,-4,3,3,-5,0,3,0,-3,1,-2,-1,0,-3,3,-4,-4,-7,-5,-2,-2,-1,1,1,2,0,0,2,-2,4,2,1,2,2,7,0,3,2,5,2,6,0,4,0,-2,-1,2,0,-1,-2,-4,-1)
Person2 <- c(-4,-3,4,-5,-1,-1,-2,2,1,0,3,2,3,-4,2,-1,2,-1,4,-2,6,-2,-1,-2,-1,-1,-3,5,2,-1,3,3,1,-3,1,3,-3,2,-2,4,-4,-6,-4,-7,0,-3,1,-2,0,2,-5,2,-2,-1,4,1,1,0,1,5,1,0,1,1,0,2,0,7,-2,3,-1,-2,-3,0,0,0,0)
df <- data.frame(cbind(Person1, Person2))
g <- ggplot(data = df, mapping = aes(x = Person1, y = Person2))
g <- g + geom_point(alpha = 1/3)  # alpha b/c of overplotting
g <- g + geom_smooth(method = "lm")  # just for comparison
g <- g + coord_fixed()  # otherwise, the angles of vectors are off
g

sửa lỗi cho dữ liệu của tôi

Lưu ý rằng, bằng cách đo lường, dữ liệu này:

  • ... có nghĩa là bằng không,
  • ... là hoàn toàn đối xứng,
  • ... và được chia tỷ lệ bằng nhau trên cả hai biến (không nên có sự khác biệt giữa ma trận tương quan và hiệp phương sai)

Bây giờ, tôi muốn kết hợp hai lô trên .

corre <- cor(x = df$Person1, y = df$Person2, method = "spearman")  # calculate correlation, must be spearman b/c of measurement
matrix <- matrix(c(1, corre, corre, 1), nrow = 2)  # make this into a matrix
eigen <- eigen(matrix)  # calculate eigenvectors and values
eigen

cho

> $values
> [1] 1.6 0.4
>
> $vectors
>     [,1]  [,2]
> [1,] 0.71 -0.71
> [2,] 0.71  0.71
>
> $vectors.scaled
>     [,1]  [,2]
> [1,]  0.9 -0.45
> [2,]  0.9  0.45

và, tiếp tục

g <- g + stat_ellipse(type = "norm")
  # add ellipse, though I am not sure which is the adequate type
  # as per https://github.com/hadley/ggplot2/blob/master/R/stat-ellipse.R
eigen$slopes[1] <- eigen$vectors[1,1]/eigen$vectors[2,1]  # calc slopes as ratios
eigen$slopes[2] <- eigen$vectors[1,1]/eigen$vectors[1,2]  # calc slopes as ratios
g <- g + geom_abline(intercept = 0, slope = eigen$slopes[1], colour = "green")  # plot pc1
g <- g + geom_abline(intercept = 0, slope = eigen$slopes[2], colour = "red")  # plot pc2
g <- g + geom_segment(x = 0, y = 0, xend = eigen$values[1], yend = eigen$slopes[1] * eigen$values[1], colour = "green", arrow = arrow(length = unit(0.2, "cm")))  # add arrow for pc1
g <- g + geom_segment(x = 0, y = 0, xend = eigen$values[2], yend = eigen$slopes[2] * eigen$values[2], colour = "red", arrow = arrow(length = unit(0.2, "cm")))  # add arrow for pc2
# Here come the perpendiculars, from StackExchange answer /programming/30398908/how-to-drop-a-perpendicular-line-from-each-point-in-a-scatterplot-to-an-eigenv ===
perp.segment.coord <- function(x0, y0, a=0,b=1){
#finds endpoint for a perpendicular segment from the point (x0,y0) to the line
# defined by lm.mod as y=a+b*x
  x1 <- (x0+b*y0-a*b)/(1+b^2)
  y1 <- a + b*x1
  list(x0=x0, y0=y0, x1=x1, y1=y1)
}
ss <- perp.segment.coord(df$Person1, df$Person2, 0, eigen$slopes[1])
g <- g + geom_segment(data=as.data.frame(ss), aes(x = x0, y = y0, xend = x1, yend = y1), colour = "green", linetype = "dotted")
g

Cốt truyện cuối cùng

Liệu cốt truyện này có minh họa đầy đủ cho việc trích xuất eigenvector / eigenvalue trong PCA không?

  • Tôi không chắc hình elip và / hoặc độ dài của vectơ sẽ là gì (hoặc nó không quan trọng?)
  • Tôi đoán, rằng các vectơ có độ dốc 1, -1là vì dữ liệu của tôi (bảng xếp hạng? Đối xứng?), Và sẽ khác nhau cho các dữ liệu khác.

Ps.: Điều này dựa trên hướng dẫn ở trên và câu hỏi CrossValidated này .

Pps.: Các đường vuông góc được thả trên vectơ là độ chính xác của câu trả lời StackExchange này


3
Đừng mở rộng quy mô của bạn; sau đó vẽ lại cốt truyện. Tôi nghĩ rằng bạn sẽ thấy ngay lập tức nơi bạn đã phạm sai lầm.
whuber

cảm ơn @whuber, đã sửa nó Tôi cần phải lấy tỷ lệ của hai Eigenvector. Bây giờ trông nó có tốt hơn không? Bất cứ một đề nghị nào khác? (Tôi đoán rằng các sườn chính xác là -1, 1 là do dữ liệu kỳ lạ của tôi).
tối đa

3
Khi chỉ có hai biến, các hàm riêng được chuẩn hóa luôn luôn , mà - như lý thuyết đã nói - là trực giao. Lỗi của bạn là bạn đã thu nhỏ chúng không chính xác: bạn nên thu nhỏ các cột thay vì các hàng. (1/2,±1/2)
whuber

@amoeba đồng ý, đã trả lời 95%. Bạn có thể bình luận về hai viên đạn cuối cùng được nêu ra trong câu hỏi? 1) Các hình elip có đúng không và 2) là 1, -1độ dốc được dự kiến?
tối đa

Câu trả lời:


2

Không có nhiều điều để trả lời ở đây. Bạn dường như đã có một số vấn đề với kịch bản của bạn mà bây giờ đã được sửa. Hiện tại không có gì sai với hình dung của bạn và trên thực tế tôi thấy đó là một minh họa rất đẹp và đầy đủ.

Để trả lời các câu hỏi còn lại của bạn:

  1. Độ dốc của các trục chính của bạn sẽ luôn là và cho bộ dữ liệu hai chiều được tiêu chuẩn hóa (nghĩa là nếu bạn đang làm việc với ma trận tương quan), như @whuber nói trong các nhận xét. Xem câu trả lời của tôi ở đây: Liệu một ma trận tương quan của hai biến luôn có cùng một hàm riêng?- 111

  2. Hình elip mà bạn đã vẽ (theo sự hiểu biết của tôi về mã nguồn của stat_ellipse()) là hình elip bao phủ 95% với giả định phân phối chuẩn nhiều biến số. Đây là một lựa chọn hợp lý. Lưu ý rằng nếu bạn muốn một phạm vi bảo hiểm khác, bạn có thể thay đổi nó thông qua leveltham số đầu vào, nhưng 95% là khá chuẩn và ổn.

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.