Visualisierung von PCA in R: Datenpunkte, Eigenvektoren, Projektionen, Vertrauensellipse

8

Ich habe einen Datensatz von 17 Personen, Rang 77 Aussagen. Ich möchte Hauptkomponenten auf einer transponierten Korrelationsmatrix von Korrelationen zwischen Personen (als Variablen) über Aussagen (als Fälle) extrahieren . Ich weiß, es ist seltsam, es heißt Q-Methodik .

Ich möchte veranschaulichen, wie PCA in diesem Zusammenhang funktioniert, indem ich Eigenwerte / Vektoren nur für ein Datenpaar extrahiere und visualisiere . (Weil nur wenige Leute in meiner Disziplin PCA bekommen , geschweige denn die Anwendung auf Q, mich eingeschlossen).

Ich möchte die Visualisierung aus diesem fantastischen Tutorial nur für meine realen Daten .

Tolle Visualisierung

Lassen Sie dies eine Teilmenge meiner Daten sein:

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

Corrplot für meine Daten

Beachten Sie, dass diese Daten durch Messung:

  • ... hat einen Mittelwert von Null,
  • ... ist perfekt symmetrisch,
  • ... und ist für beide Variablen gleich skaliert (sollte kein Unterschied zwischen Korrelation und Kovarianzmatrix sein)

Jetzt möchte ich die beiden obigen Diagramme kombinieren .

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

gibt

> $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

und weitergehen

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

Letzte Handlung

Veranschaulicht dieses Diagramm die Eigenvektor / Eigenwert-Extraktion in PCA angemessen?

  • Ich bin mir nicht sicher, wie groß die Ellipsen und / oder die Länge der Vektoren sein würden (oder spielt das keine Rolle?)
  • Ich vermute, dass die Vektoren eine Steigung von haben 1, -1aufgrund meiner Daten (Rangfolge? Symmetrie?) Und sich für andere Daten unterscheiden würden.

Ps.: Dies basiert auf dem obigen Tutorial und dieser CrossValidated-Frage .

Pps.: Die auf dem Vektor abgelegten Senkrechten sind für diese StackExchange-Antwort knapp

maxheld
quelle
3
Skalieren Sie Ihre Eigenvektoren nicht. Zeichnen Sie dann die Handlung neu. Ich denke, Sie werden dann sofort sehen, wo Sie einen Fehler gemacht haben.
whuber
danke @whuber, behoben. Ich musste das Verhältnis der beiden Eigenvektoren nehmen. Sieht es jetzt besser aus? Irgendwelche anderen Vorschläge? (Ich vermute, dass die Steigungen genau -1 sind, 1 liegt an meinen seltsamen Daten).
Maxheld
3
(1/.2,±1/.2)
@amoeba stimmte zu, es ist zu 95% beantwortet. Könnten Sie die letzten beiden in der Frage aufgeworfenen Punkte kommentieren? 1) Sind die Ellipsen korrigieren und 2) 1, -1Steigungen zu erwarten?
Maxheld

Antworten:

2

Hier gibt es nicht viel zu beantworten. Sie scheinen einige Probleme mit Ihrem Skript gehabt zu haben, die inzwischen behoben sind. An Ihrer Visualisierung ist derzeit nichts auszusetzen, und ich finde sie in der Tat eine sehr schöne und angemessene Illustration.

So beantworten Sie Ihre verbleibenden Fragen:

  1. 1- -1

  2. Die Ellipse, die Sie gezeichnet haben (nach meinem Verständnis des Quellcodes von stat_ellipse()), ist eine Ellipse mit 95% Deckung, die eine multivariate Normalverteilung voraussetzt. Dies ist eine vernünftige Wahl. Wenn Sie eine andere Abdeckung wünschen, können Sie diese über den levelEingabeparameter ändern , aber 95% sind ziemlich normal und in Ordnung.

Amöbe
quelle