Я полагаю, что в центре внимания вопроса находится не столько теоретическая, сколько практическая сторона, т. Е. Как реализовать факторный анализ дихотомических данных в R.
Во-первых, давайте смоделируем 200 наблюдений от 6 переменных, исходя из 2 ортогональных факторов. Я сделаю пару промежуточных шагов и начну с многомерных нормальных непрерывных данных, которые я позже разделю. Таким образом, мы можем сравнивать корреляции Пирсона с полихорическими корреляциями и сравнивать факторные нагрузки из непрерывных данных с данными из дихотомических данных и истинных нагрузок.
set.seed(1.234)
N <- 200 # number of observations
P <- 6 # number of variables
Q <- 2 # number of factors
# true P x Q loading matrix -> variable-factor correlations
Lambda <- matrix(c(0.7,-0.4, 0.8,0, -0.2,0.9, -0.3,0.4, 0.3,0.7, -0.8,0.1),
nrow=P, ncol=Q, byrow=TRUE)
x = Λ f+ еИксΛее н.о.р., средних 0, обычных ошибок.
library(mvtnorm) # for rmvnorm()
FF <- rmvnorm(N, mean=c(5, 15), sigma=diag(Q)) # factor scores (uncorrelated factors)
E <- rmvnorm(N, rep(0, P), diag(P)) # matrix with iid, mean 0, normal errors
X <- FF %*% t(Lambda) + E # matrix with variable values
Xdf <- data.frame(X) # data also as a data frame
Сделайте факторный анализ для непрерывных данных. Расчетные нагрузки аналогичны истинным при игнорировании не относящегося к делу знака.
> library(psych) # for fa(), fa.poly(), factor.plot(), fa.diagram(), fa.parallel.poly, vss()
> fa(X, nfactors=2, rotate="varimax")$loadings # factor analysis continuous data
Loadings:
MR2 MR1
[1,] -0.602 -0.125
[2,] -0.450 0.102
[3,] 0.341 0.386
[4,] 0.443 0.251
[5,] -0.156 0.985
[6,] 0.590
Теперь давайте дихотомизируем данные. Мы будем хранить данные в двух форматах: в виде фрейма данных с упорядоченными коэффициентами и в виде числовой матрицы. hetcor()
из пакетаpolycor
дает нам полихорическую корреляционную матрицу, которую мы позже будем использовать для FA.
# dichotomize variables into a list of ordered factors
Xdi <- lapply(Xdf, function(x) cut(x, breaks=c(-Inf, median(x), Inf), ordered=TRUE))
Xdidf <- do.call("data.frame", Xdi) # combine list into a data frame
XdiNum <- data.matrix(Xdidf) # dichotomized data as a numeric matrix
library(polycor) # for hetcor()
pc <- hetcor(Xdidf, ML=TRUE) # polychoric corr matrix -> component correlations
Теперь используйте полихорическую корреляционную матрицу, чтобы сделать обычную FA. Обратите внимание, что расчетные нагрузки довольно похожи на те, которые получены из непрерывных данных.
> faPC <- fa(r=pc$correlations, nfactors=2, n.obs=N, rotate="varimax")
> faPC$loadings
Loadings:
MR2 MR1
X1 -0.706 -0.150
X2 -0.278 0.167
X3 0.482 0.182
X4 0.598 0.226
X5 0.143 0.987
X6 0.571
Вы можете пропустить шаг вычисления полихорической корреляционной матрицы самостоятельно и напрямую использовать fa.poly()
из пакета psych
, который в конце концов делает то же самое. Эта функция принимает необработанные дихотомические данные в виде числовой матрицы.
faPCdirect <- fa.poly(XdiNum, nfactors=2, rotate="varimax") # polychoric FA
faPCdirect$fa$loadings # loadings are the same as above ...
РЕДАКТИРОВАТЬ: Для оценки факторов, посмотрите на пакет, ltm
который имеет factor.scores()
функцию специально для данных о политомных результатах. Пример приведен на этой странице -> «Факторные оценки - оценки способностей».
Вы можете визуализировать загрузки из факторного анализа, используя factor.plot()
и fa.diagram()
, и из пакета psych
. По какой-то причине factor.plot()
принимает только $fa
компонент результата из fa.poly()
, а не полный объект.
factor.plot(faPCdirect$fa, cut=0.5)
fa.diagram(faPCdirect)
Параллельный анализ и анализ «очень простой структуры» помогают в выборе ряда факторов. Опять же, пакет psych
имеет необходимые функции. vss()
принимает полихорическую корреляционную матрицу в качестве аргумента.
fa.parallel.poly(XdiNum) # parallel analysis for dichotomous data
vss(pc$correlations, n.obs=N, rotate="varimax") # very simple structure
Параллельный анализ для полихорического ЖК также предоставляется пакетом random.polychor.pa
.
library(random.polychor.pa) # for random.polychor.pa()
random.polychor.pa(data.matrix=XdiNum, nrep=5, q.eigen=0.99)
Обратите внимание, что функции fa()
и fa.poly()
предоставляют множество других возможностей для настройки FA. Кроме того, я отредактировал некоторые выходные данные, которые дают хорошие тесты соответствия и т. Д. Документация для этих функций (и пакета psych
в целом) превосходна. Этот пример предназначен только для начала.