Das Thema Faktoranalyse wird in 3 Unterthemen gesplittet, die jeweils in einer Unit besprochen werden.
Faktoranalysen reproduzieren Korrelationsmatrizen. Ausgangspunkt müssen also nicht unbedingt Rohdaten sein, Korrelationsmatrizen reichen.
PCA und EFA sind konzeptionell verschieden aber rechnerisch vergleichbar. PCA ist ein Sonderfall der EFA für spezielle Anwendungszwecke.
PCA kann beispielsweise zur Reduktion der Anzahl von Variablen dienen, vor allem dann, wenn es Probleme mit Multikollinearität gibt (zu hohe Interkorrelationen von Prädiktoren). In diesem Anwendungsfall können die Prädiktoren in eine adäquate Anzahl von Komponenten zerlegt werden. Alle darauf folgenden Berechnungen werden dann mit den Komponentenwerten durchgeführt.
In der PCA geht man davon aus, dass alle Varianz einer Variablen ‘common Variance’ ist, also durch einen gemeinsamen Einfluss zu 100% festgelegt ist. Daher werden die Kommunalitäten auf 1 (100%) festgelegt.
Im Unterschied zur PCA, die möglichst viel erklärbare Varianz in den Komponenten erklären will, geht man in der EFA von Anfang an davon aus, dass man nur einen gewissen Teil der Varianz erklären kann. Variablen werden nur als Indikatoren von dahinter liegenden Faktoren (latent Traits) aufgefasst und diese Faktoren können gar nicht vollständig erklärt werden durch die Indikatorvariablen.
Es ergibt sich das Problem der Kommunalitätenschätzung. Da die Kommunalität der Anteil der erklärbaren Gesamtvarianz ist, der durch die Gesamtheit der Faktoren erklärt werden kann, müssen adäquate maximale Kommunalitäten geschätzt werden. Der durch die sog. gemeinsamen Faktoren nicht erklärbare Varianzanteil in den Variablen wird spezifischer Varianzanteil genannt.
Die PCA beinhaltet also kein Fehlermodell, sondern betrachtet alle Komponenten als gleichwertig. Damit wird davon ausgegangen, dass die gesamte Varianz in den Variablen durch die vollständige Hauptkomponentenlösung erklärbar ist.
CFA ist ein Sonderfall der Pfadanalyse. Sie dient hauptsächlich dazu, eine bereits gegebene Faktorstruktur zu überprüfen. Die bekannte Faktorstruktur kann aus Vorstudien stammen, oder aber theoretisch abgeleitet sein, muss aber a priori festliegen. Es wird die Hypothese getestet, ob das spezifische Faktor-Modell eine vorliegende Kovarianz- oder Korrelationsmatrix adäquat beschreiben kann (model fit). Es wird ein Chi^2 Test auf Unterschiedlichkeit berechnet und es können verschiedene Fit-Indices angefordert werden.
Den explorativen Verfahren CFA und EFA ist gemein, dass unklar ist, wieviele Faktoren überhaupt extrahiert werden sollten. Inhaltlichen Überlegungen hierzu können ein Weg sein, die Anzahl festzulegen, beispielsweise aufgrund theoretisch abgeleiteter, ganz gezielter Formulierung von zwei Gruppen von Fragen.
Bei nicht inhaltlich vorgegebener Faktorenanzahl muss die Anzahl anders festgelegt werden. Häufig wird hierzu ein Screeplot angefertigt: Die Eigenwerte werden der Höhe nach geordnet in einem Diagramm angezeigt. Es wird nach einem ‘Knick’ gesucht. Subjektives Kriterium.
Ein anderes, gängiges Kriterium ist das Kaiser-Guttman-Kriterium, häufig auch nur Kaiser-Kriterium genannt. Hierbei ist die Anzahl der Faktoren gleich derer mit einem Eigenwert über 1. Idee dahinter: Ein Eigenwert von 1 resultiert, wenn ein Faktor einen ‘durchschnittlichen’ Anteil an Varianz erklärt. Die Summe der Eigenwerte ist gleich der Anzahl der faktorisierten Variablen.
Parallelanalyse dient als Hilfsmittel zum Festlegen der Faktorenanzahl. Die Idee ist, Zufallsdatensätze zu faktorisieren, die dieselben Charakteristika haben, wie der zu untersuchende Datensatz. Dies bezieht sich auf Vpn und Variablen. Auch hier gibt es Eigenwerte über 1. Mittlerer Eigenwertverlauf hieraus ist Vergleichsverlauf. Empirische Eigenwerte des eigenen, untersuchten Datensatzes, die über den Werten des gemittelten Zufalls-Eigenwertverlaufs liegen, können als bedeutsam betrachtet werden.
Mit der Parallelanalyse steht ein nicht-subjektives Vorgehen zur Festlegung der Faktorenzahl zur Verfügung.
In R stellt die Library psych mit dem Befehl fa.parallel()
die Parallelanalyse zur Verfügung. Diese Prozedur erzeugt auch einen entsprechenden aussagefähigen Plot.
Mit dem Paramter fa=...
fordert man eine Parallelanalyse für PCA fa='pc'
, für Hauptachsenanalyes (principal axis factor analysis) fa='fa'
oder beide zugleich fa='both'
an.
SAQ: SPSS-Anxiety-Questionnaire Field (2013, p. 683)
Erfundene Daten. Idee ist, mit einem Inventar, dem Spss-Anxiety-Questionnaire (SAQ) die Angst Studierender vor SPSS zu erfassen. Insgesamt 23 Statements werden auf einer 5-stufigen Lickert-Skala beantwortet.
sd = strongly disagree d = disagree n = neither agree nor disagree a = agree sa = strongly agree
Der SAQ liegt von insgesamt 2571 Personen vor. Frage: Kann die Angst im Umgang mit SPSS heruntergebrochen werden auf spezifische Subkomponenten von Angst? Welche latenten Eigenschaften tragen zur Angst vor SPSS bei?
# first 23 columns of saq.txt are the 23 items of the questionnaire. So we read only these columns
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/af/saq.txt")[1:23]
#head(dd)
# take a look at the eigenvalues
eigen(cor(dd))$values
## [1] 7.2900471 1.7388287 1.3167515 1.2271982 0.9878779 0.8953304 0.8055604
## [8] 0.7828199 0.7509712 0.7169577 0.6835877 0.6695016 0.6119976 0.5777377
## [15] 0.5491875 0.5231504 0.5083962 0.4559399 0.4238036 0.4077909 0.3794799
## [22] 0.3640223 0.3330618
# parallel analysis is part of library(psych)
library(psych)
# get parallel analysis for both types of fa (principal axis factor analysis, principal component analysis)
items.parallel <- fa.parallel(dd, fa="both")
## Parallel analysis suggests that the number of factors = 6 and the number of components = 4
# you may also get parallel analysis for one type only: here principal component analysis
# items.parallel <- fa.parallel(dd, fa="pc")
# you may also get parallel analysis for principal axis factor analysis only
# items.parallel <- fa.parallel(dd, fa="fa")
# the command below generates the graph
# plot(items.parallel)
Ein Plot ähnlich diesem sollte erzeugt werden:
parallel_plot_pc.png
Bem: Eine Meldung von Fehler in values.sim$mean : $ operator is invalid for atomic vectors
… ist bisher noch ungelöst. Plot erscheint trotzdem.
Mehr Beispiele sind bei den speziellen Verfahren zu finden.
source von fa.parallel()
Ist die zu faktorisierende Korrelationsmatrix signifikant von einer Identitätsmatrix (alle Elemente sind 0) verschieden? Eine Minimalvoraussetzung für Faktorisierung.
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_bmi_preprocessed.txt", fileEncoding = "UTF-8")
require(dplyr)
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
dd.f <- dplyr::select(dd, c(c_phys_app:c_dress, i_c_bad_way, c_figure))
require(psych)
# Ask Bartlett test whether correlation matrix is idendity matrix (all elements are 0), should be significant
# run Bartlett test on dataframe
cortest.bartlett(dd.f)
## R was not square, finding R from data
## $chisq
## [1] 148.9133
##
## $p.value
## [1] 6.236252e-27
##
## $df
## [1] 10
# alternativly on correlation matrix (add n), here calculated on the fly using cor()
cortest.bartlett(cor(dd.f), n=length(dd.f[,1]))
## $chisq
## [1] 148.9133
##
## $p.value
## [1] 6.236252e-27
##
## $df
## [1] 10
Beurteilung der Eignung der Daten zur Durchführung einer EFA. Das am häufigsten benutzte Verfahren, um die Eignung von Daten für die Faktorenanalyse zu bestimmen, ist das Kaiser-Meyer-Olkin (KMO) Maß.
vgl. Wikipedia Artikel zu KMO
vgl. Eric Klopp EFA
\[ KMO = \frac{\sum_{k \neq j} r^2_{jk}} {\sum_{k \neq j} r^2_{jk} + \sum_{k \neq j} p^2_{jk}} \]
\(r_{jk}\) ist die Korrelation zwischen zwei Variablen.
\(p_{jk}\) ist die partielle Korrelation zwischen zwei Variablen.
wobei \(r_{ij}\) der Korrelationskoeffizient der Variablen i und j ist und \(r_{ij.z}\) der partielle Korrelationskoeffizient nach Herauspartialisierung aller anderen Variablen ist. Stehen hinter dem Datensatz gemeinsame Faktoren und lädt jeder Faktor auf mindestens drei Indikatoren (Variablen), dann sollten die partiellen Korrelationen nahe Null sein. Man bestimmt also den gemeinsamen Varianzanteil, den alle Variablen miteinander teilen, und setzt diesen mit dem gemeinsamen Varianzanteil aller Variablen miteinander zuzüglich der Summe der quadrierten Partialkorrelationskoeffizienten, in Beziehung. Eine große Summe der Partialkorrelationskoeffizienten bedeutet, dass die Interkorrelationsmatrix wenig gemeinsame Varianz enthält und somit wird der KMO-Koeffizient klein. Um die Eignung einer Interkorrelationsmatrix beurteilen zu können, gelten folgende Anhaltspunkte (nach Kaiser und Rice, 1974):
KMO-Koeffizient | Eignung der Daten |
---|---|
>0,90 | sehr gut |
0,80-0,90 | gut |
0,70-0,79 | mittel |
0,60-0,69 | mäßig |
0,50-0,59 | schlecht |
<0,50 | inkompatibel mit der Berechnung |
library(psych)
bietet mit KMO()
einen Befehl hierfür.
Kaiser-Meyer-Olkins Measure of Sampling Adequacy gibt es als Gesamtmaß MSA
und für jede einzelne Variable MSAi
.
# first 23 columns of saq.txt are the 23 items of the questionnaire. So we read only these columns
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/af/saq.txt")[1:23]
# KMO is part of library(psych)
library(psych)
# get the KMO coefficients
kmo <- KMO(dd)
# show it
kmo
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = dd)
## Overall MSA = 0.93
## MSA for each item =
## Question_01 Question_02 Question_03 Question_04 Question_05 Question_06
## 0.93 0.87 0.95 0.96 0.96 0.89
## Question_07 Question_08 Question_09 Question_10 Question_11 Question_12
## 0.94 0.87 0.83 0.95 0.91 0.95
## Question_13 Question_14 Question_15 Question_16 Question_17 Question_18
## 0.95 0.97 0.94 0.93 0.93 0.95
## Question_19 Question_20 Question_21 Question_22 Question_23
## 0.94 0.89 0.93 0.88 0.77
# get ordered MSAi
kmo$MSAi[order(kmo$MSAi)]
## Question_23 Question_09 Question_08 Question_02 Question_22 Question_20
## 0.7663994 0.8337295 0.8713055 0.8747754 0.8784508 0.8890514
## Question_06 Question_11 Question_21 Question_01 Question_17 Question_16
## 0.8913314 0.9059338 0.9293369 0.9297610 0.9306205 0.9336439
## Question_15 Question_19 Question_07 Question_18 Question_13 Question_10
## 0.9404402 0.9407021 0.9416800 0.9479508 0.9482270 0.9486858
## Question_03 Question_12 Question_04 Question_05 Question_14
## 0.9510378 0.9548324 0.9553403 0.9600892 0.9671722
Gesamt-Statistik (MSA) und Statistik für jede Variable (MSAi) wird ausgegeben. Bewertung: .5 - .7 mäßig, .7 - .8 gut, .8-.9 sehr gut, über .9 super Empfehlung: Variablen mit einem Kaiser-Meyer-Olkin Measure of Sampling Adequacy von unter 0.5 ausschließen (MSA steht für Measure of Sampling Adequacy).
Fazit: Die SAQ-Daten von Andy Field eigenen sich sehr gut für eine Faktorisierung (Overall MSA = 0.93 > 0.9). Kein MSAi ist kleiner als .75, die Mehrzahl liegt über .90. Es gibt keinen Anlass, eine der Variablen aus der Faktorisierung zu nehmen.
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_ei.txt")
library(psych)
pc.2 <- psych::principal(dd, rotate='none', nfactors=2)
# summary and Chi^2 model test
pc.2
## Principal Components Analysis
## Call: psych::principal(r = dd, nfactors = 2, rotate = "none")
## Standardized loadings (pattern matrix) based upon correlation matrix
## PC1 PC2 h2 u2 com
## i1 0.37 0.56 0.45 0.55 1.7
## i2 0.78 -0.22 0.65 0.35 1.2
## i3 0.38 0.58 0.49 0.51 1.7
## i4 -0.71 0.34 0.61 0.39 1.4
## i5 0.37 0.48 0.36 0.64 1.9
## i6 -0.72 0.31 0.61 0.39 1.4
## i7 0.28 0.28 0.16 0.84 2.0
## i8 0.77 -0.09 0.60 0.40 1.0
## i9 0.42 0.53 0.46 0.54 1.9
## i10 -0.78 0.22 0.65 0.35 1.2
## i11 0.36 0.53 0.41 0.59 1.8
## i12 -0.70 0.32 0.59 0.41 1.4
##
## PC1 PC2
## SS loadings 4.10 1.95
## Proportion Var 0.34 0.16
## Cumulative Var 0.34 0.50
## Proportion Explained 0.68 0.32
## Cumulative Proportion 0.68 1.00
##
## Mean item complexity = 1.5
## Test of the hypothesis that 2 components are sufficient.
##
## The root mean square of the residuals (RMSR) is 0.08
## with the empirical chi square 90.97 with prob < 2.7e-05
##
## Fit based upon off diagonal values = 0.93
# original correlation table, that will be reproduced more or less by PCA
head(round(cor(dd), 2))
## i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
## i1 1.00 0.18 0.35 -0.06 0.17 -0.23 0.18 0.14 0.43 -0.08 0.30 -0.11
## i2 0.18 1.00 0.14 -0.48 0.18 -0.52 0.21 0.57 0.18 -0.61 0.12 -0.60
## i3 0.35 0.14 1.00 -0.07 0.30 -0.11 0.13 0.25 0.34 -0.25 0.33 -0.05
## i4 -0.06 -0.48 -0.07 1.00 -0.12 0.63 -0.12 -0.45 -0.11 0.53 -0.15 0.54
## i5 0.17 0.18 0.30 -0.12 1.00 -0.04 0.18 0.31 0.26 -0.13 0.33 -0.11
## i6 -0.23 -0.52 -0.11 0.63 -0.04 1.00 -0.04 -0.47 -0.18 0.58 -0.04 0.45
# get the reproduced correlation matrix, which is calculated on base of the loadings
# diagonal are the communalities
head(round(factor.model(pc.2$loadings), 2))
## i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
## i1 0.45 0.16 0.47 -0.07 0.40 -0.09 0.26 0.23 0.45 -0.16 0.43 -0.08
## i2 0.16 0.65 0.17 -0.62 0.18 -0.63 0.15 0.62 0.21 -0.65 0.17 -0.61
## i3 0.47 0.17 0.49 -0.07 0.42 -0.09 0.27 0.24 0.47 -0.17 0.45 -0.08
## i4 -0.07 -0.62 -0.07 0.61 -0.09 0.61 -0.10 -0.57 -0.11 0.62 -0.07 0.60
## i5 0.40 0.18 0.42 -0.09 0.36 -0.11 0.24 0.24 0.41 -0.18 0.39 -0.10
## i6 -0.09 -0.63 -0.09 0.61 -0.11 0.61 -0.11 -0.58 -0.13 0.63 -0.09 0.60
# get the residuals. These are the differences between original and reproduced correlation matrix
pc.diff <- cor(dd) - factor.model(pc.2$loadings)
head(round(pc.diff, 2))
## i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
## i1 0.55 0.02 -0.12 0.01 -0.23 -0.14 -0.08 -0.09 -0.02 0.08 -0.13 -0.03
## i2 0.02 0.35 -0.03 0.15 0.00 0.11 0.06 -0.05 -0.02 0.04 -0.04 0.02
## i3 -0.12 -0.03 0.51 0.00 -0.12 -0.01 -0.14 0.00 -0.14 -0.08 -0.11 0.04
## i4 0.01 0.15 0.00 0.39 -0.03 0.02 -0.02 0.12 0.00 -0.09 -0.07 -0.06
## i5 -0.23 0.00 -0.12 -0.03 0.64 0.07 -0.06 0.07 -0.15 0.05 -0.05 0.00
## i6 -0.14 0.11 -0.01 0.02 0.07 0.39 0.07 0.11 -0.05 -0.04 0.05 -0.15
rm(pc.diff)
# get the same via call to factor.residuals()
# diagonal are the uniquenesses.
pc.diff.2 <- factor.residuals(cor(dd), pc.2$loadings)
head(round(pc.diff.2, 2))
## i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
## i1 0.55 0.02 -0.12 0.01 -0.23 -0.14 -0.08 -0.09 -0.02 0.08 -0.13 -0.03
## i2 0.02 0.35 -0.03 0.15 0.00 0.11 0.06 -0.05 -0.02 0.04 -0.04 0.02
## i3 -0.12 -0.03 0.51 0.00 -0.12 -0.01 -0.14 0.00 -0.14 -0.08 -0.11 0.04
## i4 0.01 0.15 0.00 0.39 -0.03 0.02 -0.02 0.12 0.00 -0.09 -0.07 -0.06
## i5 -0.23 0.00 -0.12 -0.03 0.64 0.07 -0.06 0.07 -0.15 0.05 -0.05 0.00
## i6 -0.14 0.11 -0.01 0.02 0.07 0.39 0.07 0.11 -0.05 -0.04 0.05 -0.15
rm(pc.diff.2)
In der Diagonalen der reproduzierten Korrelationstabelle stehen die Kommunalitäten. In der Diagonalen der Differenzen (Residuen) stehen die spezifischen Anteile (Uniquenesses).
Ein Maß für die Qualität des Fits kann auf diesen Residuen aufbauen. Die Residuen im Verhältnis zur Höhe der Korrelation sind eine Grundidee für einen Fit-Index. Die Summe der quadrierten Residuen im Verhältnis zur Summe der quadrierten Korrelationen, von 1 abgezogen, ist der Wert hinter ‘Fit based upon off diagonal values = …’ Werte über .95 sprechen für einen guten Fit.
Der Likelihood-Quotienten-Test prüft auf Signifikanz ob die Anzahl der Faktoren ausreicht, um die Daten genügend zu erklären. Er setzt Normalverteilung voraus. Geprüft wird die 0-Hypothese, dass die Daten und das Modell mit k Faktoren statistisch gleich sind. Dabei hat die Aufnahme eines Faktors ihren ‘Preis’. Die Anzahl der Elementgleichungen geht in die Modellprüfung mit ein.
Hintergrundartikel von Manhart & Hunger (2008)
Der Kongruenzkoeffizient von Tucker dient dem Vergleich von zwei Faktoranalysen (z. B. nach Split einer Stichprobe), um die Stabilität der Faktorstruktur zu beschreiben. Analog zum Korrelationskoeffizienten interpretierbar. Koeffizienten sollten deutlich über .80 liegen. Befehl: psych::factor.congruence()
Lorenzo-Seva1 & ten Berge (2006) “Tucker’s Congruence Coefficient as a Meaningful Index of Factor Similarity” Artikel oder lokale Kopie über die Bewertung der Höhe von Tuckers Kongruenzkoeffizient.
The congruence coefficient is the cosine of the angle between the two vectors, and can be interpreted as a standardized measure of proportionality of elements in both vectors. It is evaluated as \[ \phi(x,y) = \frac{\sum{x_i, y_i} } {\sqrt{\sum{x_i^2}\sum{y_i^2}}} \] where \(x_i\) and \(y_i\) are the loadings of variable \(i\) on factor \(x\) and \(y\), respectively, \(i=1,...,n\)
“Our results suggest that a value in the range .85–.94 corresponds to a fair similarity, while a value higher than .95 implies that the two factors or components compared can be considered equal.”
# dd <- read.delim(file="http://md.psych.bio.uni-goettingen.de/mv/data/div/werner-fa.txt")
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/virt/v_ei.txt")
# we split the sample into two equal sized subsamples
set.seed(123)
dd$split <- FALSE
dd$split[sample(1:nrow(dd), nrow(dd)/2)] <- TRUE
dd.1 <- dd[dd$split,1:ncol(dd)-1]
dd.2 <- dd[!dd$split,1:ncol(dd)-1]
# we apply ML-FA to the two subsamples
require(psych)
fa.1 <- psych::fa(dd.1,
nfactors=2,
n.obs = nrow(dd.1),
SMC=TRUE,
fm="ml",
rotate="none",
max.iter=100
)
fa.2 <- psych::fa(dd.2,
nfactors=2,
n.obs = nrow(dd.2),
SMC=TRUE,
fm="ml",
rotate="none",
max.iter=100
)
# we compare it
psych::factor.congruence(fa.1, fa.2)
## ML1 ML2
## ML1 -0.97 0.28
## ML2 0.11 0.68
Hierauf wird auch in den einzelnen Units eingegangen.
Principal component analysis involves extracting linear composites of observed variables.
Factor analysis is based on a formal model predicting observed variables from theoretical latent factors.
In psychology these two techniques are often applied in the construction of multi-scale tests to determine which items load on which scales. They typically yield similar substantive conclusions (for a discussion see Comrey (1988) Factor-Analytic Methods of Scale Development in Personality and Clinical Psychology). This helps to explain why some statistics packages seem to bundle them together. I have also seen situations where “principal component analysis” is incorrectly labelled “factor analysis”.
In terms of a simple rule of thumb, I’d suggest that you:
Run factor analysis if you assume or wish to test a theoretical model of latent factors causing observed variables.
Run principal component analysis If you want to simply reduce your correlated observed variables to a smaller set of important independent composite variables.
Principal Component Analysis (PCA) and Common Factor Analysis (CFA) are distinct methods. Often, they produce similar results and PCA is used as the default extraction method in the SPSS Factor Analysis routines. This undoubtedly results in a lot of confusion about the distinction between the two.
The bottom line is that these are two different models, conceptually. In PCA, the components are actual orthogonal linear combinations that maximize the total variance. In FA, the factors are linear combinations that maximize the shared portion of the variance–underlying “latent constructs”. That’s why FA is often called “common factor analysis”. FA uses a variety of optimization routines and the result, unlike PCA, depends on the optimization routine used and starting points for those routines. Simply there is not a single unique solution.
In R, the factanal() function provides CFA with a maximum likelihood extraction. So, you shouldn’t expect it to reproduce an SPSS result which is based on a PCA extraction. It’s simply not the same model or logic. I’m not sure if you would get the same result if you used SPSS’s Maximum Likelihood extraction either as they may not use the same algorithm.
For better or for worse in R, you can, however, reproduce the mixed up “factor analysis” that SPSS provides as its default. Here’s the process in R. With this code, I’m able to reproduce the SPSS Principal Component “Factor Analysis” result using this dataset. (With the exception of the sign, which is indeterminate). That result could also then be rotated using any of R’s available rotation methods.
# Load the base dataset attitude to work with.
data(attitude)
# Compute eigenvalues and eigenvectors of the correlation matrix.
pfa.eigen<-eigen(cor(attitude))
# Print and note that eigenvalues are those produced by SPSS.
# Also note that SPSS will extract 2 components as eigenvalues > 1 = 2
pfa.eigen$values
## [1] 3.7163758 1.1409219 0.8471915 0.6128697 0.3236728 0.2185306 0.1404378
# set a value for the number of factors (for clarity)
factors<-2
# Extract and transform two components.
pfa.eigen$vectors [ , 1:factors ] %*%
+ diag ( sqrt (pfa.eigen$values [ 1:factors ] ),factors,factors )
## [,1] [,2]
## [1,] 0.7961866 0.4239721
## [2,] 0.8492648 0.3563602
## [3,] 0.6839314 0.1022845
## [4,] 0.8261764 0.0481755
## [5,] 0.8619753 -0.1913818
## [6,] 0.3573175 -0.6436979
## [7,] 0.5832712 -0.6086213
bei den jeweiligen Einzelverfahren
library(dplyr)
library(psych)
# get data
dd <- read.delim("http://md.psych.bio.uni-goettingen.de/mv/data/div/bfi_rs1.txt")
bfi_10_items2 <- c("bfi.k.2.i1","bfi.k.2.i7","bfi.k.2.i8","bfi.k.2.i9","bfi.k.2.i21","bfi.k.2.i16", "bfi.k.2.i2","bfi.k.2.i3","bfi.k.2.i19","bfi.k.2.i15")
bfi.items <- dd[bfi_10_items2]
# just to countercheck wheather parallel analysis suggests the theoretically postulated 5 factors
items.parallel <- fa.parallel(bfi.items, fa="pc")
## Parallel analysis suggests that the number of factors = NA and the number of components = 4
# ... no, 4 components are suggested by parallel analysis
# PCA with varimax rotation of BFI-10
# pca with 5 components that are postulated by BFI model, varimax rotated
pc <- psych::principal(bfi.items, rotate='varimax', nfactors=5)
print.psych(pc, cut=0.3, sort=F)
## Principal Components Analysis
## Call: psych::principal(r = bfi.items, nfactors = 5, rotate = "varimax")
## Standardized loadings (pattern matrix) based upon correlation matrix
## RC1 RC2 RC4 RC3 RC5 h2 u2 com
## bfi.k.2.i1 0.82 0.70 0.30 1.1
## bfi.k.2.i7 0.72 0.55 0.45 1.1
## bfi.k.2.i8 0.81 0.72 0.28 1.2
## bfi.k.2.i9 0.31 -0.66 0.31 0.74 0.26 2.6
## bfi.k.2.i21 0.86 0.75 0.25 1.0
## bfi.k.2.i16 -0.68 0.47 0.70 0.30 1.9
## bfi.k.2.i2 0.72 0.69 0.31 1.7
## bfi.k.2.i3 -0.68 0.37 0.64 0.36 1.7
## bfi.k.2.i19 0.65 0.43 0.66 0.34 2.0
## bfi.k.2.i15 -0.33 0.57 -0.38 0.61 0.39 2.6
##
## RC1 RC2 RC4 RC3 RC5
## SS loadings 1.75 1.34 1.33 1.21 1.12
## Proportion Var 0.18 0.13 0.13 0.12 0.11
## Cumulative Var 0.18 0.31 0.44 0.56 0.68
## Proportion Explained 0.26 0.20 0.20 0.18 0.17
## Cumulative Proportion 0.26 0.46 0.66 0.83 1.00
##
## Mean item complexity = 1.7
## Test of the hypothesis that 5 components are sufficient.
##
## The root mean square of the residuals (RMSR) is 0.11
## with the empirical chi square 1315.78 with prob < 2.4e-282
##
## Fit based upon off diagonal values = 0.47
pc$Vaccounted
## RC1 RC2 RC4 RC3 RC5
## SS loadings 1.7534956 1.3389434 1.3318050 1.2118364 1.1153488
## Proportion Var 0.1753496 0.1338943 0.1331805 0.1211836 0.1115349
## Cumulative Var 0.1753496 0.3092439 0.4424244 0.5636080 0.6751429
## Proportion Explained 0.2597221 0.1983200 0.1972627 0.1794933 0.1652019
## Cumulative Proportion 0.2597221 0.4580421 0.6553048 0.8347981 1.0000000
pc$loadings
##
## Loadings:
## RC1 RC2 RC4 RC3 RC5
## bfi.k.2.i1 0.821
## bfi.k.2.i7 -0.127 0.720 -0.124
## bfi.k.2.i8 0.167 0.813 0.106 0.128
## bfi.k.2.i9 -0.196 0.309 0.279 -0.661 0.311
## bfi.k.2.i21 0.856
## bfi.k.2.i16 -0.676 0.474
## bfi.k.2.i2 -0.150 0.252 0.723 0.278
## bfi.k.2.i3 -0.681 0.369 0.176
## bfi.k.2.i19 0.648 0.140 0.157 0.430
## bfi.k.2.i15 -0.327 0.572 0.123 -0.384
##
## RC1 RC2 RC4 RC3 RC5
## SS loadings 1.753 1.339 1.332 1.212 1.115
## Proportion Var 0.175 0.134 0.133 0.121 0.112
## Cumulative Var 0.175 0.309 0.442 0.564 0.675
presentation on the differences of PCA and FA.
R-Bloggers Tutorial John Quick [http://www.r-bloggers.com/r-tutorial-series-exploratory-factor-analysis/]
Tutorial Wollschläger: [http://www.uni-kiel.de/psychologie/rexrepos/posts/multFA.html]
Field (2012, p. 112) Kapitel 3: R Environment
Zum Unterschied von PCA und FA Link
Faktorenanalysen wollen eine Anzahl von Variablen auf weniger Variablen (Faktoren) reduzieren, wobei so viel Information wie möglich erhalten bleiben soll, die in den Ursprungsvariablen enthalten ist.
Im Kern wird versucht, die Korrelationsmatrix der Originalvariablen durch wenige Faktoren so gut wie möglich zu reproduzieren.
Unterscheidung PCA, FA-Varianten und CFA
Das Package `library(psych)´ hat speziell für die Psychologie interessante Befehle, auch im Zusammenhang mit Faktorenanalysen, in diesem Kontext
cortest.bartlett()
, KMO()
, fa.parallel()
, print.psych()
, principal()
usw.Bei PCA ist erklärter Varianzanteil durch Komponenten nach Größe geordnet und unabhängig von Anzahl der extrahierten Faktoren. Auch die Factorscores bleiben bei PCA für jede Komponente gleich, unabhängig von der Menge der Komponenten. Bei eFA ändern sie sich in Abhängigkeit von der Anzahl der extrahierten Faktoren.
PCA: factor scores sind Linearkombinationen der Variablen und der “loadings” deren Ergebnis die individuellen Faktorwerte der Beobachtungen sind. Können auch auf neue Beobachtungen übertragen werden. Das entspricht predict()
im ALM und der Befehl heißt tatsächlich auch predict.psych()
Parallelanalyse
Wir schauen uns die Ladungsmatrix an und versuchen, sie mit Inhalt zu füllen. psych::print.psych()
Marker-Items (Q06 für RC3) und Cross-Loadings (Q12 zwischen RC3 und RC1) in dem Beispiel unten
Wir interpretieren Sinn in eine Zusammenfassung von Zusammenhängen.
Überprüfen faktorieller Strukturen, z. B. Stabilität: eFA an mehreren Datensätzen und die vorgeschlagene Faktorenstruktur auf Ähnlichkeiten prüfen.
eFA vs CFA: Wenn wir eine Vorstellung der Psychologie haben, die hinter den Faktoren steckt, sollten wir eher CFAs anwenden. Mit eFA können wir nur vergleichen, ob bei unterschiedlichen Datensätzen eine ähnliche Faktorenstruktur vorgeschlagen wird. Alternative CFA kommt ist Anwendung von Strukturgleichungsmodellen (Pfadanalysen).
KMO und Zusammenspiel mit den anderen Bewertungs- bzw. Eignungsmaßen
require(tidyverse)
## Loading required package: tidyverse
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.3 ✓ purrr 0.3.4
## ✓ tibble 3.1.0 ✓ stringr 1.4.0
## ✓ tidyr 1.1.3 ✓ forcats 0.5.1
## ✓ readr 1.4.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x ggplot2::%+%() masks psych::%+%()
## x ggplot2::alpha() masks psych::alpha()
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
require(psych)
dd <- read_delim("https://pzezula.pages.gwdg.de/data/raq.dat", delim="\t")
##
## ── Column specification ────────────────────────────────────────────────────────
## cols(
## .default = col_double()
## )
## ℹ Use `spec()` for the full column specifications.
# or
dd <- readr::read_tsv("http://md.psych.bio.uni-goettingen.de/mv/data/af/raq.dat")
##
## ── Column specification ────────────────────────────────────────────────────────
## cols(
## .default = col_double()
## )
## ℹ Use `spec()` for the full column specifications.
# are the data suitable for factorization
# testing whether a correlation matrix is factorable
psych::cortest.bartlett(dd)
## R was not square, finding R from data
## $chisq
## [1] 19334.49
##
## $p.value
## [1] 0
##
## $df
## [1] 253
# ... yes, correlations differ from 0
# ... but we do better
# is the Kaiser-Meyer-Olkin KMO test of factorial adequacy.
kmo_raq <- psych::KMO(dd)
kmo_raq
## Kaiser-Meyer-Olkin factor adequacy
## Call: psych::KMO(r = dd)
## Overall MSA = 0.93
## MSA for each item =
## Q01 Q02 Q03 Q04 Q05 Q06 Q07 Q08 Q09 Q10 Q11 Q12 Q13 Q14 Q15 Q16
## 0.93 0.87 0.95 0.96 0.96 0.89 0.94 0.87 0.83 0.95 0.91 0.95 0.95 0.97 0.94 0.93
## Q17 Q18 Q19 Q20 Q21 Q22 Q23
## 0.93 0.95 0.94 0.89 0.93 0.88 0.77
# ... the closer the value to 1 the better, here we have good factorial adequacy
# parallel analysis
items.parallel <- fa.parallel(dd, fa="pc")
## Parallel analysis suggests that the number of factors = NA and the number of components = 4
pc <- psych::principal(dd, nfactors=4, scores=TRUE)
# we look at percentages of explained variance and factor loading matrix
print.psych(pc, cut=0.3, sort=F)
## Principal Components Analysis
## Call: psych::principal(r = dd, nfactors = 4, scores = TRUE)
## Standardized loadings (pattern matrix) based upon correlation matrix
## RC3 RC1 RC4 RC2 h2 u2 com
## Q01 0.50 0.36 0.43 0.57 2.4
## Q02 -0.34 0.54 0.41 0.59 1.7
## Q03 -0.57 0.37 0.53 0.47 2.3
## Q04 0.32 0.52 0.31 0.47 0.53 2.4
## Q05 0.32 0.43 0.34 0.66 2.5
## Q06 0.80 0.65 0.35 1.0
## Q07 0.64 0.33 0.55 0.45 1.7
## Q08 0.83 0.74 0.26 1.1
## Q09 0.65 0.48 0.52 1.3
## Q10 0.55 0.33 0.67 1.2
## Q11 0.75 0.69 0.31 1.5
## Q12 0.47 0.52 0.51 0.49 2.1
## Q13 0.65 0.54 0.46 1.6
## Q14 0.58 0.36 0.49 0.51 1.8
## Q15 0.46 0.38 0.62 2.6
## Q16 0.33 0.51 0.31 0.49 0.51 2.6
## Q17 0.75 0.68 0.32 1.5
## Q18 0.68 0.33 0.60 0.40 1.5
## Q19 -0.37 0.43 0.34 0.66 2.2
## Q20 0.68 0.48 0.52 1.1
## Q21 0.66 0.55 0.45 1.5
## Q22 0.65 0.46 0.54 1.2
## Q23 0.59 0.41 0.59 1.4
##
## RC3 RC1 RC4 RC2
## SS loadings 3.73 3.34 2.55 1.95
## Proportion Var 0.16 0.15 0.11 0.08
## Cumulative Var 0.16 0.31 0.42 0.50
## Proportion Explained 0.32 0.29 0.22 0.17
## Cumulative Proportion 0.32 0.61 0.83 1.00
##
## Mean item complexity = 1.8
## Test of the hypothesis that 4 components are sufficient.
##
## The root mean square of the residuals (RMSR) is 0.06
## with the empirical chi square 4006.15 with prob < 0
##
## Fit based upon off diagonal values = 0.96
# as usual in summaries print psych gives us a visualization of result objects properties like
pc$Vaccounted
## RC3 RC1 RC4 RC2
## SS loadings 3.7272497 3.3434674 2.5509149 1.9511936
## Proportion Var 0.1620543 0.1453681 0.1109093 0.0848345
## Cumulative Var 0.1620543 0.3074225 0.4183318 0.5031663
## Proportion Explained 0.3220691 0.2889067 0.2204228 0.1686013
## Cumulative Proportion 0.3220691 0.6109759 0.8313987 1.0000000
pc$loadings
##
## Loadings:
## RC3 RC1 RC4 RC2
## Q01 0.240 0.497 0.356
## Q02 -0.337 0.544
## Q03 -0.202 -0.566 -0.180 0.368
## Q04 0.319 0.517 0.314
## Q05 0.319 0.430 0.238
## Q06 0.800
## Q07 0.638 0.328 0.155
## Q08 0.131 0.168 0.833
## Q09 -0.203 0.118 0.648
## Q10 0.550 0.130 -0.123
## Q11 0.262 0.206 0.747 -0.142
## Q12 0.472 0.523
## Q13 0.647 0.234 0.228 -0.100
## Q14 0.578 0.360 0.136
## Q15 0.459 0.217 0.292 -0.188
## Q16 0.333 0.515 0.313 -0.116
## Q17 0.271 0.223 0.747
## Q18 0.684 0.328 0.127
## Q19 -0.146 -0.371 0.428
## Q20 0.677 -0.142
## Q21 0.286 0.661 0.160
## Q22 -0.191 0.645
## Q23 0.173 -0.199 0.585
##
## RC3 RC1 RC4 RC2
## SS loadings 3.727 3.343 2.551 1.951
## Proportion Var 0.162 0.145 0.111 0.085
## Cumulative Var 0.162 0.307 0.418 0.503
# we can access the factor scores of our observations
head(pc$scores)
## RC3 RC1 RC4 RC2
## [1,] -0.1066865 0.93003207 1.8266534 0.4592970
## [2,] 0.5827147 0.18940296 0.0413915 -0.2934021
## [3,] 0.5473302 -0.02775712 -0.1998143 0.9714979
## [4,] -0.7460157 -0.72254964 0.6869656 0.1867694
## [5,] -0.2518823 0.51410587 0.6336317 -0.6834459
## [6,] -1.9164897 0.27320273 0.6815885 0.5265475
# ... or even add them to our data matrix
dd.e <- cbind(dd, pc$scores)
head(dd.e)
## Q01 Q02 Q03 Q04 Q05 Q06 Q07 Q08 Q09 Q10 Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19
## 1 4 5 2 4 4 4 3 5 5 4 5 4 4 4 4 3 5 4 3
## 2 5 5 2 3 4 4 4 4 1 4 4 3 5 3 2 3 4 4 3
## 3 4 3 4 4 2 5 4 4 4 4 3 3 4 2 4 3 4 3 5
## 4 3 5 5 2 3 3 2 4 4 2 4 4 4 3 3 3 4 2 4
## 5 4 5 3 4 4 3 3 4 2 4 4 3 3 4 4 4 4 3 3
## 6 4 5 3 4 2 2 2 4 2 3 4 2 3 3 1 4 3 1 5
## Q20 Q21 Q22 Q23 RC3 RC1 RC4 RC2
## 1 4 4 4 1 -0.1066865 0.93003207 1.8266534 0.4592970
## 2 2 2 2 4 0.5827147 0.18940296 0.0413915 -0.2934021
## 3 2 3 4 4 0.5473302 -0.02775712 -0.1998143 0.9714979
## 4 2 2 2 3 -0.7460157 -0.72254964 0.6869656 0.1867694
## 5 2 4 2 2 -0.2518823 0.51410587 0.6336317 -0.6834459
## 6 1 3 5 2 -1.9164897 0.27320273 0.6815885 0.5265475
# we can even predict factor scores for new observations
dd.n <- rbind(dd[1,],
c(3, 4, 4, 2, 2, 1, 1, 4, 3, 3, 3, 3, 2, 3, 4, 3, 2, 2, 4, 1, 1, 4, 2), # is exactly equal to observation 22 of dd
c(1, 2, 4, 4, 3, 1, 2, 4, 3, 4, 3, 2, 2, 1, 2, 3, 3, 3, 4, 2, 2, 3, 3)
)
dd.n
## # A tibble: 3 x 23
## Q01 Q02 Q03 Q04 Q05 Q06 Q07 Q08 Q09 Q10 Q11 Q12 Q13
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4 5 2 4 4 4 3 5 5 4 5 4 4
## 2 3 4 4 2 2 1 1 4 3 3 3 3 2
## 3 1 2 4 4 3 1 2 4 3 4 3 2 2
## # … with 10 more variables: Q14 <dbl>, Q15 <dbl>, Q16 <dbl>, Q17 <dbl>,
## # Q18 <dbl>, Q19 <dbl>, Q20 <dbl>, Q21 <dbl>, Q22 <dbl>, Q23 <dbl>
predict.psych(pc, dd.n[2,], dd)
## RC3 RC1 RC4 RC2
## [1,] -1.71775 -0.669199 -0.1793628 -0.5121014
dd.e[22,]
## Q01 Q02 Q03 Q04 Q05 Q06 Q07 Q08 Q09 Q10 Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19
## 22 3 4 4 2 2 1 1 4 3 3 3 3 2 3 4 3 2 2 4
## Q20 Q21 Q22 Q23 RC3 RC1 RC4 RC2
## 22 1 1 4 2 -1.71775 -0.669199 -0.1793628 -0.5121014
pc.n <- predict.psych(pc, dd.n, dd)
pc.n
## RC3 RC1 RC4 RC2
## [1,] -0.1066865 0.93003207 1.8266534 0.4592970
## [2,] -1.7177495 -0.66919901 -0.1793628 -0.5121014
## [3,] -2.0493875 -0.02482569 -0.3172870 -1.0614646
# observation 22 of dd had the same values as observation 2 in dd.n
pc$scores[22,]
## RC3 RC1 RC4 RC2
## -1.7177495 -0.6691990 -0.1793628 -0.5121014