Cours
L’analyse factorielle (AF) est une méthode d’exploration des données qui vise à identifier des facteurs sous-jacents influents, ou variables latentes, à partir d’un ensemble de variables observées. Elle facilite l’interprétation en réduisant le nombre de variables. Elle extrait la variance commune maximale de l’ensemble des variables et la résume dans un score commun.
L’analyse factorielle est largement utilisée en études de marché, publicité, psychologie, finance et recherche opérationnelle. Les chargés d’études s’en servent pour repérer les clients sensibles au prix, identifier les attributs de marque qui influencent le choix des consommateurs et mieux comprendre les critères de sélection des canaux de distribution.
Analyse factorielle
L’analyse factorielle est un modèle statistique linéaire. Elle sert à expliquer la variance entre des variables observées et à condenser un ensemble de variables observées en variables non observées appelées facteurs. Les variables observées sont modélisées comme une combinaison linéaire de facteurs et de termes d’erreur (Source). Un facteur, ou variable latente, est associé à plusieurs variables observées qui partagent des schémas de réponses communs. Chaque facteur explique une part de la variance des variables observées. Il facilite l’interprétation des données en réduisant le nombre de variables.
L’analyse factorielle cherche à déterminer si un ensemble de variables d’intérêt X1, X2, …, Xl, est linéairement lié à un plus petit nombre de facteurs non observables F1, F2, …, Fk.
Source : cette image est recréée d’après des notes d’analyse factorielle. Elle offre une vue d’ensemble du processus.
Hypothèses :
- Pas de valeurs aberrantes dans les données.
- La taille d’échantillon doit être supérieure au nombre de facteurs.
- Pas de multicolinéarité parfaite.
- Pas d’homoscédasticité entre les variables.
Types d’analyse factorielle
- Analyse factorielle exploratoire (AFE) : c’est l’approche la plus courante en sciences sociales et en management. L’hypothèse de base est que toute variable observée peut être directement associée à n’importe quel facteur.
- Analyse factorielle confirmatoire (AFC) : elle suppose que chaque facteur est associé à un ensemble précis de variables observées. L’AFC vient confirmer une structure attendue.
Comment fonctionne l’analyse factorielle ?
L’objectif principal est de réduire le nombre de variables observées et d’identifier des variables non observées. Ces variables latentes aident l’analyste à tirer des conclusions à partir d’une enquête. La transformation des variables observées en variables latentes se déroule en deux étapes :
- Extraction des facteurs : on choisit le nombre de facteurs et la méthode d’extraction via des approches de partition de variance comme l’analyse en composantes principales et l’analyse des facteurs communs.
- Rotation des facteurs : la rotation vise à rendre les facteurs non corrélés — l’objectif est d’améliorer l’interprétabilité globale. Plusieurs méthodes existent : Varimax, Quartimax, Promax, entre autres.
Terminologie
Qu’est-ce qu’un facteur ?
Un facteur est une variable latente qui décrit l’association entre plusieurs variables observées. Le nombre maximal de facteurs est égal au nombre de variables observées. Chaque facteur explique une part de la variance des variables observées. Les facteurs expliquant le moins de variance sont écartés. Les facteurs sont aussi appelés variables latentes, cachées, non observées ou hypothétiques.
Qu’est-ce que les charges factorielles ?
La matrice des charges factorielles montre la relation de chaque variable avec le facteur sous-jacent. Elle indique le coefficient de corrélation entre la variable observée et le facteur, et la part de variance expliquée par les variables observées.
Qu’est-ce que les valeurs propres (eigenvalues) ?
Les valeurs propres représentent la part de variance expliquée par chaque facteur sur la variance totale. On parle aussi de racines caractéristiques.
Qu’est-ce que les communalités ?
Les communalités sont la somme des carrés des charges pour chaque variable. Elles représentent la variance commune. Elles varient de 0 à 1, une valeur proche de 1 indiquant une plus grande variance expliquée.
Qu’est-ce que la rotation factorielle ?
La rotation est un outil pour améliorer l’interprétation. Elle peut être orthogonale ou oblique. Elle redistribue les communalités en clarifiant le motif des charges.
Choisir le nombre de facteurs
Le critère de Kaiser est une approche analytique : on retient les facteurs qui expliquent une proportion plus importante de variance. L’usage des valeurs propres est courant pour déterminer le nombre de facteurs ; en général, une valeur propre supérieure à 1 constitue un bon seuil de sélection.
L’approche graphique repose sur la représentation des valeurs propres des facteurs, appelée scree plot (test de Cattell). Le « coude » de la courbe aide à choisir le nombre de facteurs.
Analyse factorielle vs analyse en composantes principales
- Les composantes de l’ACP expliquent un maximum de variance, tandis que l’analyse factorielle explique la covariance des données.
- Les composantes de l’ACP sont parfaitement orthogonales entre elles, alors que l’analyse factorielle n’impose pas l’orthogonalité des facteurs.
- En ACP, une composante est une combinaison linéaire des variables observées, alors qu’en AF, les variables observées sont des combinaisons linéaires des variables latentes (facteurs).
- Les composantes ACP sont souvent difficilement interprétables. En AF, les facteurs sous-jacents sont nommables et interprétables.
- L’ACP est une méthode de réduction de dimension, tandis que l’AF est une approche par variables latentes.
- L’ACP est parfois considérée comme un cas particulier d’analyse factorielle. L’ACP est observationnelle, alors que l’AF est une technique de modélisation.
Analyse factorielle en Python avec le package factor_analyzer
Importer les bibliothèques nécessaires
# Import required libraries
import pandas as pd
from sklearn.datasets import load_iris
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt
Chargement des données
Réalisons une analyse factorielle sur BFI (jeu de données issu d’un projet d’évaluation de la personnalité), collecté avec une échelle de réponse à 6 niveaux : 1 Very Inaccurate, 2 Moderately Inaccurate, 3 Slightly Inaccurate, 4 Slightly Accurate, 5 Moderately Accurate et 6 Very Accurate. Vous pouvez aussi télécharger ce jeu de données via le lien suivant : https://vincentarelbundock.github.io/Rdatasets/datasets.html
df= pd.read_csv("bfi.csv")
Prétraiter les données
df.columns
Index(['A1', 'A2', 'A3', 'A4', 'A5', 'C1', 'C2', 'C3', 'C4', 'C5', 'E1', 'E2',
'E3', 'E4', 'E5', 'N1', 'N2', 'N3', 'N4', 'N5', 'O1', 'O2', 'O3', 'O4',
'O5', 'gender', 'education', 'age'],
dtype='object')
# Dropping unnecessary columns
df.drop(['gender', 'education', 'age'],axis=1,inplace=True)
# Dropping missing values rows
df.dropna(inplace=True)
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2436 entries, 0 to 2799
Data columns (total 25 columns):
A1 2436 non-null float64
A2 2436 non-null float64
A3 2436 non-null float64
A4 2436 non-null float64
A5 2436 non-null float64
C1 2436 non-null float64
C2 2436 non-null float64
C3 2436 non-null float64
C4 2436 non-null float64
C5 2436 non-null float64
E1 2436 non-null float64
E2 2436 non-null float64
E3 2436 non-null float64
E4 2436 non-null float64
E5 2436 non-null float64
N1 2436 non-null float64
N2 2436 non-null float64
N3 2436 non-null float64
N4 2436 non-null float64
N5 2436 non-null float64
O1 2436 non-null float64
O2 2436 non-null int64
O3 2436 non-null float64
O4 2436 non-null float64
O5 2436 non-null float64
dtypes: float64(24), int64(1)
memory usage: 494.8 KB
df.head()
| A1 | A2 | A3 | A4 | A5 | C1 | C2 | C3 | C4 | C5 | ... | N1 | N2 | N3 | N4 | N5 | O1 | O2 | O3 | O4 | O5 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2.0 | 4.0 | 3.0 | 4.0 | 4.0 | 2.0 | 3.0 | 3.0 | 4.0 | 4.0 | ... | 3.0 | 4.0 | 2.0 | 2.0 | 3.0 | 3.0 | 6 | 3.0 | 4.0 | 3.0 |
| 1 | 2.0 | 4.0 | 5.0 | 2.0 | 5.0 | 5.0 | 4.0 | 4.0 | 3.0 | 4.0 | ... | 3.0 | 3.0 | 3.0 | 5.0 | 5.0 | 4.0 | 2 | 4.0 | 3.0 | 3.0 |
| 2 | 5.0 | 4.0 | 5.0 | 4.0 | 4.0 | 4.0 | 5.0 | 4.0 | 2.0 | 5.0 | ... | 4.0 | 5.0 | 4.0 | 2.0 | 3.0 | 4.0 | 2 | 5.0 | 5.0 | 2.0 |
| 3 | 4.0 | 4.0 | 6.0 | 5.0 | 5.0 | 4.0 | 4.0 | 3.0 | 5.0 | 5.0 | ... | 2.0 | 5.0 | 2.0 | 4.0 | 1.0 | 3.0 | 3 | 4.0 | 3.0 | 5.0 |
| 4 | 2.0 | 3.0 | 3.0 | 4.0 | 5.0 | 4.0 | 4.0 | 5.0 | 3.0 | 2.0 | ... | 2.0 | 3.0 | 4.0 | 4.0 | 3.0 | 3.0 | 3 | 4.0 | 3.0 | 3.0 |
5 lignes × 25 colonnes
Test d’adéquation
Avant de mener une analyse factorielle, il faut évaluer la « factorabilité » du jeu de données, c’est-à-dire : peut-on y déceler des facteurs ? Deux méthodes permettent de vérifier la factorabilité ou l’adéquation de l’échantillonnage :
- Test de Bartlett
- Test de Kaiser-Meyer-Olkin
Le test de sphéricité de Bartlett examine si les variables observées sont inter-corrélées en comparant la matrice des corrélations observées à la matrice identité. Si le test n’est pas statistiquement significatif, vous ne devriez pas recourir à l’analyse factorielle.
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
chi_square_value,p_value=calculate_bartlett_sphericity(df)
chi_square_value, p_value
(18146.065577234807, 0.0)
Dans ce test de Bartlett, la p-valeur est de 0. Le test est statistiquement significatif, indiquant que la matrice de corrélation observée n’est pas une matrice identité.
Le test de Kaiser-Meyer-Olkin (KMO) mesure la pertinence des données pour l’analyse factorielle. Il évalue l’adéquation pour chaque variable et pour le modèle global. Le KMO estime la proportion de variance commune entre toutes les variables observées. Une proportion plus élevée est plus favorable à l’analyse factorielle. Les valeurs de KMO vont de 0 à 1 ; une valeur inférieure à 0,6 est jugée insuffisante.
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model=calculate_kmo(df)
kmo_model
0.8486452309468382
Le KMO global de nos données est de 0,84 : excellent. Vous pouvez donc poursuivre l’analyse factorielle prévue.
Choisir le nombre de facteurs
Pour déterminer le nombre de facteurs, utilisez le critère de Kaiser et le scree plot. Les deux reposent sur les valeurs propres.
# Create factor analysis object and perform factor analysis
fa = FactorAnalyzer()
fa.analyze(df, 25, rotation=None)
# Check Eigenvalues
ev, v = fa.get_eigenvalues()
ev
| Original_Eigenvalues | |
|---|---|
| 0 | 5.134311 |
| 1 | 2.751887 |
| 2 | 2.142702 |
| 3 | 1.852328 |
| 4 | 1.548163 |
| 5 | 1.073582 |
| 6 | 0.839539 |
| 7 | 0.799206 |
| 8 | 0.718989 |
| 9 | 0.688089 |
| 10 | 0.676373 |
| 11 | 0.651800 |
| 12 | 0.623253 |
| 13 | 0.596563 |
| 14 | 0.563091 |
| 15 | 0.543305 |
| 16 | 0.514518 |
| 17 | 0.494503 |
| 18 | 0.482640 |
| 19 | 0.448921 |
| 20 | 0.423366 |
| 21 | 0.400671 |
| 22 | 0.387804 |
| 23 | 0.381857 |
| 24 | 0.262539 |
Ici, seules les 6 premières valeurs propres sont supérieures à 1. Nous retiendrons donc 6 facteurs (variables latentes).
# Create scree plot using matplotlib
plt.scatter(range(1,df.shape[1]+1),ev)
plt.plot(range(1,df.shape[1]+1),ev)
plt.title('Scree Plot')
plt.xlabel('Factors')
plt.ylabel('Eigenvalue')
plt.grid()
plt.show()
Le scree plot trace la série des valeurs propres par facteur. Le nombre de valeurs propres supérieures à 1 correspond au nombre de facteurs à retenir.
Ici, seules les 6 premières valeurs propres dépassent 1 ; nous choisissons donc 6 facteurs (variables latentes).
Réaliser l’analyse factorielle
# Create factor analysis object and perform factor analysis
fa = FactorAnalyzer()
fa.analyze(df, 6, rotation="varimax")
fa.loadings
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | Factor6 | |
|---|---|---|---|---|---|---|
| A1 | 0.040783 | 0.095220 | 0.048734 | -0.113057 | -0.530987 | 0.161216 |
| A2 | 0.235538 | 0.033131 | 0.133714 | 0.063734 | 0.661141 | -0.006244 |
| A3 | 0.343008 | -0.009621 | 0.121353 | 0.033990 | 0.605933 | 0.160106 |
| A4 | 0.219717 | -0.081518 | 0.235140 | -0.125338 | 0.404594 | 0.086356 |
| A5 | 0.414458 | -0.149616 | 0.106382 | 0.030977 | 0.469698 | 0.236519 |
| C1 | 0.077248 | -0.004358 | 0.554582 | 0.190124 | 0.007511 | 0.095035 |
| C2 | 0.038370 | 0.068330 | 0.674545 | 0.087593 | 0.057055 | 0.152775 |
| C3 | 0.031867 | -0.039994 | 0.551164 | -0.011338 | 0.101282 | 0.008996 |
| C4 | -0.066241 | 0.216283 | -0.638475 | -0.143846 | -0.102617 | 0.318359 |
| C5 | -0.180812 | 0.284187 | -0.544838 | 0.025837 | -0.059955 | 0.132423 |
| E1 | -0.590451 | 0.022280 | 0.053915 | -0.071205 | -0.130851 | 0.156583 |
| E2 | -0.684578 | 0.233624 | -0.088497 | -0.045561 | -0.116716 | 0.115065 |
| E3 | 0.556774 | -0.000895 | 0.103390 | 0.241180 | 0.179396 | 0.267291 |
| E4 | 0.658395 | -0.136788 | 0.113798 | -0.107808 | 0.241143 | 0.158513 |
| E5 | 0.507535 | 0.034490 | 0.309813 | 0.200821 | 0.078804 | 0.008747 |
| N1 | 0.068011 | 0.805806 | -0.051264 | -0.074977 | -0.174849 | -0.096266 |
| N2 | 0.022958 | 0.789832 | -0.037477 | 0.006726 | -0.141134 | -0.139823 |
| N3 | -0.065687 | 0.725081 | -0.059039 | -0.010664 | -0.019184 | 0.062495 |
| N4 | -0.345072 | 0.578319 | -0.162174 | 0.062916 | 0.000403 | 0.147551 |
| N5 | -0.161675 | 0.523097 | -0.025305 | -0.161892 | 0.090125 | 0.120049 |
| O1 | 0.225339 | -0.020004 | 0.133201 | 0.479477 | 0.005178 | 0.218690 |
| O2 | -0.001982 | 0.156230 | -0.086047 | -0.496640 | 0.043989 | 0.134693 |
| O3 | 0.325954 | 0.011851 | 0.093880 | 0.566128 | 0.076642 | 0.210777 |
| O4 | -0.177746 | 0.207281 | -0.005671 | 0.349227 | 0.133656 | 0.178068 |
| O5 | -0.014221 | 0.063234 | -0.047059 | -0.576743 | -0.057561 | 0.135936 |
- Le facteur 1 présente de fortes charges pour E1, E2, E3, E4 et E5 (Extraversion)
- Le facteur 2 présente de fortes charges pour N1, N2, N3, N4 et N5 (Névrosisme)
- Le facteur 3 présente de fortes charges pour C1, C2, C3, C4 et C5 (Conscience/propreté)
- Le facteur 4 présente de fortes charges pour O1, O2, O3, O4 et O5 (Ouverture)
- Le facteur 5 présente de fortes charges pour A1, A2, A3, A4 et A5 (Agréabilité)
- Le facteur 6 n’affiche pas de fortes charges pour une variable en particulier et reste difficile à interpréter. Mieux vaut donc retenir cinq facteurs.
Réalisons l’analyse factorielle avec 5 facteurs.
# Create factor analysis object and perform factor analysis using 5 factors
fa = FactorAnalyzer()
fa.analyze(df, 5, rotation="varimax")
fa.loadings
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | |
|---|---|---|---|---|---|
| A1 | 0.040465 | 0.111126 | 0.022798 | -0.077931 | -0.428166 |
| A2 | 0.213716 | 0.029588 | 0.139037 | 0.062139 | 0.626946 |
| A3 | 0.317848 | 0.009357 | 0.109331 | 0.056196 | 0.650743 |
| A4 | 0.204566 | -0.066476 | 0.230584 | -0.112700 | 0.435624 |
| A5 | 0.393034 | -0.122113 | 0.087869 | 0.066708 | 0.537087 |
| C1 | 0.070184 | 0.010416 | 0.545824 | 0.209584 | 0.038878 |
| C2 | 0.033270 | 0.089574 | 0.648731 | 0.115434 | 0.102782 |
| C3 | 0.023907 | -0.030855 | 0.557036 | -0.005183 | 0.111578 |
| C4 | -0.064984 | 0.240410 | -0.633806 | -0.107535 | -0.037498 |
| C5 | -0.176395 | 0.290318 | -0.562467 | 0.036822 | -0.047525 |
| E1 | -0.574835 | 0.042819 | 0.033144 | -0.058795 | -0.104813 |
| E2 | -0.678731 | 0.244743 | -0.102483 | -0.042010 | -0.112517 |
| E3 | 0.536816 | 0.024180 | 0.083010 | 0.280877 | 0.257906 |
| E4 | 0.646833 | -0.115614 | 0.102023 | -0.073422 | 0.306101 |
| E5 | 0.504069 | 0.036145 | 0.312899 | 0.213739 | 0.090354 |
| N1 | 0.078923 | 0.786807 | -0.045997 | -0.084704 | -0.216363 |
| N2 | 0.027301 | 0.754109 | -0.030568 | -0.010304 | -0.193744 |
| N3 | -0.061430 | 0.731721 | -0.067084 | -0.004217 | -0.027712 |
| N4 | -0.345388 | 0.590602 | -0.178902 | 0.075225 | 0.005886 |
| N5 | -0.161291 | 0.537858 | -0.037309 | -0.149769 | 0.100931 |
| O1 | 0.213005 | -0.002224 | 0.115080 | 0.504907 | 0.061550 |
| O2 | 0.004560 | 0.175788 | -0.099729 | -0.468925 | 0.081809 |
| O3 | 0.310956 | 0.026736 | 0.076873 | 0.596007 | 0.126889 |
| O4 | -0.191196 | 0.220582 | -0.021906 | 0.369012 | 0.155475 |
| O5 | -0.005347 | 0.085401 | -0.062730 | -0.533778 | -0.010384 |
# Get variance of each factors
fa.get_factor_variance()
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | |
|---|---|---|---|---|---|
| SS Loadings | 2.473090 | 2.709633 | 2.041106 | 1.522153 | 1.844498 |
| Proportion Var | 0.098924 | 0.108385 | 0.081644 | 0.060886 | 0.073780 |
| Cumulative Var | 0.098924 | 0.207309 | 0.288953 | 0.349839 | 0.423619 |
Au total, 42 % de la variance cumulée est expliquée par les 5 facteurs.
Avantages et limites de l’analyse factorielle
L’analyse factorielle explore de grands jeux de données et met en évidence des relations interdépendantes. Elle réduit les variables observées en quelques variables latentes ou identifie des groupes de variables corrélées, ce qui aide les équipes marketing à simplifier des situations de marché complexes et à révéler des liens cachés entre goûts, préférences et influences culturelles. Elle contribue aussi à améliorer les questionnaires pour de futures enquêtes. Les facteurs facilitent une interprétation plus naturelle des données.
Les résultats peuvent toutefois prêter à discussion. Les interprétations peuvent diverger, car plusieurs lectures d’un même ensemble de facteurs sont possibles. Après l’identification et la nomination des facteurs, une expertise métier est nécessaire.
Conclusion
Félicitations, vous êtes arrivé au bout de ce tutoriel !
Vous avez découvert ce qu’est l’analyse factorielle, ses différents types, son fonctionnement, les notions de base, comment choisir le nombre de facteurs, la comparaison entre l’analyse en composantes principales et l’analyse factorielle, son implémentation en Python avec le package FactorAnalyzer, ainsi que ses avantages et limites.
Vos retours et questions sont les bienvenus. Laissez un commentaire : je ferai de mon mieux pour vous répondre.
Pour aller plus loin avec les facteurs en Python, suivez le cours Unsupervised Learning in Python de DataCamp.