Identier les facteurs latents en SHS avec R

Exemples d’application du couple analyse factorielle exploratoire (AFE) / analyse factorielle confirmatoire (CFA)

Grégoire Le Campion (Passages, CNRS)

Solenne Roux (LabPsy, Université de Bordeaux)

featured

Cette fiche présente deux méthodes d’analyse factorielle et leurs applications sous R. Ces méthodes cousines de l’analyse en composante principale, s’en distinguent notamment car elles permettent de mettre en évidence des facteurs latents plutôt que des composantes principales. Cette approche par les facteurs latents est surtout utilisée en Psychologie. Moins répandue dans les autres disciplines des sciences humaines et sociales, elle pourrait néanmoins s’avérer particulièrement utile pour répondre à des hypothèses ou besoins particuliers dans toutes les disciplines des SHS.

Pré-requis : Connaissances de base en traitement et analyse de données. Être familier des risques induits par les outliers, la multicolinéarité, etc. dans la modélisation statistique.

Introduction

1 L’analyse factorielle

Comment rendre compte, de manière simple, de la complexité des différents types de relations qui existent entre plusieurs variables d’une base de données ?

C’est à cette question que permet, entre autre, de répondre l’analyse multivariée, et par extension les méthodes d’analyse factorielle qui appartiennent à ce champs de méthodes.

1.1 L’Objectif de l’analyse factorielle ?

L’objectif général de l’analyse factorielle est de réduire un nombre important d’informations (c’est-à-dire les valeurs contenues dans différentes variables) à quelques grandes dimensions. Il s’agit de synthétiser l’information. Par exemple, imaginons des chercheurs souhaitant étudier le comportement de préservation de l’environnement des français. Pour cela, ils récoltent différentes données concernant le statut socioprofessionnel des participants, leur état de santé, leur zone géographique d’habitation, leur implication dans des associations, etc. Ils recueillent donc beaucoup de données dans chacun des différents thèmes susceptibles d’expliquer leurs hypothèses. Afin de synthétiser l’information alors recueillie, et éventuellement par la suite de pouvoir dégager des profils de comportement ou des liens de causalités, ils feront d’abord appel à l’une des méthodes de factorisation existante.

Comme dans toute analyse statistique, on va chercher à expliquer la plus forte proportion de la variance (de la covariance dans le cas de l’analyse factorielle) par un nombre aussi restreint que possible de variables (appelées dans l’analyse factorielle composantes ou facteurs).

1.2 Les différents types d’analyses factorielles

L’analyse factorielle est, elle aussi, un regroupement de différentes méthodes dont les plus connues et les plus utilisées en SHS sont, pour les données quantitatives : l’analyse en composante principale (ACP) et l’analyse factorielle exploratoire (AFE) ; et pour les données qualitatives : l’analyse factorielle des correspondances (AFC) et l’analyse des correspondances multiples (ACM).

Ici nous vous parlerons des méthodes de l’analyse factorielle exploratoire (AFE, ou EFA en anglais) et de l’analyse factorielle confirmatoire (CFA en anglais) qui sont des méthodes très employées en psychologie notamment.

Ces différentes méthodes, si elles ont toutes l’objectif commun que nous avons exprimé précédemment, ont aussi des différences importantes.

Pour mieux comprendre, un rapide retour historique sur ces méthodes est utile.

1.3 Petite histoire des analyses factorielles

Les premiers à théoriser les méthodes d’analyses factorielles sont le mathématicien anglais Karl Pearson (1901) et le psychologue anglais Charles Spearman (1904).

Pearson développera sa réflexion sur les analyses en compostantes principales (ACP) (Pearson F.R.S., K., 1901). Alors que Spearman se concentrera sur l’analyse factorielle, afin de rendre compte de la variance commune partagée par les items d’un même outil psychométrique (Spearman, C., 1904). Ces pionniers des analyses factorielles travaillaient déjà sur les corrélations, et ce sont ces mêmes personnes qui ont donné leurs noms aux coefficients de corrélation de Pearson et de Spearman.

Mais c’est notamment avec les travaux du mathématicien français Jean-Paul Benzecri (Benzecri J.-P., 1973), dans les années 70, que ces méthodes vont connaître leur essor en France (Pages, J-P., et al., 1979). En particulier grâce à l’apport des représentations graphiques qui permettent de venir synthétiser et illustrer les résultats. C’est Benzecri qui va développer les méthodes sortant du modèle gaussien en prenant en compte les variables catégorielles, telles que les analyses factorielles des correspondances (AFC) et les analyses factorielles des correspondances multiples (ACM)(Pages, J-P., et al., 1979).

Si les méthodes popularisées par Benzecri ont su rester à la postérité et servir dans toutes les SHS, notamment grâce à la mise en oeuvre des méthodes pour travailler sur des données qualitatives, il peut être utile de se rappeler qu’il en existe d’autres qui les ont précédées. C’est par exemple le cas de l’analyse factorielle exploratoire (AFE). Cette méthode, si elle est très utilisée en psychologie - discipline de Spearman, reste effectivement beaucoup plus rare dans les autres sciences humaines et sociales.

2 L’ AFE pour quoi faire

L’AFE vise à explorer la structure sous-jacente d’une base de donnée en identifiant des facteurs latents qui vont expliquer les relations entre les variables de notre base de données.

Qu’est ce qu’un facteur latent ? C’est une variable qui est sous-jacente, car non observée ou non mesurée directement. Ce facteur sous-jacent est postulé pour expliquer les covariances (ou corrélations) entre l’ensemble des variables observées et mesurées (celles de notre base de données). Les variables observées, sont mesurées directement, tandis que les facteurs latents ne le sont pas.

Cette notion de facteur latent est au coeur de l’analyse factorielle exploratoire. En effet l’idée centrale de cette méthode est que nos variables mesurées sont influencées par ces facteurs latents, et que ces facteurs vont expliquer la structure des relations des variables entre elles. Chaque facteur latent est associé à un groupe de variables qui partagent une variance commune. En d’autres termes, le facteur latent “capture” l’information partagée par un ensemble de variables. Supposons que nous avons une base de données constituée de variables mesurant un ensemble de critères observables. Par exemple, lors d’un match de rugby nous avons collecté le nombre de mètres parcourus, de points marqués, du nombre de passes, de plaquages… On pourrait postuler l’existence de facteurs latents qu’on pourrait appeler “performance” et “vision de jeu”. Ces deux facteurs latents ne peuvent pas être mesurés directement, mais peuvent être postulés pour tenter d’expliquer la variation commune de nos variables observées/mesurées.

Notre objectif lorsque l’on réalise une AFE sera d’identifier le nombre et la nature de ces facteurs latents et de comprendre comment ils sont associés et reliés aux variables mesurées. Cette méthode va donc permettre de faire émerger un pattern de relations entre ces variables. La structuration des facteurs obtenus ne sera peut-être d’ailleurs pas exactement celle envisagée par les hypothèses de départ, c’est en cela que l’AFE est exploratoire.

Ainsi, si on cherche à explorer et à identifier des dimensions explicatives sous-jacentes, qui influencent nos variables, comme c’est souvent le cas en SHS, l’AFE s’avérera être un bon choix. Autre avantage important de l’analyse factorielle exploratoire, c’est qu’elle peut être associée à une analyse factorielle confirmatoire afin d’étayer les résultats obtenus. Nous reviendrons plus tard dans cet article sur l’analyse factorielle confirmatoire.

2.1 ACP et AFE : quelles différences ?

En réalité, les différences entre ces deux méthodes sont importantes, bien que pas si simple à appréhender intuitivement. Ces deux méthodes vont différer tant dans leur objectif que dans leur approche. Ainsi, voici trois points principaux où ces méthodes divergent et qu’il est nécessaire de prendre en compte pour faire un choix éclairé entre analyse en composantes principale et analyse factorielle exploratoire : l’objectif principal, la nature des variables et l’interprétation des résultats.

1- L’objectif principal :

ACP et AFE ont comme objectif commun la réduction de l’information, mais elles ne vont pas du tout opérer de la même manière.

  • l’ACP : l’objectif est de réduire la dimensionnalité des données en utilisant les composantes principales. L’ACP va transformer les variables observées en un ensemble de variables non corrélées, que l’on appelle composantes principales. La composante principale est une combinaison linéaire des variables originales qui capture le plus possible de variance présente dans les données. Ces composantes principales sont classées par ordre décroissant de l’importance de la variance qu’elles capturent. Tout l’enjeu de l’ACP est de définir des composantes principales qui permettent de réduire la dimensionnalité des données tout en conservant l’information essentielle contenue dans les variables d’origine. Les composantes principales étant des variables non corrélées entre elles, cela simplifie l’interprétation des relations entre les observations. Pour résumer, l’objectif principal de l’ACP est de synthétiser nos données en composantes principales en tentant de conserver le maximum de variance des variables de notre base de données.
  • L’AFE : vise à explorer la structure sous-jacente des données en identifiant des facteurs latents qui expliquent les relations entre les variables observées. L’objectif est de réduire la dimensionnalité des données en se centrant sur la variance partagée entre les variables et non sur l’ensemble des données. Dans le cadre de l’AFE, une partie de la variance des données ne sera pas retenue dans le modèle. L’objectif n’étant pas de conserver le maximum de variance de notre jeu de données, mais bien de se centrer sur la variance partagée entre les différentes variables.

2- La nature des variables :

  • L’ACP : Les variables de notre base de données sont plutôt considérées comme des mesures directes. On cherche à réduire la dimensionnalité sans nécessairement interpréter les composantes principales en tant que telles.
  • L’AFE : Les variables sont considérées comme des indicateurs de facteurs latents. On souhaite comprendre la structure sous-jacente de notre base de données.

3- Interprétabilité :

  • L’ACP : Les composantes principales sont des combinaisons linéaires des variables originales et peuvent être peu interprétables du point de vue conceptuel. On va considérer le poids ou la contribution d’une variable pour chaque composante principale, ce qui va permettre de mesurer l’importance relative des variables dans la variance totale de nos données.
  • L’AFE : Les facteurs latents identifiés sont souvent interprétables comme des concepts sous-jacents aux données, mais qu’il est nécessaire d’identifier et de théoriser. Pour l’interprétation, nous allons étudier les charges factorielles associées à chaque facteur latent. Il s’agit tout simplement des corrélations de chaque variable avec chaque facteur latent. Ces corrélations nous permettent d’étudier la relation entre les variables et les facteurs latents, et donc de donner du sens à ces facteurs alors identifiés. L’analyse factorielle exploratoire repose sur la comparaison entre la matrice de corrélation initiale (sans la grille de lecture obtenue suite à l’identification des facteurs latents) et la matrice de corrélation obtenue suite à l’identification des facteurs. Si la différence entre ces deux matrices est faible, alors l’analyse factorielle exploratoire obtenue est considérée comme bonne et les facteurs latents identifiés permettent bien de réduire l’information proposée. Sinon la structure factorielle des données est à repenser.

Le choix de ces deux méthodes repose globalement sur ce que l’on veut étudier et de ce que l’on veut faire de la variance. Si on considère qu’il n’y a pas de facteur latent et que l’on souhaite conserver le maximum de la variance de nos données alors l’ACP est un choix tout à fait pertinent. En revanche, si on envisage une structure sous-jacente à nos données, et donc la présence de facteurs latents, et que l’on estime qu’il n’est pas forcément nécessaire de conserver toute la variance de nos données, mais uniquement celle qui est partagée entre nos variables, alors l’AFE sera le bon choix.

2.2 Limites de l’AFE

Comme toutes les méthodes d’analyse de données l’AFE comporte des limites.

Le type de variable

La limite majeure de l’AFE, repose sur le fait que cette méthode est plus efficiente avec des variables continues. Toutefois, il est tout-à-fait possible de l’utiliser avec des variables ordonnées : catégories qui suivent un ordre, (par ex. de 1. “Pas du tout d’accord” à 5. “Tout-à-fait d’accord”) en traduisant chaque catégorie par un score. On peut également réaliser ce type d’analyse avec des variables catégorielles (catégories sans échelle de valeur entre elles par ex. : profession), mais il faudra alors être beaucoup plus prudent sur l’interprétation. Et selon les cas, il peut être plus pertinent d’utiliser une autre méthode de factorisation comme l’analyse factorielle des correspondances (AFC) ou une analyse des correspondances multiples (ACM).

La taille de l’échantillon

La taille de l’échantillon est également un élément contraignant pour ce type d’analyse. Si l’échantillon est trop faible au regard de la taille des informations à synthétiser, les résultats obtenus risquent de surreprésenter les spécifictés de la population alors testée. La structure de l’analyse ne sera pas généralisable, mais influencée par les spécificités de l’échantillon. Il est donc important d’avoir une taille d’échantillon suffisamment importante afin de pallier ce type de biais (Young and Pearce 2013). L’échantillon devra être sélectionné selon le nombre de variables contenues dans l’analyse et la force du lien entre les variables mesurées et les facteurs latents (Watkins, M. W., 2018). Plus ce lien sera fort, moins il sera nécessaire d’avoir un échantillon conséquent. Certains auteurs indiquent que si les corrélations entre les variables manifestes et les facteurs latents sont inférieures ou égales à 0.80, 150 observations peuvent suffire à réaliser l’analyse factorielle exploratoire. En revanche, si ces mêmes corrélations sont inférieures à 0.40 il serait alors nécessaire d’avoir un échantillon d’au-moins 300 observations pour retrouver une structure factorielle stable (Schreiber, J., 2021)

La force des liens

Des corrélations trop fortes ou trop faibles entre les variables peuvent mettre en péril la mise en facteur des informations, mais pas pour les mêmes raisons. Si le set de variables soumis à la factorisation n’est pas du tout corrélé, alors les éléments présentés ne partagent pas d’éléments communs et ne peuvent pas être résumés sous un même facteur. L’hétérogénéité des informations peut tout-à-fait empêcher son résumé statistique via l’utilisation des analyses factorielles. Il n’est pas possible de réaliser des analyses factorielles sur des ensembles de variables non-corrélées. A l’inverse, si les variables retenues pour l’analyse sont trop fortement corrélées alors ceci sous-tend qu’elles contiennent des informations tellement similaires qu’elles en sont redondantes. Cette redondance peut biaiser la factorisation des informations, car certains éléments seront surreprésentés - sans que cela ne reflète une quelconque réalité - par rapport à d’autres. Ce problème peut être résolu en sélectionnant uniquement l’une des deux variables représentatives d’un même phénomène. Par exemple, la catégorie socio-professionnelle et le niveau de diplôme sont généralement très corrélés, il faudra sélectionner l’une de ces deux variables dans le modèle d’analyse factorielle pour que celui-ci soit optimal (Tabachnick, B., & Fidell, L., 2014).

L’interprétation

La subjectivité de l’interprétation peut aussi être une limite, notamment sur l’identification et l’interprétation des facteurs latents, qui dépendra beaucoup du chercheur et de son positionnement théorique.

2.3 L’AFE aujourd’hui en sciences humaines

En SHS aujourd’hui l’AFE est surtout utilisée en psychologie, et ce depuis de nombreuses années. La validation des tests psychométriques constitue un exemple classique de l’utilisation de l’AFE et de son utilisation conjointe avec l’Analyse factorielle confirmatoire (AFC). Afin de réaliser des tests standardisés pour évaluer des processus psychologiques, les psychologues ont recours à ce couple d’analyses factorielles, en réalisant une analyse factorielle exploratoire sur un premier échantillon et une analyse factorielle confirmatoire sur un second échantillon (ayant tous 2 les mêmes caractéristiques).

Les psychologues se sont tournés vers ces techniques de réduction des dimensions car, pour la plupart de leurs études, ils souhaitent se centrer sur la variance partagée entre chaque item, plutôt que de chercher à conserver la variance totale d’un ensemble de variables. Le processus méthodologique alors suivi permet de faire émerger une structure factorielle sans nécessairement la totalité des variables présentes. Cette structure factorielle permet d’observer comment les variables du jeu de données rendent compte des facteurs latents qui les sous-tendent. L’objectif est de savoir “Est-ce que je mesure bien ce que je pense mesurer ?”. En d’autres termes, est-ce que les questions posées aux répondants sont adaptées pour accéder à une dimension latente non appréhendable directement.

Un point important nous semble à présent à souligner, sur l’utilisation des analyses factorielles exploratoires et confirmatoires. A partir du moment où un test psychométrique est validé, c’est-à-dire qu’il a déjà été éprouvé par le couple AFE/AFC sur un jeu de données assez conséquent, avec une population ayant les mêmes caractéristiques, il n’est pas nécessaire de remettre en cause la structure du test et nous pouvons directement procéder à une analyse factorielle confirmatoire, afin de vérifier si le modèle alors pré-établi par d’autres, s’ajuste à nos données. Ceci est conseillé afin de ne pas multiplier les tests statistiques et entraîner une inflation des résultats faussements positifs (encore appelés erreur de type II).

Cette approche statistique, peut tout-à-fait être appliquée aux autres disciplines des SHS, à la fois sur l’exploration des bases de données (AFE), ou sur une validation de modèle, ou encore une comparaison dans le temps (couple AFE/AFC). Nous verrons dans cet article comment adapter ce processus statistique à des données non psychologiques.

3 Les packages

if (!require("pacman")) install.packages("pacman")
pacman::p_load(correlation, corrplot, dplyr, EFA.dimensions, effectsize, ggraph, ggplot2, here, lavaan, nFactors, parallel, parameters, psych, RColorBrewer, see, SemPlot, SemTools, table1, usdm)

A quoi servent ces différents packages ? :

  • pacman : est un package de management de packages.

  • here : permet de gérer les chemin d’accès au sein de notre projet

  • les packages correlation et corrplot permettent de réaliser des corrélations et des graphiques tels que des corrélogrammes.

  • dplyr est un package de manipulation de données.

  • Les packages EFA.dimensions, nfactors, psych et parallel sont des packages utilisés pour vérifier si les données sont factorisables grâce à différents indices statistiques (KMO, etc.). Ils permettent également de déterminer le nombre de facteurs optimal à retenir selon le set de données soumis à l’analyse.

  • ggraph, ggplot2, RColorBrewer et see sont des packages dédiés à la production de représentations graphiques.

  • Le package lavaan permet de réaliser des modèles statistiques impliquant des variables latentes, telles qu’elles existent dans les Analyses factorielles exploratoires et confirmatoires.

  • Les packages parameters, et table1 sont utilisés dans cette fiche pour réaliser des statistiques descriptives et des mises en forme de sortie exploitables directement.

  • Le package usdm comprend différentes fonction permettant d’explorer l’impact de différentes sources d’incertitudes dans des mesures d’association. Nous utiliserons surtout les fonctions permettant de mesurer la multicolinéarité entre des variables.

  • Le package effectsize pour interpréter les coefficients de l’analyse factorielle confirmatoire

  • Les packages semPlot et semTools pour réaliser des équations structurelles méthode à laquelle appartient l’analyse factorielle confirmatoire

4 Les données

L’idée de cet article est de présenter l’analyse factorielle exploratoire et de voir comment elle peut constituer une alternative à l’analyse en composante principale. Pour illustrer l’intérêt de ces méthodes en dehors de la psychologie, nous utiliserons des données issues de travaux en géographie. Ces dernières portent sur le prix de l’immobilier. La dimension spatiale de ces données ne sera pas exploitée, ce n’est pas l’objectif des analyses factorielles. En revanche, il pourrait être tout à fait possible et pertinent de cartographier les résultats obtenus ou de les intégrer à des modèles de statistiques spatiales.



Télécharger les données


5 Mise en pratique : exemple du prix de l’immobilier en France hexagonale

Les données du prix de l’immobilier par EPCI (prix médian au m²) sont issues des ventes observées sur l’année 2018, extraites depuis la base de données des notaires de France par Frédéric Audard et Alice Ferrari. Ce fichier a été simplifié pour ne conserver que les variables d’intérêts parmi une cinquantaine Les données statistiques proviennent de l’INSEE (année 2019) : 9 variables ont été choisies pour leur potentialité à expliquer les variations des prix de l’immobilier, concernant la population, le logement et les revenus et niveaux de vie.

Ce fichier est composé des 9 variables suivantes :

  • prix_med : prix médian par EPCI à la vente au m²
  • perc_log_vac : % logements vacants
  • perc_maison : % maisons
  • perc_tiny_log : % petits logements
  • dens_pop : densité de population
  • med_niveau_vis : médiane du niveau de vie
  • part_log_suroccup : % logements suroccupés
  • part_agri_nb_emploi : % agriculteurs
  • part_cadre_profintellec_nbemploi : % cadres et professions intellectuelles
# Chargement des données de base

library(here)
csv_path <- here("data", "immo_afe.csv")

immo <- read.csv2(csv_path, row.names=1)


### Centrer et réduire les variables
dfz <-  data.frame(scale(immo, center=T, scale=T))

Il est extrêmement recommandé de centrer-réduire ses données pour réaliser une analyse statistique telle qu’une analyse factorielle, ou plus généralement lorsque l’on travaille avec des variables n’étant pas sur les mêmes échelles, sur les mêmes ordres de grandeurs. Cela implique de faire subir à nos données une transformation statistique visant à ce qu’elles aient une moyenne de 0 et un écart-type de 1. On parle aussi en statistique de standardisation. Cette transformation permet de conserver la variabilité de nos données (la distance entre chaque valeur reste inchangée), tout en les rendant comparables (elles sont placées sur une même échelle). Dans le cadre de modélisations statistiques, il est nécessaire de réaliser cette opération sur les variables explicatives du modèle. Sur R on peut facilement réaliser cette opération avec la fonction scale() - que nous utilisons dans notre exemple - ou à “la main”. L’opération est simple : on soustrait chaque valeur par la moyenne puis on divise chaque valeur par l’écart-type.

La première étape étant toujours la description des données, voici le code pour réaliser un tableau récapitulatif de nos variables :

table1(~ prix_med + perc_log_vac + perc_maison + perc_tiny_log + dens_pop + med_niveau_vis + part_log_suroccup + part_agri_nb_emploi + part_cadre_profintellec_nbemploi , data=immo) 

La réalisation des représentations graphiques permet d’appréhender les distributions de nos variables et leurs éventuelles spécificités. Voici une façon de réaliser un diagramme des distributions de nos variables.

dfgraph<-subset(immo, select = c(prix_med, perc_log_vac, perc_maison, perc_tiny_log, dens_pop, med_niveau_vis, part_log_suroccup, part_agri_nb_emploi, part_cadre_profintellec_nbemploi))

par(mfrow = c(3,3))

h1 <- hist(dfgraph$prix_med, main=NULL)
h2 <- hist(dfgraph$perc_log_vac, main=NULL)
h3 <- hist(dfgraph$perc_maison, main=NULL)
h4 <- hist(dfgraph$perc_tiny_log, main=NULL)
h5 <- hist(dfgraph$dens_pop, main=NULL)
h6 <- hist(dfgraph$med_niveau_vis, main=NULL)
h7 <- hist(dfgraph$part_log_suroccup, main=NULL)
h8 <- hist(dfgraph$part_agri_nb_emploi, main=NULL)
h9 <- hist(dfgraph$part_cadre_profintellec_nbemploi, main=NULL)

par(mfrow = c(1,1))

5.1 Les pré-requis de l’analyse factorielle

Comme toutes les méthodes statistiques les analyses factorielles ont un certain nombre de pré-requis à vérifier. Ne pas en tenir compte nous expose à des résultats biaisés voire complètement erronés.

5.1.1 Les Outliers : comment les gérer ?

La question du traitement de ces individus extrêmes est loin d’être simple. Elle doit faire l’objet d’une réflexion et de choix importants qu’il faut pouvoir assumer tant statistiquement que théoriquement.

Les outliers sont nos individus extrêmes. Il est toujours nécessaire de pouvoir les identifier afin de savoir comment les gérer. L’enjeu autour de ces individus c’est qu’ils vont nécessairement influencer (voire fausser) les résultats de nos analyses. L’analyse obtenue sera différente si on fait le choix de les supprimer ou de les conserver (Zijlstra et al. 2011).

Il existe un grand nombre d’indicateurs et de distances différentes qui permettent d’identifier des outliers. Nous ne les présenterons pas dans le cadre de cet article. Il existe différents travaux sur le sujet pouvant vous éclairer, dont voici un aperçu (Aguinis et al. 2013 ; Bakker, M., & Wicherts, J. M., 2014 ; Leys et al. 2018 ; Leys et al. 2019, etc.).

Nous avons sorti les outliers de notre base de données. Petite précision, dans notre exemple une seule observation était considérée comme extrême, il s’agissait de l’individu de la ligne 266 correspondant au grand Paris. Il devient beaucoup plus aisé de comprendre pourquoi cet individu est aussi particulier (nous rappelons qu’il y a le prix de l’immobilier au m² dans nos variables), mais aussi des enjeux de le supprimer ou non de notre analyse. En effet, le supprimer c’est retirer le grand Paris de notre analyse des prix de l’immobilier en France hexagonale, avec les conséquences théorique que cela peut impliquer.

Pour cet article nous faisons le choix de le supprimer de notre analyse. Nous cherchons à mettre en évidence les facteurs latents, s’exprimant par nos variables mesurées, qui caractérisent les EPCI de la France Hexagonale. Or malheureusement si nous conservons le grand Paris nous nous exposons à ne pas observer la variabilité des différentes EPCI de l’haxagone, mais uniquement de la distance entre le grand Paris et les autres EPCI de notre base de données. En effet, le grand Paris étant tellement éloigné des autres EPCI sur l’ensemble des variables de notre base de données que celui-ci écrase les variabilités entre les autres communes. Afin de pouvoir faire émerger une structure factorielle qui ait du sens entre nos EPCI, nous faisons le choix de sortir le grand Paris de notre base de données.

Les données sans outliers sont dans le dossier data, le fichier s’appelle dfzp.csv. Nous chargeons cette nouvelle base de données.

# Chargement des données de base

library(here)
csv_path <- here("data", "dfzp.csv")

dfzp <- read.csv(csv_path, row.names=1)

Il faut désormais vérifier si les distributions de nos variables ont été impactées par cette suppression de nos outliers afin vérifier que les analyses envisagées sont toujours réalisables.

dfgraph2<-subset(dfzp, select = c(prix_med, perc_log_vac, perc_maison, perc_tiny_log, dens_pop, med_niveau_vis, part_log_suroccup, part_agri_nb_emploi, part_cadre_profintellec_nbemploi))

par(mfrow = c(3,3))

h1 <- hist(dfgraph2$prix_med, main=NULL)
h2 <- hist(dfgraph2$perc_log_vac, main=NULL)
h3 <- hist(dfgraph2$perc_maison, main=NULL)
h4 <- hist(dfgraph2$perc_tiny_log, main=NULL)
h5 <- hist(dfgraph2$dens_pop, main=NULL)
h6 <- hist(dfgraph2$med_niveau_vis, main=NULL)
h7 <- hist(dfgraph2$part_log_suroccup, main=NULL)
h8 <- hist(dfgraph2$part_agri_nb_emploi, main=NULL)
h9 <- hist(dfgraph2$part_cadre_profintellec_nbemploi, main=NULL)

par(mfrow = c(1,1))

5.1.2 Analyse de la matrice de corrélation

L’analyse des corrélations est une étape toujours essentielle dans l’analyse de données, et notamment dans le cadre de la modélisation statistique.

Cette étape est fondamentale pour plusieurs raisons. D’abord car elle nous permet d’étudier les relations entre nos variables, ce qui va nous donner des indications sur le meilleur modèle pour nos données. En effet, des corrélations trop fortes ou à l’inverse une absence totale de corrélation peut poser de nombreux problèmes comme nous l’avons évoqué précédemment. Par exemple:

  • La multi-colinéarité : Lorsque des variables sont trop fortement corrélées (positivement ou négativement) cela pose un problème de multi-colinéarité. Les variables sont tellement liées qu’il devient difficile de distinguer leur impact individuel, cela va rendre les résultats peu fiables. Il deviendra compliqué d’interpréter les coefficients et de comprendre de quoi rend-il vraiment compte.
  • Des risques de surajustement : Un modèle avec des prédicteurs trop fortement corrélés va être surajusté et donc ne sera pas pertinent dans son rôle prédictif.
  • Une instabilité du modèle : Les modèles avec des variables trop fortement corrélées sont instables. La moindre variation dans les données pourra provoquer de très grandes variations dans les résultats.
  • Un modèle non optimisé : Un modèle doit respecter le principe de parcimonie. Il ne faut pas qu’il contienne de variables redondantes (corrélations trop fortes) ou inutiles (absence de corrélations).
  • Un modèle nul : Une absence totale de corrélations remet en question la pertinence de tester, dans un même modèle, des variables qui n’auraient donc aucun rapport entre elles.

Comme nous avons pu l’observer précédemment avec les histogrammes des distributions de nos variables, celles-ci ne suivent pas une loi normale. Le coeficient de corrélation de Pearson n’étant pas stable sur des données non-normales, nous lui préfererons celui de Spearman pour faire notre matrice.

# Matrice de corrélation
cor <- correlation(dfzp, method = "spearman")
cor %>%
  summary(redundant = FALSE)
# Correlation Matrix (spearman-method)

Parameter           | part_cadre_profintellec_nbemploi | part_agri_nb_emploi
----------------------------------------------------------------------------
prix_med            |                          0.55*** |            -0.59***
perc_log_vac        |                         -0.34*** |             0.44***
perc_maison         |                         -0.59*** |             0.70***
perc_tiny_log       |                          0.69*** |            -0.69***
dens_pop            |                          0.71*** |            -0.81***
med_niveau_vis      |                          0.44*** |            -0.42***
part_log_suroccup   |                          0.54*** |            -0.62***
part_agri_nb_emploi |                         -0.75*** |                    

Parameter           | part_log_suroccup | med_niveau_vis | dens_pop
-------------------------------------------------------------------
prix_med            |           0.45*** |        0.64*** |  0.61***
perc_log_vac        |          -0.21*** |       -0.56*** | -0.46***
perc_maison         |          -0.75*** |       -0.24*** | -0.53***
perc_tiny_log       |           0.80*** |        0.20*** |  0.65***
dens_pop            |           0.45*** |        0.46*** |         
med_niveau_vis      |             0.07* |                |         
part_log_suroccup   |                   |                |         
part_agri_nb_emploi |                   |                |         

Parameter           | perc_tiny_log | perc_maison | perc_log_vac
----------------------------------------------------------------
prix_med            |       0.42*** |    -0.52*** |     -0.79***
perc_log_vac        |      -0.14*** |     0.30*** |             
perc_maison         |      -0.72*** |             |             
perc_tiny_log       |               |             |             
dens_pop            |               |             |             
med_niveau_vis      |               |             |             
part_log_suroccup   |               |             |             
part_agri_nb_emploi |               |             |             

p-value adjustment method: Holm (1979)

La matrice obtenue indique que l’ensemble de nos variables sont corrélées. Nous ne sommes pas en présence d’une hétérogénéité d’informations. Nous pouvons donc rechercher une structure sous-jacente à cet ensemble de variables qui partagent une part de variance commune entre-elles et donc réaliser une analyse factorielle.

Toutefois, on observe entre certaines variables des corrélations fortes, notamment entre la part de logement sur-occupés (part_log_suroccup) et le pourcentage de maisons (perc_maison) avec un coefficient de -0.75. Ou encore entre le pourcentage de logements sur-occupés et le pourcentage de petits logements (perc_tiny_log) avec un coefficient de corrélation de 0.80. La question à se poser est de savoir s’il est absolument nécessaire de conserver toutes ces variables. Apportent-elles toutes une part d’information singulière ou est-on en présence de redondance d’information entre nos variables ? Bref leur co-présence dans notre modèle n’est-elle pas source de biais?

Pour faire ce choix il faut appliquer le principe de parcimonie. Ce principe indique qu’entre deux choix qui expliquent de manière adéquate les observations, il faut tendre vers le modèle le plus simple et le moins complexe.

Ici nous faisons le choix de conserver toutes les variables, bien que très corrélées, nous estimons qu’elles ne renvoient pas à la même information et souhaitons les conserver dans notre modèle.

Vérifions tout de même si nous ne sommes pas en présence d’une multicolinéarité. C’est-à-dire que plusieurs variables partagent une part de variance importante, ce qui peut amener à sur-représenter un phénomène et biaiser les résultats lors d’une analyse factorielle exploratoire. Afin de vérifier la multicolinéarité entre nos variables nous utiliserons le VIF Variance Inflation Factor. Cet indice est habituellement utilisé pour des modèles de régressions, toutefois Kyriazos & Poga ont démontré son utilité dans le cadre des analyses factorielles (Kyriazos & Poga, 2023).

vifstep(dfzp, method = "spearman")
No variable from the 9 input variables has collinearity problem. 

The linear correlation coefficients ranges between: 
min correlation ( part_log_suroccup ~ med_niveau_vis ):  0.07115077 
max correlation ( part_agri_nb_emploi ~ dens_pop ):  -0.8051288 

---------- VIFs of the remained variables -------- 
                         Variables      VIF
1                         prix_med 4.593899
2                     perc_log_vac 2.263956
3                      perc_maison 3.297333
4                    perc_tiny_log 6.445563
5                         dens_pop 2.089354
6                   med_niveau_vis 2.137548
7                part_log_suroccup 6.894329
8              part_agri_nb_emploi 1.813606
9 part_cadre_profintellec_nbemploi 3.115692

Bien que la fonction ne nous signale aucun problème de multicolinéarité, nous observons toutefois 2 VIF supérieurs à 5. Celui sur la variable représentant la part des logements sur-occupés et celui sur le pourcentage de petits logements. Le seuil à retenir pour considérer la présence de multicolinéarité ou non à l’aide du VIF ne fait pas l’unanimité parmi les statisticiens. Dans notre exemple, nous nous basons sur la démonstration de Farrar & Glauber qui préconise un seuil de 5 (Farrar & Glauber, 1967). Nous choisissons donc de sortir la variable renseignant la part de logements sur-occupés. Après vérification sur ce nouveau set de variable, les VIF obtenus sont tous inférieurs à 5, nous pouvons conclure en faveur d’une absence de multicolinéarité entre nos 8 variables.

dfzpp<-subset(dfzp, select = -c(part_log_suroccup))
vifstep(dfzpp, method = "spearman")
No variable from the 8 input variables has collinearity problem. 

The linear correlation coefficients ranges between: 
min correlation ( perc_tiny_log ~ perc_log_vac ):  -0.141792 
max correlation ( part_agri_nb_emploi ~ dens_pop ):  -0.8051288 

---------- VIFs of the remained variables -------- 
                         Variables      VIF
1                         prix_med 3.815959
2                     perc_log_vac 2.257504
3                      perc_maison 2.994347
4                    perc_tiny_log 3.996999
5                         dens_pop 2.024424
6                   med_niveau_vis 1.829559
7              part_agri_nb_emploi 1.760249
8 part_cadre_profintellec_nbemploi 3.115098

5.1.3 Pré-requis à la factorisation : KMO et Bartlett

Avant de factoriser nos données et de rechercher une structure sous-jacente, il est nécessaire de vérifier la présence d’un minimun de corrélation entre nos variables. Ce que nous avons fait précédemment avec la matrice de corrélation. En effet, dans le cas où les corrélations sont très faibles ou inexistantes, il sera très difficile de faire émerger un ou des facteurs. L’AFE ne sera donc probablement pas l’analyse à conseiller.

5.1.3.1 Indice Kaiser-Meyer-Olkin (KMO)

Dans le cadre d’une anlyse factorielle il faut mesurer l’adéquation de l’échantillonnage. Cette mesure donne un aperçu global de la qualité des corrélations inter-items (inter-variables). Pour ce faire on va utiliser l’indice Kaiser-Meyer-Olkin ou plus simplement appelé KMO (Kaiser, H., F., 1974). L’indice KMO varie entre 0 et 1 et donne une information complémentaire à l’examen de la matrice de corrélation. Cet indice est calculé pour l’ensemble de nos variables, mais aussi pour chaque variable. Un KMO élevé indique que les variables sont suffisamment corrélées pour justifier l’utilisation de l’AFE (ou plus largement d’une méthode d’analyse factorielle). En revanche, un KMO bas suggère que l’analyse factorielle pourrait ne pas être appropriée avec les données fournies.

L’interprétation du KMO a été décrite par Kaiser en 1974 et se décline ainsi (Kaiser, H., F., 1974) :

  • 0.90 et plus : Merveilleux
  • 0.80 et plus : Méritoire
  • 0.70 et plus : Bien
  • 0.60 et plus : Médiocre
  • 0.50 et plus : Misérable
  • Moins de 0.50 : Inacceptable

On peut tout-à-fait avoir le cas d’un KMO global élevé indiquant une bonne adéquation générale, mais un KMO d’une variable en particulier très mauvais. Dans ce cas de figure il faut examiner la variable pour essayer de comprendre pourquoi son KMO est faible. Cela peut venir de valeurs manquantes, d’une faible variance, ou encore d’une mauvaise corrélation avec les autres variables. Cette variable peut empêcher au modèle d’être mis en lumière correctement et provoquer du bruit. Il faudrait donc envisager de la retirer du modèle.

5.1.3.2 Test de Bartlett

Il faut également vérifier que notre matice de corrélation n’est pas une matrice d’identité. C’est-à-dire une matrice de corrélation où toutes nos variables sont parfaitement indépendantes, à savoir où toutes les corrélations sont égales à 0. Pour celà nous utilisons le test de sphéricité de Bartlett (Bartlett, M.S., 1937). Pour valider ce pré-requis il est nécessaire que le test soit significatif (p < 0,05) pour accepter l’idée que notre matrice de corrélation est significativement différente d’une matrice d’identité.

Pour réaliser un KMO et le test de Bartlett on peut utiliser la librairie psych avec les fonctions KMO() et cortest.bartlett(). Une alternative intéressante est la fonction check_factostructure() du package performance, cette fonction réalise les deux tests et nous indique si nos données sont appropriées pour réaliser une analyse factorielle.

#Avec psych
## KMO
KMO(dfzpp)
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = dfzpp)
Overall MSA =  0.81
MSA for each item = 
                        prix_med                     perc_log_vac 
                            0.76                             0.74 
                     perc_maison                    perc_tiny_log 
                            0.81                             0.78 
                        dens_pop                   med_niveau_vis 
                            0.88                             0.76 
             part_agri_nb_emploi part_cadre_profintellec_nbemploi 
                            0.90                             0.84 
## Test de sphéricité
cortest.bartlett(dfzpp, n=1222)
$chisq
[1] 5827.853

$p.value
[1] 0

$df
[1] 28
# Avec performance
performance::check_factorstructure(dfzpp)
# Is the data suitable for Factor Analysis?


  - Sphericity: Bartlett's test of sphericity suggests that there is sufficient significant correlation in the data for factor analysis (Chisq(28) = 5827.85, p < .001).
  - KMO: The Kaiser, Meyer, Olkin (KMO) overall measure of sampling adequacy suggests that data seems appropriate for factor analysis (KMO = 0.81). The individual KMO scores are: prix_med (0.76), perc_log_vac (0.74), perc_maison (0.81), perc_tiny_log (0.78), dens_pop (0.88), med_niveau_vis (0.76), part_agri_nb_emploi (0.90), part_cadre_profintellec_nbemploi (0.84).

Dans notre cas nous avons donc un KMO global méritoire (0.81) et des KMO par variable satisfaisants. Le test de sphéricité nous indique que notre matrice de corrélation n’est pas une matrice d’identité. Nous pouvons donc nous lancer dans l’AFE!

5.2 Combien de facteurs retenir ?

Lorsque l’on procède à une analyse factorielle il est très souvent nécessaire de définir le nombre de composantes que l’on souhaite (pour l’ACP) ou de facteurs latents (AFE) en amont. Cette décision repose sur l’étude des valeurs propres et il existe un grand nombre d’indices et de méthodes (comme par exemple le coude de Katell, la règle de Kaiser-Guttman…). Cependant, il n’existe pas de consensus sur quelle méthode choisir et laquelle serait la plus appropriée selon les cas.

Makowski en 2018, propose de se reposer sur un consensus parmi les méthodes plutôt que sur une méthode en particulier (Makowski, 2018). Il implémente sa solution dans le packge psycho puis dans la fonctionn_factors() dans le package parameters. C’est ce que nous utiliserons ici pour définir le nombre adéquat de facteurs à retenir pour notre analyse.

# Identification du nombre de facteurs
library(parameters)
n <- n_factors(dfzpp)
n
# Method Agreement Procedure:

The choice of 2 dimensions is supported by 6 (31.58%) methods out of 19 (Optimal coordinates, Parallel analysis, Kaiser criterion, Scree (SE), VSS complexity 2, Velicer's MAP).
# Plus de détail peuvent être obtenu en pasant au format data frame et en utilisant summary()

nb_factor <- as.data.frame(n)

head(nb_factor)
  n_Factors              Method              Family
1         1                   t Multiple_regression
2         1                   p Multiple_regression
3         1 Acceleration factor               Scree
4         1          Scree (R2)            Scree_SE
5         1    VSS complexity 1                 VSS
6         2 Optimal coordinates               Scree
summary(n)
  n_Factors n_Methods Variance_Cumulative
1         1         5           0.5136409
2         2         6           0.6510016
3         3         1           0.6970123
4         4         3           0.7301025
5         5         1           0.7509842
6         6         2           0.7532000
7         7         1           0.7540760
# On peut également représenter le nombre de facteurs.
library(see)
plot(n, type="line") + theme_modern()

# et visualiser le graphique des valeures propres
SCREE_PLOT(dfzpp, corkind="spearman", verbose=T)

            Eigenvalues    Proportion of Variance    Cumulative Prop. Variance
Factor 1           4.80                      0.60                         0.60
Factor 2           1.41                      0.18                         0.78
Factor 3           0.56                      0.07                         0.85
Factor 4           0.42                      0.05                         0.90
Factor 5           0.28                      0.03                         0.93
Factor 6           0.26                      0.03                         0.97
Factor 7           0.15                      0.02                         0.98
Factor 8           0.13                      0.02                         1.00

Ici les résultats bruts renvoient 2 facteurs latents. Mais 5 méthodes, ce qui est important, font également consensus autour d’un seul facteur, ce qui peut être tout à fait logique vu le petit nombre de variables que nous avons. C’est aussi une des forces de l’AFE de pouvoir faire émerger un seul facteur latent global au sein duquel se projetteraient toutes nos variables. C’est un résultat qui peut aussi être très intéressant.

Ainsi, deux possibilités s’offrent à nous chacune pertinente pour des raisons différentes, cela pose une question fondamentale : quel est le meilleur modèle ?

L’AFE va nous permettre de lancer et d’étudier les deux modèles et c’est l’analyse factorielle confirmatoire, que nous allons vous présenter par la suite, qui va nous permettre de décider quel modèle est statistiquement le plus performant. En attendant, nous pouvons lancer les deux analyses !

Pour réaliser ces analyses il va falloir déterminer la méthode de factorisation. C’est-à-dire définir sur quelle mesure on se base pour extraire les facteurs de notre set de variables. Les méthodes les plus couramment utilisées sont celles qui se basent soit sur le maximum de vraisemblance (maximum likelihood), soit sur les méthodes des moindres carrés (pondérés ou non) (weighted or unweighted least square) (Tabachnick, B. G., & Fidell, L. S., 2014). Dans notre exemple, après observation des distributions de nos données, nous avons choisi de réaliser nos analyses avec la méthode de factorisation du maximum de vraisemblance robuste (mlr). Cette méthode permet d’optimiser le calcul des distances et la version robuste est adaptée à des données non normales (Kyriazos & Poga, 2023).

5.3 Lancement des AFE

1er modèle à un 1 facteur :

# Utilisation de mlr méthode considérée comme plus robuste même pour des données non-normales

# Pour avoir mlr il faut utiliser la syntaxe ci-dessous :
# Nous n'utilisons pas de méthode de rotation car nous testons la solution à 1 seul facteur
efa1immo <- lavaan::efa(dfzpp, nfactors = 1, estimator = "MLR")

print(efa1immo)

                                     f1 
prix_med                          0.686*
perc_log_vac                     -0.447*
perc_maison                      -0.790*
perc_tiny_log                     0.843*
dens_pop                          0.703*
med_niveau_vis                    0.438*
part_agri_nb_emploi              -0.650*
part_cadre_profintellec_nbemploi  0.831*

Avec un seul facteur toutes nos variables corrèlent donc avec un facteur latent. Dans notre cas on a toute une partie qui corrèle positivement et l’autre négativement. Ainsi, le pourcentage de petit logements, la part des cadres dans l’emploi, le prix median du m², la densité de population et le niveau de vie médian corrèlent positivement et à l’inverse, le pourcentage de maison, la part d’agriculteurs dans l’emploi et le pourcentage de logements vacant corrèlent négativement. Cela laisse à penser à une dichotomie qui serait ville / campagne. Ainsi le facteur latent exprimé par nos huit variables qui caractérisent nos EPCI, serait une dimension sur le niveau d’urbanité ou de ruralité.

L’avantage de l’AFE c’est qu’une fois le facteur latent identifié, nous pouvons, pour chaque individu obtenir un score sur ce facteur latent. Dans notre exemple, vu la dimension spatiale des données il faudrait ensuite les cartographier pour visualiser spatialement l’information. L’intérêt des scores factoriels étant d’être ré-utilisés soit dans des analyses complémentaires, soit directement pour comprendre la structure de nos données. Dans notre cas, on pourrait s’en servir pour définir un score d’urbanité et de ruralité puis le représenter

# Extraction des scores factoriels par observation
factor_scores_immo<-predict(efa1immo)

# Regardons  les 5 premières lignes
head(factor_scores_immo, 5)
              f1
[1,]  1.37802423
[2,] -0.22773769
[3,]  0.07818743
[4,] -0.05003235
[5,] -0.42494739
# Extraction des charges factorielles par variable
factor_loadings_immo <- efa1immo$loadings

# Afficher les charges factorielles
print(factor_loadings_immo)
                                     f1
prix_med                          0.686
perc_log_vac                     -0.447
perc_maison                      -0.790
perc_tiny_log                     0.843
dens_pop                          0.703
med_niveau_vis                    0.438
part_agri_nb_emploi              -0.650
part_cadre_profintellec_nbemploi  0.831

Testons le modèle à deux facteurs !

# Utilisation de mlr méthode considérée comme plus robuste même pour données non-normales
# Utilisation d'une méthode de rotation promax car nous testons un modèle à2 facteurs

efa2immo <- lavaan::efa(dfzpp, nfactors = 2, estimator = "MLR", rotation = "promax")
loads2immo<-print(efa2immo)

                                     f1     f2
prix_med                          0.922       
perc_log_vac                     -0.886      .
perc_maison                           . -0.680
perc_tiny_log                         .  1.088
dens_pop                                 0.679
med_niveau_vis                    0.689       
part_agri_nb_emploi                   . -0.425
part_cadre_profintellec_nbemploi      .  0.720
loads2immo
[[1]]
                                         f1          f2
prix_med                          0.9218108  0.04752817
perc_log_vac                     -0.8864241  0.21359654
perc_maison                      -0.1861246 -0.67992319
perc_tiny_log                    -0.2061558  1.08843752
dens_pop                          0.0253656  0.67856182
med_niveau_vis                    0.6885109 -0.08577373
part_agri_nb_emploi              -0.2532162 -0.42512873
part_cadre_profintellec_nbemploi  0.1123612  0.71993957

Cette structure à deux facteurs est également très intéressante, et a permis de faire émerger en plus du facteur latent, qui serait urbanité/ruralité, un autre facteur représentant le coût de la vie. Au niveau de ce facteur on observe une corrélation positive avec le prix médian de l’immobilier au m² et le niveau de vie médian, et négative avec le pourcentage de logement vacant. Ainsi, les EPCI ayant un score élevé sur ce facteur latent seraient les EPCI où le niveau de vie médian et le prix de l’immobilier seraient le plus élevés.

Extraction des charges factorielles par variable :

factor_loadings_immo2 <- efa2immo$loadings

# Afficher les charges factorielles
print(factor_loadings_immo2)
                                     f1     f2
prix_med                          0.922  0.048
perc_log_vac                     -0.886  0.214
perc_maison                      -0.186 -0.680
perc_tiny_log                    -0.206  1.088
dens_pop                          0.025  0.679
med_niveau_vis                    0.689 -0.086
part_agri_nb_emploi              -0.253 -0.425
part_cadre_profintellec_nbemploi  0.112  0.720

Une fois de plus nous pouvons extraire les scores de ces deux facteurs latents de ce second modèle.

# Extraction des scores factoriels par observation
factor_scores_immo2<-predict(efa2immo)

# Regardons  les 5 premières lignes
head(factor_scores_immo2, 5)
             f1         f2
[1,]  1.1630309  1.7195533
[2,]  0.1358464 -0.3291296
[3,] -0.9112937  0.3642026
[4,] -0.1611307 -0.1211379
[5,] -0.3071902 -0.5258387

Il est tout à fait possible dans le cadre de l’AFE d’emprunter une représentation classique de l’ACP (le scatter plot) pour représenter nos variables et leurs charges factorielles. Cette représentation peut s’avérer également utile pour mieux comprendre nos facteurs latents.

# Graphique


# Extraire les charges factorielles
factor_loadings_immo2 <- efa2immo$loadings

# transformer les charges factorielles dans un data frame
factor_loadings_dfimmo2 <- as.data.frame(factor_loadings_immo2)

# Renommer les colonnes
colnames(factor_loadings_dfimmo2) <- c("Factor", "Loading")

#  Ajouter une variables pour identifier nos charges factorielles
factor_loadings_dfimmo2$Item <- rownames(factor_loadings_dfimmo2)

# charger ggplot2
library(ggplot2)

# Réaliser un graphique des charges factorielles
ggplot(factor_loadings_dfimmo2, aes(x = Factor, y = Loading, label = Item)) +
  geom_point() +
  geom_text(size = 3, hjust = -0.1) +
  labs(x = "Factor", y = "Loading", title = "Factor Loadings Plot") +
  theme_minimal()

6 L’Analyse factorielle confirmatoire

L’analyse factorielle confirmatoire est une technique statistique utilisée pour tester un modèle factoriel.

Si dans le cas de l’AFE les facteurs latents émergent de manière exploratoire à partir des données, dans le cadre de l’analyse factorielle confirmatoire il s’agira de tester au contraire un modèle avec des hypothèses pré-établies sur nos facteurs latents. Nous allons imposer une structure aux données et étudier dans quelle mesure les données vont correspondre à cette structure prédéfinie. Nous pourrons ainsi, utiliser la CFA, entre autres pour vérifier la stabilité d’un modèle dans le temps, vérifier des outils de mesure ou encore étudier quels modèle semble le plus pertinent.

C’est en ce sens que cette analyse est confirmatoire. Nous étudions comment un modèle pré-établi dans le cadre d’une théorie, ou suite à une première analyse statistique sur des données, est confirmée par les données observées.

LA CFA, se déroule en plusieurs étapes :

1- Définir un modèle Préalable : Spécifier un modèle factoriel a priori, indiquant la relation entre les variables observées et les facteurs latents que nous supposons. Le modèle peut également inclure des relations entre les facteurs latents.

2- Obtenir les estimations des paramètres : les différents paramètres de l’analyse factorielle confirmatoire (charges factorielles, covariances entre les facteurs latents…) sont estimés à l’aide de nos données observées. L’objectif de l’analyse étant d’obtenir des estimations qui maximisent l’ajustement entre les données observées et le modèle.

3- Lire les critères d’ajustement : La qualité et l’ajustement du modèle sont évalués en utilisant divers critères statistiques évaluant la position du modèle entre un modèle nul (sans aucun lien) et un modèle saturé (avec des liens très maximum partout). Les indices utilisés sont notamment : le chi², le RMSEA, le CFI, etc.

4- Interpréter les résultats : Les charges factorielles indiquent la force et la direction de la relation entre chaque variable observée et son facteur latent correspondant. A partir de ces indications, nous pouvons interpréter les résultats et vérifier si la structure obtenue est bien dans le même sens que celle envisagée.

5- Modifier le modèle : Si le modèle ne s’ajuste pas bien (que les indices d’ajustement ne sont pas satisfaisants), des modifications peuvent être apportées, comme la suppression ou l’ajout de liens entre les facteurs et les variables observées, pour améliorer l’ajustement. Attention toutefois à rester dans un cadre théorique cohérent et ne pas tester des liens qui n’ont pas de sens.

Tout l’enjeu en cas de non ajustement du modèle va être de comprendre et d’analyser pourquoi le modèle ne s’ajuste pas. Cela peut venir d’un modèle théorique qui n’est pas adapté aux données observées ou à des variations entre la première analyse, qui permet d’établir un premier modèle, et sa confirmation via l’analyse factorielle confirmatoire.

L’analyse factorielle confirmatoire est donc un très bon complément à l’AFE. Il est d’ailleurs très fréquent que ces deux méthodes soient utilisées ensemble. C’est même plutôt recommandé, tels que l’argumentent Flora & Flake dans un article paru en 2017 (Flora & Flake, 2017). Il est préférable de ne pas réaliser l’analyse factorielle confirmatoire sur le même jeu de données que l’AFE pour éliminer toute spécificité liée à l’échantillonnage. Néanmoins il est envisageable d’utiliser une partie des données comme échantillon d’entrainement pour identifier des facteurs latents (AFE) et l’autre partie comme échantillon test pour tester le modèle (CFA). Pour réaliser efficacement le duo AFE/AFC il est nécessaire d’avoir une base de données avec un grand nombre d’individus surtout afin de permettre la création d’un échantillon d’entrainement et de test suffisamment grand. Il est de pratique courante de diviser un échantillon en deux parties de façon aléatoire. Sur une première moitié sera alors réalisée l’AFE et sur la seconde moitié l’AFC.

6.1 Quel modèle choisir ?

6.1.1 L’analyse factorielle confirmatoire en pratique

L’analyse factorielle confirmatoire fait partie du champs des équations structurelles, sa mise en oeuvre se fait très bien sur R. L’avantage des équations structurelles c’est qu’à la manière de l’ACP nous pourrons représenter graphiquement les modèles obtenus.

1- Etape 1 : partitionnement des données :

## En premier lien le partitionnement des data
partitions <- datawizard::data_partition(dfzpp, proportion = 0.5) # ici division du corpus eavec 50% des individus dasn l'échantillon d'entrainement
training <- partitions$p_0.5
test <- partitions$test

training$.row_id <- NULL
test$.row_id <- NULL

2- Etape 2 : Réalisation des AFE sur la partition d’entrainement

# modèle à 1 facteur
efa1immo_F1 <- lavaan::efa(training, nfactors = 1, estimator = "MLR")


# modèle à 2 facteurs
efa2immo_F2 <- lavaan::efa(training, nfactors = 2, estimator = "MLR", rotation = "promax")

3- Etape 3 : Réaliser une analyse factorielle confirmatoire

library(lavaan)

attach(test) # nécessaire à cause du package lavaan

# modèle à 1 facteur
model1F<- 'F1 =~ prix_med + perc_log_vac + perc_maison + perc_tiny_log + dens_pop + med_niveau_vis + part_agri_nb_emploi + part_cadre_profintellec_nbemploi'

fact_1immo <- cfa(model1F, std.lv=T, estimator="MLR", data=test)

# modèle à 2 facteurs
model2F<- 'F1 =~ prix_med + perc_log_vac + med_niveau_vis
           F2 =~ perc_maison + perc_tiny_log + dens_pop + part_agri_nb_emploi + part_cadre_profintellec_nbemploi'
fact_2immo <- cfa(model2F, std.lv=T, estimator="MLR", data=test)

Etape 3 : étudier la convergence de nos deux modèles

Attention les sorties d’un modèle d’analyse factorielle confirmatoire sont nombreuses, nous les détaillons ici pour en avoir une première lecture mais leurs analyses se feront véritablement à l’aide d’autres fonctions. Il faut retenir que deux grandes étapes seront à évaluer : l’adéquation de nos données au modèle proposé (avec la vérification des indices d’ajustement au modèle) - on parle de modèle de mesure - et si le modèle s’ajuste correctement nous pourrons alors étudier la structure de celui-ci par la force et le signe des saturations obtenues - on parle alors de modèle de structure.

res_fact1immo <- summary(fact_1immo, standardized=T, modindices = T, fit.measures=T, rsquare=T)

# Pour voir les différents éléments qui composent notre summary de notre modèle
summary(res_fact1immo)
       Length Class             Mode   
header  5     -none-            list   
optim   9     -none-            list   
data    2     -none-            list   
test    2     -none-            list   
fit    49     lavaan.vector     numeric
pe     10     data.frame        list   
mi      8     lavaan.data.frame list   
resfact2immo <- summary(fact_2immo, standardized=T, modindices = T, fit.measures=T, rsquare=T)
  • header : contient des éléments contextuels sur notre fonction (version du package…) ainsi que les mesures d’ajustement si fitMeasures=TRUE
  • optim : liste d’information concernant l’optimisation du modèle
  • data : des éléments sur nos données
  • test : les résultats des différents tests
  • fit : Résultats des différents test d’ajustement du modèle
  • pe : les différents paramètres des relations au sein du modèle sous la forme d’un data frame des facteurs latent et de la variance
  • mi: si modindices=TRUE, il s’agit des suggestions proposées par la fonction pour améliorer notre modèle.
ATTENTION cette option (modindices=TRUE)est à utiliser avec grandes précautions. L’idée ici est bien de tester un modèle théorique pré-établi et donc chaque modifications proposées qui seraient ajoutées au modèle final doit pouvoir se justifier théoriquement. La corrélation de l’ensemble des erreurs de mesure ensemble, comme c’est souvent proposé par cette option, est difficile à justifier dans un modèle théorique pré-établi.

Voici donc la sortie brute de summary, on retrouve également les R2

#exemple pour le modèle à 1 facteur
res_fact1immo
lavaan 0.6-19 ended normally after 22 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        16

  Number of observations                           611

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               833.595     493.336
  Degrees of freedom                                20          20
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.690
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              2969.556    1383.130
  Degrees of freedom                                28          28
  P-value                                        0.000       0.000
  Scaling correction factor                                  2.147

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.723       0.651
  Tucker-Lewis Index (TLI)                       0.613       0.511
                                                                  
  Robust Comparative Fit Index (CFI)                         0.725
  Robust Tucker-Lewis Index (TLI)                            0.615

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -5780.141   -5780.141
  Scaling correction factor                                  4.097
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -5363.343   -5363.343
  Scaling correction factor                                  2.759
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                               11592.281   11592.281
  Bayesian (BIC)                             11662.923   11662.923
  Sample-size adjusted Bayesian (SABIC)      11612.126   11612.126

Root Mean Square Error of Approximation:

  RMSEA                                          0.258       0.197
  90 Percent confidence interval - lower         0.243       0.185
  90 Percent confidence interval - upper         0.273       0.208
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    1.000       1.000
                                                                  
  Robust RMSEA                                               0.256
  90 Percent confidence interval - lower                     0.237
  90 Percent confidence interval - upper                     0.276
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         1.000

Standardized Root Mean Square Residual:

  SRMR                                           0.118       0.118

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  F1 =~                                                                 
    prix_med          0.653    0.048   13.614    0.000    0.653    0.666
    perc_log_vac     -0.441    0.042  -10.506    0.000   -0.441   -0.425
    perc_maison      -0.839    0.039  -21.447    0.000   -0.839   -0.809
    perc_tiny_log     0.898    0.059   15.153    0.000    0.898    0.872
    dens_pop          0.577    0.073    7.923    0.000    0.577    0.716
    med_niveau_vis    0.372    0.053    7.076    0.000    0.372    0.383
    part_gr_nb_mpl   -0.638    0.031  -20.491    0.000   -0.638   -0.648
    prt_cdr_prfnt_    0.871    0.064   13.651    0.000    0.871    0.842

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .prix_med          0.535    0.072    7.423    0.000    0.535    0.556
   .perc_log_vac      0.882    0.058   15.166    0.000    0.882    0.820
   .perc_maison       0.371    0.045    8.225    0.000    0.371    0.345
   .perc_tiny_log     0.253    0.032    7.805    0.000    0.253    0.239
   .dens_pop          0.317    0.090    3.513    0.000    0.317    0.487
   .med_niveau_vis    0.807    0.104    7.792    0.000    0.807    0.854
   .part_gr_nb_mpl    0.562    0.064    8.718    0.000    0.562    0.580
   .prt_cdr_prfnt_    0.312    0.052    6.024    0.000    0.312    0.291
    F1                1.000                               1.000    1.000

R-Square:
                   Estimate
    prix_med          0.444
    perc_log_vac      0.180
    perc_maison       0.655
    perc_tiny_log     0.761
    dens_pop          0.513
    med_niveau_vis    0.146
    part_gr_nb_mpl    0.420
    prt_cdr_prfnt_    0.709

Modification Indices:

                   lhs op                              rhs      mi    epc
1             prix_med ~~                     perc_log_vac 271.463 -0.483
2             prix_med ~~                      perc_maison  24.625 -0.107
3             prix_med ~~                    perc_tiny_log  99.278 -0.198
4             prix_med ~~                         dens_pop   9.076 -0.056
5             prix_med ~~                   med_niveau_vis 160.976  0.355
6             prix_med ~~              part_agri_nb_emploi   3.637 -0.046
7             prix_med ~~ part_cadre_profintellec_nbemploi   7.630 -0.057
8         perc_log_vac ~~                      perc_maison   0.951  0.025
9         perc_log_vac ~~                    perc_tiny_log 125.527  0.264
10        perc_log_vac ~~                         dens_pop   1.729  0.030
11        perc_log_vac ~~                   med_niveau_vis  68.790 -0.289
12        perc_log_vac ~~              part_agri_nb_emploi  11.514  0.102
13        perc_log_vac ~~ part_cadre_profintellec_nbemploi   7.956  0.070
14         perc_maison ~~                    perc_tiny_log  47.971 -0.137
15         perc_maison ~~                         dens_pop   7.386  0.046
16         perc_maison ~~                   med_niveau_vis  14.314  0.094
17         perc_maison ~~              part_agri_nb_emploi   2.300  0.033
18         perc_maison ~~ part_cadre_profintellec_nbemploi  74.779  0.173
19       perc_tiny_log ~~                         dens_pop  35.827  0.095
20       perc_tiny_log ~~                   med_niveau_vis  73.982 -0.193
21       perc_tiny_log ~~              part_agri_nb_emploi   9.047  0.061
22       perc_tiny_log ~~ part_cadre_profintellec_nbemploi  36.278  0.119
23            dens_pop ~~                   med_niveau_vis  14.500 -0.083
24            dens_pop ~~              part_agri_nb_emploi  23.309  0.091
25            dens_pop ~~ part_cadre_profintellec_nbemploi   8.466  0.048
26      med_niveau_vis ~~              part_agri_nb_emploi   3.766 -0.055
27      med_niveau_vis ~~ part_cadre_profintellec_nbemploi  12.146  0.082
28 part_agri_nb_emploi ~~ part_cadre_profintellec_nbemploi   5.358 -0.048
   sepc.lv sepc.all sepc.nox
1   -0.483   -0.703   -0.703
2   -0.107   -0.239   -0.239
3   -0.198   -0.538   -0.538
4   -0.056   -0.136   -0.136
5    0.355    0.540    0.540
6   -0.046   -0.084   -0.084
7   -0.057   -0.139   -0.139
8    0.025    0.044    0.044
9    0.264    0.559    0.559
10   0.030    0.057    0.057
11  -0.289   -0.342   -0.342
12   0.102    0.144    0.144
13   0.070    0.133    0.133
14  -0.137   -0.448   -0.448
15   0.046    0.135    0.135
16   0.094    0.172    0.172
17   0.033    0.073    0.073
18   0.173    0.508    0.508
19   0.095    0.336    0.336
20  -0.193   -0.426   -0.426
21   0.061    0.161    0.161
22   0.119    0.426    0.426
23  -0.083   -0.164   -0.164
24   0.091    0.217    0.217
25   0.048    0.152    0.152
26  -0.055   -0.082   -0.082
27   0.082    0.164    0.164
28  -0.048   -0.116   -0.116

On peut également obtenir les saturations standardisées pour les deux modèles, ce qui sera intéressant dans une perspective de compréhension de la structure de la CFA, mais aussi de réutilisation dans des analyses complémentaires (régressions…).

## Saturations standardisées
resid(fact_1immo,type="standardized")
$type
[1] "standardized"

$cov
                                  prx_md  prc_l_  prc_ms  prc_t_  dns_pp
prix_med                           0.000                                
perc_log_vac                      -9.951   0.000                        
perc_maison                       -1.753   0.670   0.000                
perc_tiny_log                    -13.872  15.959  -3.507   0.000        
dens_pop                          -3.004   1.678   2.739   3.093   0.000
med_niveau_vis                     7.942  -8.427   3.176  -9.462  -3.329
part_agri_nb_emploi               -1.977   3.133   1.520   3.639   4.473
part_cadre_profintellec_nbemploi  -2.577   3.099   8.938   2.531   1.438
                                  md_nv_ prt_g__ prt_c__
prix_med                                                
perc_log_vac                                            
perc_maison                                             
perc_tiny_log                                           
dens_pop                                                
med_niveau_vis                     0.000                
part_agri_nb_emploi               -2.208   0.000        
part_cadre_profintellec_nbemploi   2.186  -1.997   0.000
resid(fact_2immo,type="standardized")
$type
[1] "standardized"

$cov
                                 prx_md prc_l_ md_nv_ prc_ms prc_t_ dns_pp
prix_med                          0.000                                   
perc_log_vac                     -0.027  0.000                            
med_niveau_vis                    0.398 -3.108  0.000                     
perc_maison                      -2.292  1.286  0.595  0.000              
perc_tiny_log                    -8.149  6.064 -2.174 -2.160  0.000       
dens_pop                         -1.093  0.421 -1.174  3.789  1.987  0.000
part_agri_nb_emploi              -4.066  3.874 -3.616  2.091  4.526  3.932
part_cadre_profintellec_nbemploi  0.660  0.599  2.824  9.581  1.228  1.319
                                 prt_g__ prt_c__
prix_med                                        
perc_log_vac                                    
med_niveau_vis                                  
perc_maison                                     
perc_tiny_log                                   
dens_pop                                        
part_agri_nb_emploi                0.000        
part_cadre_profintellec_nbemploi  -2.713   0.000

Etape 4 : Représenter les deux modèles :

Voici donc la représentation des équations structurelles, représentations qui obéit à un certain nombre de codes visuels : les rectangles renvoient aux variables observées, les ellipses aux variables latentes, les doubles flèches associées aux rectangles et aux ellipses à l’erreur de chaque variable. Les couleurs vertes et rouges renvoient au signe de la corrélation et l’épaisseur à la force de la corrélation entre les variables et les facteurs.

semPlot::semPaths(fact_1immo, "std",
             sizeMan = 8, sizeInt = 8, sizeLat = 8,
             edge.label.cex=0.8,
             fade=FALSE)

semPlot::semPaths(fact_2immo, "std",
             sizeMan = 8, sizeInt = 8, sizeLat = 8,
             edge.label.cex=0.8,
             fade=FALSE)

Etape 5 : Comparer nos deux modèles

Tout notre enjeu ici va être de comparer les deux modèles et de choisir celui qui s’ajuste le mieux à nos données. Pour ce faire nous pouvons comparer les deux modèles sur différents indices.

# Pour comparer les modèles à l'aide des indices tel que l'AIC, le RMSEA, R2...
performance::compare_performance(fact_1immo, fact_2immo, verbose = FALSE)
# Comparison of Model Performance Indices

Name       |  Model |    Chi2 | Chi2_df | p (Chi2) | Baseline(28)
-----------------------------------------------------------------
fact_1immo | lavaan | 833.595 |  20.000 |   < .001 |     2969.556
fact_2immo | lavaan | 309.177 |  19.000 |   < .001 |     2969.556

Name       | p (Baseline) |   GFI |  AGFI |   NFI |  NNFI |   CFI | RMSEA
-------------------------------------------------------------------------
fact_1immo |       < .001 | 0.741 | 0.534 | 0.719 | 0.613 | 0.723 | 0.258
fact_2immo |       < .001 | 0.891 | 0.793 | 0.896 | 0.855 | 0.901 | 0.158

Name       |    RMSEA  CI | p (RMSEA) |   RMR |  SRMR |   RFI |  PNFI |   IFI
-----------------------------------------------------------------------------
fact_1immo | [0.24, 0.27] |    < .001 | 0.117 | 0.118 | 0.607 | 0.514 | 0.724
fact_2immo | [0.14, 0.17] |    < .001 | 0.060 | 0.060 | 0.847 | 0.608 | 0.902

Name       |   RNI | Loglikelihood |   AIC (weights) |   BIC (weights) | BIC_adjusted
-------------------------------------------------------------------------------------
fact_1immo | 0.723 |     -5780.141 | 11592.3 (<.001) | 11662.9 (<.001) |    11612.126
fact_2immo | 0.901 |     -5517.932 | 11069.9 (>.999) | 11144.9 (>.999) |    11090.949
# Une autre manière de visualiser très utile.
effectsize::interpret(fact_1immo)
    Name     Value Threshold Interpretation
1    GFI 0.7408374      0.95           poor
2   AGFI 0.5335073      0.90           poor
3    NFI 0.7192862      0.90           poor
4   NNFI 0.6127786      0.90           poor
5    CFI 0.7234133      0.90           poor
6  RMSEA 0.2580290      0.05           poor
7   SRMR 0.1175162      0.08           poor
8    RFI 0.6070007      0.90           poor
9   PNFI 0.5137759      0.50   satisfactory
10   IFI 0.7241635      0.90           poor
effectsize::interpret(fact_2immo)
    Name      Value Threshold Interpretation
1    GFI 0.89053008      0.95           poor
2   AGFI 0.79258331      0.90           poor
3    NFI 0.89588430      0.90           poor
4   NNFI 0.85462461      0.90           poor
5    CFI 0.90135242      0.90   satisfactory
6  RMSEA 0.15810090      0.05           poor
7   SRMR 0.05999792      0.08   satisfactory
8    RFI 0.84656634      0.90           poor
9   PNFI 0.60792149      0.50   satisfactory
10   IFI 0.90165332      0.90   satisfactory

Dans les deux configurations testées, l’analyse factorielle confirmatoire présente un ajustement des modèles aux jeux de données “test” plutôt mauvais. Pour le deuxième modèle toutefois, 2 indices sont considérés comme satisfaisants et 3 indices ont des valeurs très proches des seuils (NFI : 0.8669; CFI : 0.8720 ; IFI : 0.8724). Ces indices indiquent l’écart entre un modèle nul (rien n’est lié) et un modèle saturé (tout est lié avec des coefficients à 1). Le fait que ces indices aient des valeurs de 0.86 ou 0.87 et non de 0.90 n’est pas particulièrement problématique.

Concrètement, le deuxième modèle testé, avec 2 facteurs latents permettrait de mieux rendre compte de la complexité de nos données. Celui-ci s’ajustant le mieux à nos données.

Le package Lavaan, fait également quelques propositions pour améliorer notre modèle. Théoriquement, en tenant compte de toutes ces propositions, le modèle s’ajusterait parfaitement, mais on serait dans un cas évident de sur-ajustement aux données. En revanche, cela peut être intéressant d’en prendre connaissance afin de vérifier qu’aucune relation n’ait été oubliée et qui permettrait d’améliorer significativement le modèle. Cette relation doit bien évidemment faire sens théoriquement. La syntaxe utilisée est celle du package lavaan, on peut en trouver une traduction ici

modindices(fact_1immo) %>% arrange(-mi) %>% head(20)
              lhs op                              rhs      mi    epc sepc.lv
1        prix_med ~~                     perc_log_vac 271.463 -0.483  -0.483
2        prix_med ~~                   med_niveau_vis 160.976  0.355   0.355
3    perc_log_vac ~~                    perc_tiny_log 125.527  0.264   0.264
4        prix_med ~~                    perc_tiny_log  99.278 -0.198  -0.198
5     perc_maison ~~ part_cadre_profintellec_nbemploi  74.779  0.173   0.173
6   perc_tiny_log ~~                   med_niveau_vis  73.982 -0.193  -0.193
7    perc_log_vac ~~                   med_niveau_vis  68.790 -0.289  -0.289
8     perc_maison ~~                    perc_tiny_log  47.971 -0.137  -0.137
9   perc_tiny_log ~~ part_cadre_profintellec_nbemploi  36.278  0.119   0.119
10  perc_tiny_log ~~                         dens_pop  35.827  0.095   0.095
11       prix_med ~~                      perc_maison  24.625 -0.107  -0.107
12       dens_pop ~~              part_agri_nb_emploi  23.309  0.091   0.091
13       dens_pop ~~                   med_niveau_vis  14.500 -0.083  -0.083
14    perc_maison ~~                   med_niveau_vis  14.314  0.094   0.094
15 med_niveau_vis ~~ part_cadre_profintellec_nbemploi  12.146  0.082   0.082
16   perc_log_vac ~~              part_agri_nb_emploi  11.514  0.102   0.102
17       prix_med ~~                         dens_pop   9.076 -0.056  -0.056
18  perc_tiny_log ~~              part_agri_nb_emploi   9.047  0.061   0.061
19       dens_pop ~~ part_cadre_profintellec_nbemploi   8.466  0.048   0.048
20   perc_log_vac ~~ part_cadre_profintellec_nbemploi   7.956  0.070   0.070
   sepc.all sepc.nox
1    -0.703   -0.703
2     0.540    0.540
3     0.559    0.559
4    -0.538   -0.538
5     0.508    0.508
6    -0.426   -0.426
7    -0.342   -0.342
8    -0.448   -0.448
9     0.426    0.426
10    0.336    0.336
11   -0.239   -0.239
12    0.217    0.217
13   -0.164   -0.164
14    0.172    0.172
15    0.164    0.164
16    0.144    0.144
17   -0.136   -0.136
18    0.161    0.161
19    0.152    0.152
20    0.133    0.133
modindices(fact_2immo) %>% arrange(-mi) %>% head(20)
                   lhs op                              rhs     mi    epc
1                   F1 =~                      perc_maison 65.495 -0.257
2          perc_maison ~~ part_cadre_profintellec_nbemploi 61.894  0.157
3                   F1 =~                    perc_tiny_log 60.582 -0.219
4             prix_med ~~                      perc_maison 59.199 -0.113
5       med_niveau_vis ~~ part_cadre_profintellec_nbemploi 51.113  0.144
6       med_niveau_vis ~~                      perc_maison 25.875  0.107
7         perc_log_vac ~~                    perc_tiny_log 24.245  0.081
8        perc_tiny_log ~~              part_agri_nb_emploi 18.107  0.083
9             dens_pop ~~              part_agri_nb_emploi 17.246  0.079
10        perc_log_vac ~~              part_agri_nb_emploi 15.706  0.092
11 part_agri_nb_emploi ~~ part_cadre_profintellec_nbemploi 14.611 -0.081
12         perc_maison ~~                    perc_tiny_log 12.631 -0.072
13         perc_maison ~~                         dens_pop 11.571  0.056
14       perc_tiny_log ~~                         dens_pop 11.001  0.051
15        perc_log_vac ~~                   med_niveau_vis 10.517 -0.101
16                  F2 =~                         prix_med 10.517 -0.243
17                  F1 =~              part_agri_nb_emploi 10.476 -0.120
18            prix_med ~~ part_cadre_profintellec_nbemploi  8.787 -0.042
19            prix_med ~~                   med_niveau_vis  7.248 -0.124
20                  F2 =~                     perc_log_vac  7.248 -0.136
   sepc.lv sepc.all sepc.nox
1   -0.257   -0.248   -0.248
2    0.157    0.454    0.454
3   -0.219   -0.213   -0.213
4   -0.113   -0.566   -0.566
5    0.144    0.312    0.312
6    0.107    0.218    0.218
7    0.081    0.248    0.248
8    0.083    0.255    0.255
9    0.079    0.185    0.185
10   0.092    0.156    0.156
11  -0.081   -0.185   -0.185
12  -0.072   -0.281   -0.281
13   0.056    0.168    0.168
14   0.051    0.218    0.218
15  -0.101   -0.162   -0.162
16  -0.243   -0.248   -0.248
17  -0.120   -0.122   -0.122
18  -0.042   -0.224   -0.224
19  -0.124   -0.465   -0.465
20  -0.136   -0.131   -0.131

Conclusion

Nous avons ainsi présenté pas à pas un exemple d’utilisation de l’AFE et en suivant de la CFA. L’idée était de présenter une méthode ancienne mais peu utilisée en dehors de la Psychologie. Il ne s’agit pas de remplacer l’ACP mais de proposer une alternative, et surtout de proposer aux usagers de faire un choix conscient sur la méthode plutôt que de répondre à une habitude disciplinaire.

Ainsi, si vous souhaitez explorer vos données et identifier des facteurs latents corrélés (ou non) afin de faire émerger une structure synthétique, voir si la structure observée est cohérente avec un modèle théorique, ou encore si cette structure observée est stable dans le temps ou au contraire évolue, alors l’utilisation du couple entre AFE/CFA est tout-à-fait pertinente.

Bibliographie

  • Aguinis, H., Gottfredson, R. K., & Joo, H. (2013). Best-Practice Recommendations for Defining, Identifying, and Handling Outliers. Organizational Research Methods, 16(2), 270-301. https://doi.org/10.1177/1094428112470848

  • Bakker, M., & Wicherts, J. M. (2014). Outlier removal, sum scores, and the inflation of the type I error rate in independent samples t tests: The power of alternatives and recommendations. Psychological Methods, 19(3), 409–427. https://doi.org/10.1037/met0000014

  • Bartlett, M.S. (1937) Properties of Sufficiency and Statistical Test. Proceedings of the Royal Society A, 160, 268-282. https://doi.org/10.1098/rspa.1937.0109

  • Benzecri J.-P. (1973), L’analyse des données, Paris, Dunod, vol. 2 : Correspondances

  • Farrar, D. E., & Glauber, R. R. (1967). Multicollinearity in Regression Analysis: The Problem Revisited. The Review of Economics and Statistics, 49(1), 92–107. https://doi.org/10.2307/1937887.

  • Flora, D. B., & Flake, J. K. (2017), The purpose and practice of exploratory and confirmatory factor analysis in psychological research: Decisions for scale development and validation. Canadian Journal of Behavioural Science / Revue canadienne des sciences du comportement, 49(2), 78–88. https://doi.org/10.1037/cbs0000069

  • Hooper, D., Coughlan, J., & Mullen, M. R. (2008), Structural Equation Modelling: Guidelines for Determining Model Fit. The Electronic Journal of Business Research Methods, 6, 53-60.

  • Kaiser, H.F. (1974) An index of factorial simplicity. Psychometrika 39, 31–36. https://doi.org/10.1007/BF02291575

  • Kyriazos, T. and Poga, M. (2023) Dealing with Multicollinearity in Factor Analysis: The Problem, Detections, and Solutions. Open Journal of Statistics, 13, 404-424. doi: 10.4236/ojs.2023.133020

  • Kyriazos, T. and Poga-Kyriazou, M. (2023) Applied Psychometrics: Estimator Considerations in Commonly Encountered Conditions in CFA, SEM, and EFA Practice. Psychology, 14, 799-828. doi: https://doi.org/10.4236/psych.2023.145043

  • Leys, C., Klein, O., Dominicy, Y., and Ley., C., 2018, “Detecting Multivariate Outliers: Use a Robust Variant of the Mahalanobis Distance.” Journal of Experimental Social Psychology 74: 150–56. https://doi.org/10.1016/j.jesp.2017.09.011

  • Leys, C., et al. (2019). How to Classify, Detect, and Manage Univariate and Multivariate Outliers, With Emphasis on Pre-Registration. International Review of Social Psychology, 32(1): 5, 1–10. DOI: https://doi.org/10.5334/irsp.289

  • Makowski, (2018). The psycho Package: an Efficient and Publishing-Oriented Workflow for Psychological Science. Journal of Open Source Software, 3(22), 470. https://doi.org/10.21105/joss.00470

  • Pages, J-P., et al., (1979), Analyse factorielle : Un peu d’histoire et de géométrie, Revue de statistiques appliquée, tome 27, n°1, p.5-28.

  • Pearson F.R.S., K. (1901) LIII. On lines and planes of closest fit to systems of points in space, The London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science, 2:11, 559-572, DOI: 10.1080/14786440109462720

  • Schreiber, J.B., (2021), Issues and recommendations for exploratory factor analysis and principal component analysis, Research in Social and Administrative Pharmacy, Volume 17, Issue 5, 2021, Pages 1004-1011, ISSN 1551-7411, https://doi.org/10.1016/j.sapharm.2020.07.027.

  • Spearman, C. (1904). The Proof and Measurement of Association between Two Things. The American Journal of Psychology, 15(1), 72–101. https://doi.org/10.2307/1412159

  • Tabachnick, B., & Fidell, L., (2014), Using Multivariate Statistics (6th ed.). Harlow: Pearson Education

  • Tobacyk, J., & Milford, G. (1983). Belief in paranormal phenomena: Assessment instrument development and implications for personality functioning. Journal of personality and social psychology, 44(5), 1029.

  • Tobacyk, J. J., Nagot, E., & Miller, M. (1988). Paranormal Beliefs and Locus of Control: A Multidimensional Examination. Journal of Personality Assessment, 52(2), 241–246. https://doi.org/10.1207/s15327752jpa5202_5

  • Tobacyk, J. J. (2004). A revised paranormal belief scale. International Journal of Transpersonal Studies, 23(1), 94–98.. International Journal of Transpersonal Studies, 23 (1). http://dx.doi.org/10.24972/ijts.2004.23.1.94

  • Van Laar, S., & Braeken, J., 2021, Understanding the Comparative Fit Index : It’s All About Base !, Practical Assessment, Reasearch & Evaluation, Vol 26, N°26

  • Watkins, M. W. (2018). Exploratory Factor Analysis: A Guide to Best Practice. Journal of Black Psychology, 44(3), 219-246. https://doi.org/10.1177/0095798418771807

  • Yong, A. G., & Pearce, S. (2013) A Beginner’s Guide to Factor Analysis: Focusing on Exploratory Factor Analysis, Tutorials in Quantitative Methods for Psychology, 9(2), 79-94. doi: 10.20982/tqmp.09.2.p079

  • Zijlstra, W. P., van der Ark, L. A., & Sijtsma, K. (2011). Outliers in Questionnaire Data: Can They Be Detected and Should They Be Removed? Journal of Educational and Behavioral Statistics, 36(2), 186–212. http://www.jstor.org/stable/29789477

Annexes

Info session

setting value
version R version 4.4.2 (2024-10-31 ucrt)
os Windows 11 x64 (build 22631)
system x86_64, mingw32
ui RTerm
language (EN)
collate French_France.utf8
ctype French_France.utf8
tz Europe/Paris
date 2024-12-19
pandoc 3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
package ondiskversion source
correlation 0.8.5 CRAN (R 4.4.1)
corrplot 0.94 CRAN (R 4.4.1)
dplyr 1.1.4 CRAN (R 4.4.1)
EFA.dimensions 0.1.8.4 CRAN (R 4.4.2)
effectsize 1.0.0 CRAN (R 4.4.2)
ggplot2 3.5.1 CRAN (R 4.4.1)
ggraph 2.2.1 CRAN (R 4.4.2)
here 1.0.1 CRAN (R 4.4.1)
lattice 0.22.6 CRAN (R 4.4.2)
lavaan 0.6.19 CRAN (R 4.4.2)
nFactors 2.4.1.1 CRAN (R 4.4.2)
pacman 0.5.1 CRAN (R 4.4.2)
parameters 0.24.0 CRAN (R 4.4.2)
psych 2.4.6.26 CRAN (R 4.4.2)
RColorBrewer 1.1.3 CRAN (R 4.4.0)
see 0.9.0 CRAN (R 4.4.2)
table1 1.4.3 CRAN (R 4.4.2)
terra 1.8.5 CRAN (R 4.4.2)
usdm 2.1.7 CRAN (R 4.4.2)

Citation

Auteur.e P, Auteur.e S (2021). “Titre de la fiche.” doi:10.48645/xxxxxx, https://doi.org/10.48645/xxxxxx,, https://rzine.fr/publication_rzine/xxxxxxx/.

BibTex :

@Misc{,
  title = {Titre de la fiche},
  subtitle = {Sous-Titre de la fiche},
  author = {Premier Auteur.e and Second Auteur.e},
  doi = {10.48645/xxxxxx},
  url = {https://rzine.fr/publication_rzine/xxxxxxx/},
  keywords = {FOS: Other social sciences},
  language = {fr},
  publisher = {FR2007 CIST},
  year = {2021},
  copyright = {Creative Commons Attribution Share Alike 4.0 International},
}


Glossaire