La question porte sur «l'identification des relations [linéaires] sous-jacentes» entre les variables.
Le moyen rapide et facile de détecter des relations consiste à régresser toute autre variable (utiliser une constante, même) par rapport à ces variables à l'aide de votre logiciel préféré: toute bonne procédure de régression détectera et diagnostiquera la colinéarité. (Vous n'aurez même pas la peine de regarder les résultats de la régression: nous comptons simplement sur un effet secondaire utile de la configuration et de l'analyse de la matrice de régression.)
0
(Il y a un art et beaucoup de littérature associé à l'identification de ce qu'est un "petit" chargement. Pour modéliser une variable dépendante, je suggère de l'inclure dans les variables indépendantes de l'ACP afin d'identifier les composants - indépendamment de leur taille - dans laquelle la variable dépendante joue un rôle important. De ce point de vue, "petit" signifie beaucoup plus petit que n'importe quel composant de ce type.)
Regardons quelques exemples. (Celles-ci sont utilisées R
pour les calculs et le traçage.) Commencez par une fonction pour effectuer l'ACP, recherchez les petits composants, tracez-les et retournez les relations linéaires entre eux.
pca <- function(x, threshold, ...) {
fit <- princomp(x)
#
# Compute the relations among "small" components.
#
if(missing(threshold)) threshold <- max(fit$sdev) / ncol(x)
i <- which(fit$sdev < threshold)
relations <- fit$loadings[, i, drop=FALSE]
relations <- round(t(t(relations) / apply(relations, 2, max)), digits=2)
#
# Plot the loadings, highlighting those for the small components.
#
matplot(x, pch=1, cex=.8, col="Gray", xlab="Observation", ylab="Value", ...)
suppressWarnings(matplot(x %*% relations, pch=19, col="#e0404080", add=TRUE))
return(t(relations))
}
B , C, D ,EUNE
process <- function(z, beta, sd, ...) {
x <- z %*% beta; colnames(x) <- "A"
pca(cbind(x, z + rnorm(length(x), sd=sd)), ...)
}
B , … , EA = B + C+ D + EA = B + ( C+ D ) / 2 + Esweep
n.obs <- 80 # Number of cases
n.vars <- 4 # Number of independent variables
set.seed(17)
z <- matrix(rnorm(n.obs*(n.vars)), ncol=n.vars)
z.mean <- apply(z, 2, mean)
z <- sweep(z, 2, z.mean)
colnames(z) <- c("B","C","D","E") # Optional; modify to match `n.vars` in length
B , … , EUNE
La sortie associée au panneau supérieur gauche était
A B C D E
Comp.5 1 -1 -1 -1 -1
00 ≈ A - B - C- D - E
La sortie du panneau central supérieur était
A B C D E
Comp.5 1 -0.95 -1.03 -0.98 -1.02
( A , B , C, D , E)
A B C D E
Comp.5 1 -1.33 -0.77 -0.74 -1.07
UNE′= B′+ C′+ D′+ E′
1 , 1 / 2 , 1 / 2 , 1
En pratique, il n’est souvent pas vrai qu’une variable soit désignée comme une combinaison évidente des autres: tous les coefficients peuvent être de tailles comparables et de signes variables. De plus, lorsqu'il existe plusieurs dimensions de relations, il n'y a pas de moyen unique de les spécifier: une analyse plus approfondie (comme la réduction des lignes) est nécessaire pour identifier une base utile pour ces relations. C'est ainsi que le monde fonctionne: tout ce que vous pouvez dire, c'est que ces combinaisons particulières qui sont produites par PCA ne correspondent à presque aucune variation dans les données. Pour y faire face, certaines personnes utilisent directement les plus grandes composantes («principales») comme variables indépendantes dans la régression ou l'analyse subséquente, quelle que soit la forme qu'elle pourrait prendre. Si vous faites cela, n'oubliez pas d'abord de supprimer la variable dépendante de l'ensemble de variables et de refaire le PCA!
Voici le code pour reproduire cette figure:
par(mfrow=c(2,3))
beta <- c(1,1,1,1) # Also can be a matrix with `n.obs` rows: try it!
process(z, beta, sd=0, main="A=B+C+D+E; No error")
process(z, beta, sd=1/10, main="A=B+C+D+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+C+D+E; Large error")
beta <- c(1,1/2,1/2,1)
process(z, beta, sd=0, main="A=B+(C+D)/2+E; No error")
process(z, beta, sd=1/10, main="A=B+(C+D)/2+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+(C+D)/2+E; Large error")
(J'ai dû jouer avec le seuil dans les cas de grandes erreurs afin d'afficher un seul composant: c'est la raison pour laquelle je fournis cette valeur comme paramètre process
.)
L'utilisateur ttnphns a aimablement dirigé notre attention sur un sujet étroitement lié. Une de ses réponses (par JM) suggère l'approche décrite ici.