Aujourd’hui, je vous propose un article sur les corrélations deux à deux ; on les appelle aussi corrélations par paires, ou encore pairwise correlations en anglais. Je commencerai par expliquer pourquoi on peut être amené à calculer ces corrélations par paires, puis je présenterai les principales fonctions que j’utilise pour les représenter.
Classiquement, on s’intéresse à ces corrélations par paires lorsqu’on ajuste un modèle de régression linéaire multiple (ou linéaire généralisé multiple), pour évaluer les effets des variables explicatives sur une variable réponse à expliquer.
En effet, lorsque le modèle de régression multiple comporte plusieurs (au moins deux) variables prédictives fortement liées entre elles de façon linéaire, cela entraîne une instabilité du modèle, et le rend in-interprétable. On parle de multicollinéarité.
Il est donc important de repérer ces variables fortement liées entre elles de façon linéaire, afin de ne pas les inclure simultanément dans le modèle.
Et pour cela, on va calculer le coefficient de corrélation de Pearson, entre toutes les variables numériques deux à deux. C’est ce qu’on appelle les pairwise correlations (ou corrélation deux à deux).
Remarque : Certains utilisent une valeur seuil du coefficient de corrélation de Pearson à 0.85 pour retirer une des deux variable du modèle.
Au delà de ce problème de multicollinéarité, il peut également être intéressant pour mieux comprendre son jeu de données, d’étudier comment les variables sont liées entre elles. Et notamment de connaître les variables qui évoluent dans le même sens, celles qui évoluent à l’opposé, ou encore celles qui sont totalement indépendantes. Cela peut vraiment être utile, par exemple, pour bien comprendre les résultats d’un modèle de régression multiple.
On s’intéresse aussi à ces corrélations deux à deux (ou par paires) lorsqu’on souhaite construire un modèle prédictif, car de nombreux algorithmes de Machine Learning sont plus performants lorsque les prédicteurs ne sont pas fortement corrélés.
Je vais alors vous présenter les principales fonctions que j’utilise lorsque je veux étudier les corrélations deux à deux. Pour les illustrer, je vais utiliser le jeu de données mtcars qui appartient au package datasets (chargé par défaut) en lui retirant les variables am et vs qui sont des variables catégorielles. Je nomme ce nouveau jeu de données mtcars2 :
library(tidyverse)
mtcars2 <- mtcars %>%
select(-vs, -am)
head(mtcars2)
## mpg cyl disp hp drat wt qsec gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 3 1
Une façon toute simple d‘obtenir les coefficients de corrélation de Pearson pour toutes les paires de variables, est d’utiliser la fonction cor() du package stats
, chargé par défaut.
cor(mtcars2)
## mpg cyl disp hp drat wt
## mpg 1.0000000 -0.8521620 -0.8475514 -0.7761684 0.68117191 -0.8676594
## cyl -0.8521620 1.0000000 0.9020329 0.8324475 -0.69993811 0.7824958
## disp -0.8475514 0.9020329 1.0000000 0.7909486 -0.71021393 0.8879799
## hp -0.7761684 0.8324475 0.7909486 1.0000000 -0.44875912 0.6587479
## drat 0.6811719 -0.6999381 -0.7102139 -0.4487591 1.00000000 -0.7124406
## wt -0.8676594 0.7824958 0.8879799 0.6587479 -0.71244065 1.0000000
## qsec 0.4186840 -0.5912421 -0.4336979 -0.7082234 0.09120476 -0.1747159
## gear 0.4802848 -0.4926866 -0.5555692 -0.1257043 0.69961013 -0.5832870
## carb -0.5509251 0.5269883 0.3949769 0.7498125 -0.09078980 0.4276059
## qsec gear carb
## mpg 0.41868403 0.4802848 -0.5509251
## cyl -0.59124207 -0.4926866 0.5269883
## disp -0.43369788 -0.5555692 0.3949769
## hp -0.70822339 -0.1257043 0.7498125
## drat 0.09120476 0.6996101 -0.0907898
## wt -0.17471588 -0.5832870 0.4276059
## qsec 1.00000000 -0.2126822 -0.6562492
## gear -0.21268223 1.0000000 0.2740728
## carb -0.65624923 0.2740728 1.0000000
Mais comme vous pouvez le voir, la matrice de corrélation deux à deux obtenue n’est pas très facile à interpréter.
Pour avoir une meilleure idée des relations entre les variables, j’aime bien utiliser la fonction pairs() du package graphics (chargé par défaut). Pour que la fonction renvoie une visualisation intéressante, il est nécessaire de copier coller dans la console la fonction panel.cor_simple(). Je l’ai adaptée de la fonction panel.cor disponible ici.
panel.cor_simple <- function(x, y, digits=2, prefix="", cex.cor)
{
usr <- par("usr"); on.exit(par(usr))
par(usr = c(0, 1, 0, 1))
r <- cor(x, y)
txt <- format(c(r, 0.123456789), digits=digits)[1]
txt <- paste(prefix, txt, sep="")
if(missing(cex.cor)) cex <- 0.8/strwidth(txt)
test <- cor.test(x,y)
# borrowed from printCoefmat
Signif <- symnum(test$p.value, corr = FALSE, na = FALSE,
cutpoints = c(0, 0.001, 0.01, 0.05, 0.1, 1),
symbols = c("***", "**", "*", ".", " "))
text(0.5, 0.5, txt, cex = cex * abs(r))
text(.8, .8, Signif, cex=cex, col=2)
}
Cette fonction panel.cor_simple() entre dans l’argument upper.pannel de la fonction pairs() :
pairs(mtcars2, lower.panel=panel.smooth, upper.panel=panel.cor_simple)
J’aime bien cette représentation, car dans la partie basse (à gauche), on peut voir la courbe de régression loess (régression de voisinage) entre les deux variables; ça permet d’avoir une idée de la forme de leur relation. Et dans la partie haute (à droite) on retrouve le coefficient de corrélation avec des étoiles pour indiquer la significativité du test d’égalité à zéro du coefficient de corrélation de Pearson.
On peut également obtenir une version plus complète avec le R2 et la p-value du test de l’égalité à zéro du coefficient de corrélation de Pearson, en utilisant la fonction panel.cor() du package “quantable”, en argument de upper.panel.
library(quantable)
pairs(mtcars2, lower.panel=panel.smooth, upper.panel=panel.cor)
Pour obtenir des représentations plus synthétiques et plus visuelles, j’utilise la fonction corrplot(), du package corrplot.
Voici quelques visualisations que j’apprécie particulièrement :
library(corrplot)
M <- cor(mtcars2)
corrplot(M, method = "number", type="upper")
Pour améliorer encore la visualisation, on peut aussi colorier la case en fonction du coefficient de corrélation :
col <- colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD", "#4477AA"))
corrplot(M, method="color", col=col(200),
type="upper",
addCoef.col = "black")
On peut encore obtenir une permutation des lignes et des colonnes avec l’argument order=”hclust” afin que les variables apparaissent par ensemble selon le sens de leur corrélation.
corrplot(M, method="color", col=col(200) ,
type="upper",
addCoef.col = "black", order="hclust")
Il est également possible de passer en blanc les cases correspondant à des corrélations non significatives. Pour cela, on utilise dans un premier temps la fonction cor.mtest(), qu’il faut copier coller dans la console.
cor.mtest <- function(mat, ...) {
mat <- as.matrix(mat)
n <- ncol(mat)
p.mat<- matrix(NA, n, n)
diag(p.mat) <- 0
for (i in 1:(n - 1)) {
for (j in (i + 1):n) {
tmp <- cor.test(mat[, i], mat[, j], ...)
p.mat[i, j] <- p.mat[j, i] <- tmp$p.value
}
}
colnames(p.mat) <- rownames(p.mat) <- colnames(mat)
p.mat
}
Appliquée sur le jeu de données, cette fonction produit en sortie, non plus une matrice de corrélation deux à deux, mais une matrice de p-values de tests d’égalité à 0 des coefficients de corrélations de Pearson :
p.mat <- cor.mtest(mtcars2)
p.mat
## mpg cyl disp hp drat
## mpg 0.000000e+00 6.112687e-10 9.380327e-10 1.787835e-07 1.776240e-05
## cyl 6.112687e-10 0.000000e+00 1.802838e-12 3.477861e-09 8.244636e-06
## disp 9.380327e-10 1.802838e-12 0.000000e+00 7.142679e-08 5.282022e-06
## hp 1.787835e-07 3.477861e-09 7.142679e-08 0.000000e+00 9.988772e-03
## drat 1.776240e-05 8.244636e-06 5.282022e-06 9.988772e-03 0.000000e+00
## wt 1.293959e-10 1.217567e-07 1.222320e-11 4.145827e-05 4.784260e-06
## qsec 1.708199e-02 3.660533e-04 1.314404e-02 5.766253e-06 6.195826e-01
## gear 5.400948e-03 4.173297e-03 9.635921e-04 4.930119e-01 8.360110e-06
## carb 1.084446e-03 1.942340e-03 2.526789e-02 7.827810e-07 6.211834e-01
## wt qsec gear carb
## mpg 1.293959e-10 1.708199e-02 5.400948e-03 1.084446e-03
## cyl 1.217567e-07 3.660533e-04 4.173297e-03 1.942340e-03
## disp 1.222320e-11 1.314404e-02 9.635921e-04 2.526789e-02
## hp 4.145827e-05 5.766253e-06 4.930119e-01 7.827810e-07
## drat 4.784260e-06 6.195826e-01 8.360110e-06 6.211834e-01
## wt 0.000000e+00 3.388683e-01 4.586601e-04 1.463861e-02
## qsec 3.388683e-01 0.000000e+00 2.425344e-01 4.536949e-05
## gear 4.586601e-04 2.425344e-01 0.000000e+00 1.290291e-01
## carb 1.463861e-02 4.536949e-05 1.290291e-01 0.000000e+00
Cette matrice est ensuite utilisée en argument de p.mat. Le seuil de significativité peut être modif
corrplot(M, method="color", col=col(200),
type="upper", order="hclust",
addCoef.col = "black", # Ajout du coefficient de corrélation
tl.col="black", tl.srt=45, #Rotation des etiquettes de textes
# Combiner avec le niveau de significativité
p.mat = p.mat, sig.level = 0.05, insig = "blank",
# Cacher les coefficients de corrélation sur la diagonale
diag=FALSE
)
Vous trouverez d’autres exemples de l’utilisation du package corrplot dans la vignette,
ainsi que sur ce post.
Un autre package est particulièrement intéressant pour analyser les corrélations deux à deux, il s’agit du package corrr. Ce package est compatible avec le tidyverse.
library(corrr)
library(tidyverse)
Par exemple, on peut rapidement obtenir la matrice des corrélations deux à deux, avec
un format que je trouve très facile à lire.
M <- mtcars2 %>%
correlate() %>%
rearrange() %>%
shave(upper=TRUE)
La fonction rearrange(), permet comme tout à l’heure avec la fonction corrplot de réarranger la matrice pour obtenir des groupes de variables fortement corrélées. Les réarrangements ne sont pas identiques, au moins ici avec ce jeu de données.
M
## # A tibble: 9 x 10
## rowname drat gear wt disp mpg cyl hp carb
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 drat NA NA NA NA NA NA NA NA
## 2 gear 0.700 NA NA NA NA NA NA NA
## 3 wt -0.712 -0.583 NA NA NA NA NA NA
## 4 disp -0.710 -0.556 0.888 NA NA NA NA NA
## 5 mpg 0.681 0.480 -0.868 -0.848 NA NA NA NA
## 6 cyl -0.700 -0.493 0.782 0.902 -0.852 NA NA NA
## 7 hp -0.449 -0.126 0.659 0.791 -0.776 0.832 NA NA
## 8 carb -0.0908 0.274 0.428 0.395 -0.551 0.527 0.750 NA
## 9 qsec 0.0912 -0.213 -0.175 -0.434 0.419 -0.591 -0.708 -0.656
## # ... with 1 more variable: qsec <dbl>
Si on le souhaite, on peut facilement obtenir la matrice de corrélation de Spearman, ou de Kendall, à l’aide de l’argument méthod :
s <- mtcars2 %>%
correlate(method="spearman") %>%
rearrange() %>%
shave(upper=TRUE)
Ms
## # A tibble: 9 x 10
## rowname drat gear wt disp mpg cyl hp carb
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 drat NA NA NA NA NA NA NA NA
## 2 gear 0.745 NA NA NA NA NA NA NA
## 3 wt -0.750 -0.676 NA NA NA NA NA NA
## 4 disp -0.684 -0.594 0.898 NA NA NA NA NA
## 5 mpg 0.651 0.543 -0.886 -0.909 NA NA NA NA
## 6 cyl -0.679 -0.564 0.858 0.928 -0.911 NA NA NA
## 7 hp -0.520 -0.331 0.775 0.851 -0.895 0.902 NA NA
## 8 carb -0.125 0.115 0.500 0.540 -0.657 0.580 0.733 NA
## 9 qsec 0.0919 -0.148 -0.225 -0.460 0.467 -0.572 -0.667 -0.659
## # ... with 1 more variable: qsec <dbl>
On peut aussi obtenir un format plus concis de cette matrice de corrélation deux à deux, avec la fonction fashion().
fashion(M)
## rowname drat gear wt disp mpg cyl hp carb qsec
## 1 drat
## 2 gear .70
## 3 wt -.71 -.58
## 4 disp -.71 -.56 .89
## 5 mpg .68 .48 -.87 -.85
## 6 cyl -.70 -.49 .78 .90 -.85
## 7 hp -.45 -.13 .66 .79 -.78 .83
## 8 carb -.09 .27 .43 .39 -.55 .53 .75
## 9 qsec .09 -.21 -.17 -.43 .42 -.59 -.71 -.66
Mais le vrai plus de ce package, c’est la fonction network_plot(), qui permet un autre type de visualisation qui me semble vraiment très intéressante, même si j’ai très peu de recul sur ce type de graph.
mtcars2%>%
correlate() %>%
network_plot(min_cor = .2)
Et vous, que pensez vous de cette nouvelle représentation ?
Dans tous les cas, j’espère que ce court post, vous permettra de mieux étudier les corrélations deux à deux (ou par paire ou encore pairwise corrélation) entre vos variables, que cela soit pour identifier d’éventuels problèmes de multicollinéarité, ou simplement pour mieux comprendre vos données.
Si vous utilisez d’autres fonctions, n’hésitez pas à me les indiquer en commentaire.
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee
Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.