Analyse Factorielle Multiple avec R

Objectif général de cette présentation

Analyser le jeu de données “interest” du package {profileR} à l’aide de l’analyse factorielle multiple (AFM, anglais : MFA) grâce aux packages {FactoMineR} et {factoextra}.

Ce jeu de données a été conçu à des fins pédagogiques et peut être téléchargé ici : http://psych.colorado.edu/~carey/Courses/PSYC7291/ClassDataSets.htm

  • différences entres l’AFM et d’autres approches similaire (ACP et ACM)
  • applications
  • démo “éclair” de l’ACP et l’ACM => visualisation
  • AFM étape par étape

En partant d’une analyse générale vers une analyse détaillée des diagnostiques, nous alternerons analyse avec RStudio, interprétation des graphiques et des diagnostiques en passant par un retour aux données brutes.

Connaissances préalables (kit de survie)

Niveau 1 :

  • Connaître les pourcentages
  • Les angles obtus, droits, aigüs
  • Savoir retrouver les coordonnées d’un point dans un graphique avec des abscisses et des ordonnées

Niveau 2 :

  • Savoir lire une p-valeur
  • Les tests de corrélation
  • Les tests de Chi2

Définition brève des ACP, ACM et de l’AFM

“Couteau suisse” pour analyser les jeux de données complexes => résumer la complexité en grandes oppositions entre individus => réduction de dimension. Analyses exploratoires et descriptives.

Simplifie des corrélations complexes entre variables sous la forme d’axes qui résument les oppositions entre individus. Ces axes sont appelés dimensions ou composantes principales ou facteurs.

Ces oppositions peuvent émerger sous la forme d’une variable :

QUALI : caractéristiques d’un lieu de vacances choisi par des géographes et des historiens. Relief intéressant <=> Temps agréablement chaud <=> historiquement intéressant.

QUANTI : la quantité d’aide accordée par l’Etat pour isoler sa résidence principale. 0 euros <=> 37 …..<=> 600 euros.

Un axe peut résumer un groupe de variables. Cette variation est ensuite écartée pour laisser la place aux différences plus subtiles entre individus exprimées dans l’axe 2 etc jusqu’à ce que toutes les différences soient exprimées. Par défaut, FactoMineR s’arrête à 5 axes.

Visualisations multiples accompagnées de tableaux de diagnostiques détaillés.

#La méthode choisie dépend de la nature des données :

  • AFM : analyse factorielle multiple (num. et/ou quali. + familles de variables => “groupes”)
  • ACP : analyse en composante principale (num. au moins 3 variables distinctes)
  • ACM : analyse des correspondances multiples (quali. au moins 3 variables distinctes)
  • AFDM : analyse factorielle de données mixtes (quali et quanti, pas de familles de variables).

Attention au rapport entre le nombre d’observations et nombre de variables. ex : 32 indiv. vs. 566 variables => bloque ex : 44 indiv. vs. 566 variables => OK

ex : si on a 1 variable voire 2 => bloque

NB : demander à François Husson pour plus de précisions via le groupe google (?) FactoMineR users google group : https://groups.google.com/g/factominer-users?pli=1

Avec ces méthodes on peut :

  • Caractériser la variation d’un jeu de données.
  • Vérifier la présence ou non de corrélations entre les variables.
  • Détecter les variables qui caractérisent au mieux la variation.
  • Evaluer les ressemblances et écarts entre les individus.
  • Classer ces individus en groupes (ajout d’une classification).

Application de l’AFM et de ses dérivés

Sensorimétrie

  • Evaluations de jus d’orange ou de vins par des testeurs et la composition chimique du brevage, l’image de la marque, packaging…

Evaluation

  • Evaluation de francophones en anglais sur l’intonation, les consonnes, voyelles.
  • Evaluation d’individus en fonction de leur résultat au bac, du lycée, du revenu des parents, du recours à des cours particuliers etc…
  • Performance de sportifs, conditions d’entraînement, environement pendant une compétition, matériel utilisé, moral…

Profilage de clients

  • Tests de personalité selon des critères muliples et habitudes d’achat

Textométrie

  • Analyses d’articles de presse selon divers critères, catégories sémantiques, type de lectorat, réception de l’article, richesse du vocabulaire, tournures grammaticales…

Linguistique anglaise

Sociologie

Histoire sociale

Avantages de ces méthodes statistiques

  • Contrairement aux régressions, l’ACP, l’ACM et l’AFM ne requièrent pas de relation entre une variable dépendante et des variables indépendantes.
  • Ces méthodes acceptent plus de 500 variables sans occulter la variation individuelle. Elles redonnent aux individus toute leur importance. “Benzecri a rendu les individus à la statistique (…) sous la forme de points dans un nuage”. https://issuu.com/sfleury/docs/st-1994-lebart_salem
  • Ces méthodes minorent l’effet du bruit dans la variation (réduction de dimensionalité). Bruit : schémas de variation jugés mineurs.
  • Elles sont compatibles avec diverses formes de classification. La réduction de bruit des ACP/ACM/AFM donne souvent des classifications plus robustes.
  • Aident à sélectionner des individus globalement médians (représentatifs d’un échantillon), des individus globalement très atypiques.

Quelques inconvénients surmontables

  • Les grandes tendances qui se dégagent donnent l’impression d’enfoncer des portes ouvertes pour quelqu’un qui connaît bien son domaine mais cela peut rassurer et indiquer que l’on est sur la bonne voie.
  • Les diagnostiques détaillés font peur au début mais c’est là que l’on peut vraiment interroger ses données sous toutes ses coutures.
  • Le nuage d’individus peut paraître touffu à analyser or les filtres visuels et l’utilisation de la classification orientent le chercheur dans son analyse.

Quelque soit l’approche statistique, plus les données sont complexes, plus il faut du temps pour en saisir la complexité. Ces approches fournissent une très bonne aide avec plusieurs outils en un (individus => clusters => grandes tendances).

Premier apperçu visuel de ces méthodes : pour gens pressés

Exemple de données pour l’ACP

library(knitr) # pour générer la table ci-dessous
library(profileR) # pour extraire les données IPMMc
library(dplyr) # to use recode_factor function

# Renommer les noms des variables pour plus de clarté
names(IPMMc) <- c("Anxiete","Hypochondrie","Schizophrenie", "Bipolaire", "Pole_nevrose")

# Renommer les modalités de la variable Pole_nevrose
IPMMc$Pole_nevrose <- recode_factor(IPMMc$Pole_nevrose, "1"= "Nevrose","0"= "Psychose")

# Imprimer le tableau modifié
kable(IPMMc, caption ="Jeu de données Personalité et Humeur QUANTI", row.names = T)
Jeu de données Personalité et Humeur QUANTI
Anxiete Hypochondrie Schizophrenie Bipolaire Pole_nevrose
1 75 60 50 50 Nevrose
2 60 75 45 55 Nevrose
3 60 60 55 45 Nevrose
4 50 50 75 60 Psychose
5 45 55 60 75 Psychose
6 55 45 60 60 Psychose

Analyse “éclair” en ACP et classification

library(FactoMineR)
# graphe 1 : nom => carte factorielle / graphe des individus,
# graphe 2 : nom => cercle des corrélations / graphe des variables
res.pca <- PCA(IPMMc, quali.sup = 5)

plot(res.pca, choix="var")

# graph 3 : nom => biplot (TOUT EN UN) => individus, var. quali (rose) et var. quanti (bleu) + coloration des individus selon une caractéristique donnée (ici : type de patient atteint de névrose vs. pyschose)
library(factoextra)
fviz_pca_biplot(res.pca, repel = TRUE,
                col.var = "#2E9FDF", # Variables color
                col.ind = "#696969",  # Individuals color
                habillage = "Pole_nevrose")

Classification post ACP

# classification
hc.pca <- HCPC(res.pca, nb.clust=3) #Si nb.clust = -1 : laisser le programme décider du nombre optimal de clusters.

# Dendrogramme
plot(hc.pca, choice="tree")

# Dendrogramme + carte factorielle
# Aide ? Taper "plot.MFA"
# help(plot.MFA)
plot(hc.pca, choice="map", draw.tree = F)

plot(hc.pca, choice="map", draw.tree = F, legend = list(bty = "y", x = "top"))

Analyse “éclair” en ACM et classification

Cours Husson : https://www.youtube.com/watch?v=bihScz3OXbw Tuto Husson : https://www.youtube.com/watch?v=mUKz4L2ZsuY

Préparation des données

IPMMc2 <- IPMMc
IPMMc2$Anxiete <- if_else(IPMMc2$Anxiete > 55,"A1","A0")
IPMMc2$Hypochondrie <- if_else(IPMMc2$Hypochondrie  > 55,"H1","H0")
IPMMc2$Schizophrenie <- if_else(IPMMc2$Schizophrenie > 55,"S1","S0")
IPMMc2$Bipolaire <- if_else(IPMMc2$Bipolaire > 55,"B1","B0")
IPMMc2$Film <- c("F_Med","F_Psy","F_Med", "F_Hor","F_Med","F_Vio")
kable(IPMMc2, caption ="Jeu de données Personalité et Humeur QUALI", row.names = T)
Jeu de données Personalité et Humeur QUALI
Anxiete Hypochondrie Schizophrenie Bipolaire Pole_nevrose Film
1 A1 H1 S0 B0 Nevrose F_Med
2 A1 H1 S0 B0 Nevrose F_Psy
3 A1 H1 S0 B0 Nevrose F_Med
4 A0 H0 S1 B1 Psychose F_Hor
5 A0 H0 S1 B1 Psychose F_Med
6 A0 H0 S1 B1 Psychose F_Vio

ACM

res.mca <- MCA(IPMMc2, quali.sup=5, graph=F)
plot(res.mca,habillage="quali", cex=1, xlim=c(-2,2), repel=T, invisible="quali.sup") # couleur (= habillage) par variable quali

#plot(res.mca, choix="ind", invisible=c("var", "quali.sup")) # ind. uniquement
#plot(res.mca,invisible=c("quali.sup","ind"),hab="quali") # var. uniquement

Classification post ACM

hc.mca <- HCPC(res.mca, nb.clust=-1) #Si nb.clust = -1 : laisser le programme décider du nombre optimal de clusters.

AFM étape par étape

1 Préparation de ses données

Préparer un tableau au format large. Un individu (point de mesure) par ligne et tous les critères d’évaluation en colonne. Pour l’AFM, agencer ses colonnes par groupe de variable.

Info sur les données interest

Jeu de données créé à des fins pédagogiques.

250 individus ont passé des tests de langage, de calcul et d’analyse logique etc. (scores centrés réduits ?). Les individus ont aussi indiqué leurs traits de caractère : gestion du stress, anxiété, impulsivité ou sociabilité…(scores centrés réduits ?). L’âge, le sexe et le nombre d’années de scolarisation depuis le primaire est renseigné.

15 variables retenues et 7 groupes de variables. 128 Femmes, 122 Hommes.

library(knitr)
library(profileR)
kable(interest[1:5,1:7], caption ="Jeu de données interest")
Jeu de données interest
gender educ age vocab reading sentcomp mathmtcs
2 18 47 1.67 1.67 1.46 0.90
1 12 39 -1.19 -1.43 -1.19 -0.17
2 12 50 1.56 1.11 2.25 1.40
2 12 41 -0.59 -0.03 0.12 0.05
1 14 33 0.15 0.98 -0.05 0.20
kable(interest[1:5,8:15], caption ="Jeu de données interest")
Jeu de données interest
geometry analyrea socdom sociabty stress worry impulsve thrillsk
0.49 1.65 0.48 1.11 0.23 -1.82 -0.78 -1.87
0.28 0.23 -1.62 -1.15 0.37 -0.23 0.29 0.77
1.85 2.04 1.00 0.90 0.73 1.64 -0.82 0.65
-0.48 -0.17 0.71 0.87 -0.43 -0.88 -0.06 -0.30
-0.68 0.58 -1.17 -0.79 -0.94 -0.38 0.12 -0.36

Groupe de variable 1 : métadonnées (sexe, QUALI)

Groupe de variable 2 : métadonnées (années d’étude, l’âge, QUANTI)

Groupe de variable 3 : tests linguistiques (vocab, lecture, compléter des phrases, QUANTI)

Groupe de variable 4 : tests math_log (math, géométie, logique, QUANTI)

Groupe de variable 5 : sociabilité (dominance sociale, sociabilité, QUANTI)

Groupe de variable 6 : stress (réaction au stress, taux d’anxiété, QUANTI)

Groupe de variable 7 : impulsivité (impulsivité, goût du risque, QUANTI)

https://cran.r-project.org/web/packages/profileR/profileR.pdf

Info sur la variable educ: nombre d’années de scolarisation (système américain) Min : 8 => brevet. Moyenne : => 12 jusqu’à la première/bac. Max : 18 => master.

2 Préparation dans R

Installer les packages FactoMineR, factoextra & profileR

#install.packages(c("FactoMineR", "factoextra","profileR"))

library(profileR)
data("interest")
interest$gender<- as.factor(interest$gender)
# Renommer le genre pour plus de clarté
levels(interest$gender) <- c("F","H")
summary(interest[1:15]) # ne garder que les 15 variables du début (plus pertinentes ici)
##  gender       educ           age            vocab             reading       
##  F:128   Min.   : 8.0   Min.   :11.00   Min.   :-2.62000   Min.   :-2.4700  
##  H:122   1st Qu.:12.0   1st Qu.:33.00   1st Qu.:-0.60500   1st Qu.:-0.5175  
##          Median :12.0   Median :40.00   Median : 0.04000   Median : 0.1850  
##          Mean   :12.3   Mean   :39.55   Mean   : 0.09016   Mean   : 0.1350  
##          3rd Qu.:12.0   3rd Qu.:46.00   3rd Qu.: 0.86000   3rd Qu.: 0.7975  
##          Max.   :18.0   Max.   :65.00   Max.   : 2.63000   Max.   : 2.7000  
##     sentcomp           mathmtcs          geometry          analyrea      
##  Min.   :-2.47000   Min.   :-3.7100   Min.   :-3.3200   Min.   :-2.8300  
##  1st Qu.:-0.55000   1st Qu.:-0.4925   1st Qu.:-0.5600   1st Qu.:-0.4825  
##  Median : 0.10500   Median : 0.1000   Median : 0.0900   Median : 0.2000  
##  Mean   : 0.07356   Mean   : 0.1055   Mean   : 0.1125   Mean   : 0.1750  
##  3rd Qu.: 0.77500   3rd Qu.: 0.9200   3rd Qu.: 0.7675   3rd Qu.: 0.8375  
##  Max.   : 2.73000   Max.   : 3.0600   Max.   : 3.8600   Max.   : 3.5000  
##      socdom           sociabty            stress             worry         
##  Min.   :-2.7200   Min.   :-3.09000   Min.   :-2.56000   Min.   :-3.07000  
##  1st Qu.:-0.5550   1st Qu.:-0.70750   1st Qu.:-0.61250   1st Qu.:-0.72750  
##  Median : 0.0700   Median : 0.03500   Median : 0.00500   Median :-0.03000  
##  Mean   : 0.1012   Mean   : 0.05968   Mean   :-0.01696   Mean   : 0.00224  
##  3rd Qu.: 0.7400   3rd Qu.: 0.69750   3rd Qu.: 0.61000   3rd Qu.: 0.74000  
##  Max.   : 2.9000   Max.   : 2.76000   Max.   : 2.78000   Max.   : 2.42000  
##     impulsve           thrillsk      
##  Min.   :-3.04000   Min.   :-2.9600  
##  1st Qu.:-0.65750   1st Qu.:-0.5575  
##  Median : 0.12500   Median : 0.1500  
##  Mean   : 0.05248   Mean   : 0.1410  
##  3rd Qu.: 0.71000   3rd Qu.: 0.7950  
##  Max.   : 2.62000   Max.   : 3.0000

3 Executer une AFM

library(FactoMineR)
res <- MFA(interest[1:15], group=c(1,2,3,3,2,2,2), 
           # *group* : indiquer le nombre de colonnes à inclure dans le groupe. 
           # Partir de la gauche. Group 1 : 1 var, group 2 : 2 var, group 4 : 3 var.
           type=c("n","s","s","s","s","s","s"), 
           #n: les variables du groupe sont nominatives, 
           #s: les variables sont centrées réduites, 
           #c: les variables sont centrées. 
           #Valeure par défaut: s.
           name.group=c("sexe","educ_age","ling",
                        "math_log","soc","stress","impuls"),
           # donner un nom à chaque groupe.
           num.group.sup=c(1,2), graph = F)

# Indiquer les groupes qui ne font pas partie de l'analyse et qui sont supplémentaires : groupe 1 et 2 concernent les métadonnées. On veut classifier les individus uniquement par le biais des résultats aux tests scolaires et de personalité.

Cours Husson sur les variables supplémentaires : https://youtu.be/8qw0bNfK4H0?t=2039

4 Diagnostiques de base de l’AFM

NB : utiliser la fonction summary() pour obtenir les diagnostiques les plus importants. Tuto Husson : https://youtu.be/miCPrUe7Yq8?t=252

# Sortir les diagnostiques les plus importants :
summary(res)
## 
## Call:
## MFA(base = interest[1:15], group = c(1, 2, 3, 3, 2, 2, 2), type = c("n",  
##      "s", "s", "s", "s", "s", "s"), name.group = c("sexe", "educ_age",  
##      "ling", "math_log", "soc", "stress", "impuls"), num.group.sup = c(1,  
##      2), graph = F) 
## 
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6   Dim.7
## Variance               1.814   1.139   0.951   0.868   0.373   0.322   0.261
## % of var.             28.769  18.069  15.075  13.761   5.911   5.104   4.141
## Cumulative % of var.  28.769  46.838  61.913  75.674  81.585  86.689  90.830
##                        Dim.8   Dim.9  Dim.10  Dim.11  Dim.12
## Variance               0.241   0.124   0.093   0.065   0.056
## % of var.              3.829   1.960   1.467   1.027   0.888
## Cumulative % of var.  94.658  96.618  98.085  99.112 100.000
## 
## Groups
##             Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr   cos2  
## ling     |  0.852 46.986  0.715 |  0.001  0.124  0.000 |  0.013  1.360  0.000 |
## math_log |  0.825 45.472  0.669 |  0.002  0.218  0.000 |  0.011  1.182  0.000 |
## soc      |  0.055  3.045  0.003 |  0.219 19.231  0.045 |  0.666 70.047  0.415 |
## stress   |  0.002  0.101  0.000 |  0.481 42.227  0.205 |  0.252 26.504  0.056 |
## impuls   |  0.080  4.396  0.006 |  0.435 38.200  0.171 |  0.009  0.906  0.000 |
## 
## Supplementary groups
##            Dim.1  cos2   Dim.2  cos2   Dim.3  cos2  
## sexe     | 0.000 0.000 | 0.000 0.000 | 0.025 0.001 |
## educ_age | 0.263 0.045 | 0.045 0.001 | 0.018 0.000 |
## 
## Individuals (the 10 first)
##             Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr   cos2  
## 1        |  2.156  1.025  0.476 |  0.036  0.000  0.000 |  0.012  0.000  0.000 |
## 2        | -1.410  0.438  0.362 | -0.468  0.077  0.040 | -1.176  0.582  0.252 |
## 3        |  2.532  1.413  0.646 | -0.563  0.111  0.032 |  1.183  0.589  0.141 |
## 4        | -0.232  0.012  0.030 |  0.640  0.144  0.230 |  0.324  0.044  0.059 |
## 5        | -0.022  0.000  0.000 | -0.144  0.007  0.007 | -1.422  0.851  0.683 |
## 6        |  0.651  0.093  0.063 |  1.899  1.265  0.537 | -0.289  0.035  0.012 |
## 7        |  0.161  0.006  0.007 |  0.771  0.208  0.168 |  0.191  0.015  0.010 |
## 8        |  0.452  0.045  0.082 |  0.589  0.122  0.140 | -0.505  0.107  0.102 |
## 9        | -1.922  0.814  0.814 |  0.524  0.096  0.060 |  0.063  0.002  0.001 |
## 10       | -0.072  0.001  0.003 | -0.168  0.010  0.017 |  0.035  0.001  0.001 |
## 
## Continuous variables (the 10 first)
##             Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr   cos2  
## vocab    |  0.888 16.963  0.788 |  0.047  0.074  0.002 | -0.083  0.286  0.007 |
## reading  |  0.838 15.115  0.702 | -0.035  0.042  0.001 | -0.134  0.734  0.018 |
## sentcomp |  0.832 14.909  0.693 |  0.016  0.009  0.000 | -0.091  0.340  0.008 |
## mathmtcs |  0.862 16.153  0.744 |  0.011  0.004  0.000 | -0.156  1.003  0.024 |
## geometry |  0.804 14.022  0.646 |  0.005  0.001  0.000 |  0.001  0.000  0.000 |
## analyrea |  0.839 15.296  0.704 |  0.079  0.213  0.006 | -0.066  0.179  0.004 |
## socdom   |  0.196  1.332  0.038 |  0.378  7.914  0.143 |  0.757 38.039  0.573 |
## sociabty |  0.222  1.714  0.049 |  0.452 11.317  0.204 |  0.694 32.008  0.482 |
## stress   | -0.051  0.098  0.003 | -0.577 19.878  0.333 |  0.415 12.337  0.172 |
## worry    | -0.009  0.003  0.000 | -0.612 22.349  0.374 |  0.445 14.167  0.198 |
## 
## Supplementary continuous variables
##             Dim.1   cos2    Dim.2   cos2    Dim.3   cos2  
## educ     |  0.548  0.300 | -0.002  0.000 | -0.061  0.004 |
## age      | -0.035  0.001 | -0.228  0.052 | -0.131  0.017 |
## 
## Supplementary categories
##             Dim.1   cos2 v.test    Dim.2   cos2 v.test    Dim.3   cos2 v.test  
## F        |  0.021  0.009  0.254 | -0.001  0.000 -0.016 | -0.151  0.442 -2.500 |
## H        | -0.022  0.009 -0.254 |  0.001  0.000  0.016 |  0.158  0.442  2.500 |

Faut-il plutôt faire une AFM qu’une ACP ?

Inspecter les coéfficients de corrélation canoniques de l’AFM (Pagès 2013, p. 123-124).

Chercher la valeur max dans les premières dimensions et la seconde valeure max dans des dimension supérieures. Si les coefficients d’au moins deux groupes en dim 1 de préférence sont compris dans cette tranche, alors il est recommandé d’utiliser l’AFM. Sinon, revérifier son groupement de variables ou ne pas grouper les variables et faire une ACP.

round(res$group$correlation, 2)
##          Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## ling      0.92  0.10  0.12  0.10  0.13
## math_log  0.91  0.07  0.13  0.20  0.13
## soc       0.24  0.47  0.82  0.25  0.19
## stress    0.05  0.69  0.50  0.52  0.94
## impuls    0.29  0.66  0.14  0.70  0.18

Comparaison avec les données “cas d’école” Wine

data(wine)
res.W <- MFA(wine, group=c(2,5,3,10,9,2), type=c("n",rep("s",5)),
    ncp=5, name.group=c("orig","olf","vis","olfag","gust","ens"),
    num.group.sup=c(1,6), graph = F)

round(res.W$group$correlation, 2)
##       Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## olf    0.89  0.96  0.89  0.48  0.42
## vis    0.93  0.22  0.16  0.22  0.17
## olfag  0.97  0.89  0.90  0.57  0.66
## gust   0.95  0.87  0.30  0.25  0.52

Les valeurs propres : indicateur de la fiabilité des résultats de l’AFM : variation structurée ou aléatoire ?

Cours Husson: https://youtu.be/8qw0bNfK4H0?t=1887

Réponse : 46.9% de la variation est expliquée par les dim 1 & 2. Une dimension => 1 grande tendance / jeu d’opposition entre les individus. Les premières dimensions => les premières dimensions sont les plus pertinentes. Souvent 5 dimensions suffisent pour analyser les données dans le détail. Ici avec les 5 dimensions on explique 81.7% de la variation.

Elbow test (test du coude) : si après une dimension la valeur propre chute brutalement puis se stabilise, la dernière dimension recommandée sera celle placée juste avant le coude. Selon les données, on peut aussi inclure les dimensions dont la valeur propre est égale ou supérieure à 1 (cf. Abdi & Williams 2010 p. 441, section “How many components?”)

Conclusion : la variation ne semble pas aléatoire, cela vaut la peine d’appliquer l’AFM.

library(factoextra)
library(ggrepel)
# Visualize eigenvalues (valeurs propres)
fviz_screeplot(res, addlabels = TRUE, ylim = c(0, 50))

Quelles sont les distances entre les individus en fonction des résultats au test de personnalité ?

graphique : carte factorielle / graphique des individus

Les individus au croisement des axes sont les individus au profil le plus courant. Plus un individu s’écarte des axes, plus il est atypique. Sa position va être conditionnée par les variables (jusqu’ici invisibles mais sous-jacentes) Un individu peut être le meilleur aux tests de logique, être le plus stressé ou le moins sociable. Cela va conditionner sa position sur le graphique.

plot(res, choix = "ind", axes = c(1,2), repel=F)
## Warning: ggrepel: 144 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

# avec coloration en fonction du genre ou tout autre variable qualitative.
# Seuls les individus caractérisant les extrémités d'une dimension sont indiqués
plot(res, choix = "ind", , axes = c(1,2), habillage = "gender", lab.ind =T,
     select=c("10","11","111","243","56","164","202"), repel=F)

plot(res, choix = "ind", , axes = c(1,2), col.ind = "lightgrey", lab.ind =T, cex =1, invisible="quali.sup", autoLab = "yes",select=c("10","11","111","243","56","164","202"), repel=T)

# 2 individus aux valeurs proches des moyennes : individus 10 et 11
# res$ind$coord ## chercher les individus aux coordonnées proches de zéro pour la dim 1 et 2.
# convertir les résultats en data.frame (peut être extrait en txt par la suite)

coorddf<- as.data.frame(res$ind$coord)
# les noms des colonnes ont un point Dim.1 => renommer au cas où.
names(coorddf) <- c("Dim1","Dim2","Dim3","Dim4","Dim5")

# ordonner les coordonnées des individus et chercher les valeurs absolues proches de 0.01 pour la dim 1 et 2. On obtien les individus dont les valeurs sont les plus proches de la moyenne.

round(coorddf[order( coorddf[,1], coorddf[,2] ),], 2)
##      Dim1  Dim2  Dim3  Dim4  Dim5
## 111 -4.68  0.88 -0.41  1.00  0.23
## 90  -3.57  0.90 -0.10 -1.17 -0.59
## 196 -3.37  0.41 -0.36  0.36 -0.65
## 227 -3.14 -1.86  0.44 -0.40 -1.21
## 69  -2.91 -2.09 -0.08  0.99  0.34
## 177 -2.82  0.46 -0.28  0.89  0.25
## 169 -2.68 -0.80  1.17 -0.82 -0.70
## 231 -2.57  2.38  0.28  0.38 -1.32
## 12  -2.39 -0.12 -0.35  0.75  0.84
## 52  -2.34 -2.32  0.17  2.04  0.69
## 247 -2.28  0.60  0.96 -1.20  0.08
## 250 -2.25  0.81 -2.05 -0.73  1.11
## 117 -2.24  0.40  0.79 -0.13 -0.05
## 187 -2.23 -0.22  0.27 -1.96 -0.35
## 155 -2.15 -0.56  0.02 -0.67 -0.67
## 83  -2.10  0.04 -0.41 -1.03  0.84
## 40  -2.05  1.21 -0.30  0.28  0.11
## 220 -2.05 -0.63  0.29 -0.59 -1.03
## 72  -2.03 -0.72 -0.82  1.66 -1.21
## 232 -2.02  0.24 -0.04  1.13 -0.28
## 9   -1.92  0.52  0.06  0.13  0.67
## 76  -1.90 -0.63  2.70 -0.85 -1.14
## 241 -1.88 -1.08 -0.47 -1.12 -0.50
## 176 -1.87  0.08  0.71  1.41 -0.45
## 31  -1.83 -1.27 -0.65 -1.12 -0.43
## 25  -1.77  1.02  0.67 -0.63 -0.10
## 174 -1.75  1.36 -1.54 -0.36  0.21
## 74  -1.69 -0.29  0.71 -1.39  0.01
## 158 -1.65  0.63 -0.44 -0.59  0.50
## 163 -1.61  0.21 -0.17  0.62  1.35
## 240 -1.61 -1.15  0.53 -0.43 -0.25
## 234 -1.54  0.57  2.32  0.75  1.19
## 71  -1.54  0.25  1.91 -0.12 -0.05
## 218 -1.51 -0.43  1.01  0.38  0.89
## 216 -1.50  0.39  0.33 -1.60  0.38
## 82  -1.45 -0.55 -2.01  0.90 -0.51
## 2   -1.41 -0.47 -1.18  0.75  0.03
## 119 -1.40  0.06 -0.14  1.15  0.78
## 192 -1.40  0.65 -1.08  1.06  0.31
## 116 -1.36 -1.62 -0.57  1.14  0.01
## 122 -1.36 -1.18 -0.22 -0.30  0.42
## 235 -1.35  0.25 -0.60 -0.55  0.10
## 133 -1.28 -0.24  1.04 -1.01  0.52
## 199 -1.27  0.42  1.32 -0.66  0.67
## 103 -1.25 -0.33 -0.52 -0.22  1.35
## 106 -1.16  0.40 -0.91  2.21  0.33
## 178 -1.15  0.34  0.38  0.33 -0.21
## 246 -1.12 -1.61 -0.10  0.38 -0.54
## 208 -1.12  1.84  0.62 -1.50 -0.21
## 214 -1.12  1.57  0.84  0.28 -0.71
## 80  -1.11  0.27  0.04 -0.38  0.91
## 88  -1.07 -0.10 -1.34  0.10  1.64
## 207 -1.02  0.24  2.04 -0.63 -0.73
## 224 -0.98 -0.31 -0.80 -0.23 -0.36
## 156 -0.95  1.81  1.48 -0.61 -0.19
## 86  -0.93 -0.16 -0.35  1.46 -0.32
## 201 -0.92 -0.81 -1.07 -0.39  0.80
## 160 -0.89 -0.33  0.01 -0.94  1.32
## 70  -0.88  1.19 -1.05  0.45  0.14
## 186 -0.85 -0.91  1.25  0.32  0.02
## 152 -0.85 -1.45  0.67  0.33  0.37
## 162 -0.82 -0.73 -0.38  0.02  0.06
## 87  -0.80 -0.37 -0.71 -0.79 -0.38
## 215 -0.79  0.05 -0.19 -0.13  0.21
## 19  -0.78 -1.41  0.83 -0.48 -0.94
## 36  -0.78  0.49  0.66  0.30 -0.36
## 153 -0.74 -1.48  0.33 -0.10  0.25
## 249 -0.72 -0.19 -1.26 -1.84 -0.58
## 123 -0.71  0.25 -0.96  0.74  0.51
## 66  -0.69  0.07 -0.85  1.16 -1.36
## 50  -0.67 -0.75 -0.62  0.06  0.16
## 99  -0.67  2.14  0.50 -0.65 -0.09
## 195 -0.67 -0.31  0.34 -0.16 -0.48
## 118 -0.66 -1.04 -1.54  1.26 -0.17
## 211 -0.66 -0.93  0.89 -0.65  1.61
## 213 -0.65  1.92  0.25 -0.27  0.17
## 194 -0.62  1.08 -0.06  0.17  0.60
## 205 -0.58  0.13 -0.13 -0.37  0.51
## 49  -0.57 -1.17  1.97 -0.45 -0.12
## 145 -0.56  1.77 -0.08  0.22  0.01
## 242 -0.56 -0.75  1.88  1.47  0.22
## 228 -0.53  0.05  1.46 -0.44  0.60
## 43  -0.53 -1.33  0.81 -0.73  0.57
## 62  -0.52 -0.32 -1.39  0.38  0.28
## 41  -0.50 -0.11  0.00  1.09  0.45
## 175 -0.48 -0.68 -3.15 -0.33  0.26
## 127 -0.48 -0.45  0.36 -0.35  0.58
## 248 -0.47 -0.74 -0.17 -1.20 -1.17
## 166 -0.45  0.28 -0.54  0.63 -0.10
## 165 -0.45 -0.05  0.14 -0.37 -0.80
## 24  -0.45  1.17  0.87 -0.89  0.88
## 102 -0.44  0.16  0.52 -0.40 -0.08
## 222 -0.42  0.72  0.19  1.10 -0.38
## 237 -0.40  0.66 -0.87  2.57 -0.03
## 33  -0.39 -0.95 -0.48 -0.12 -0.11
## 55  -0.38 -1.20 -0.72 -0.63 -0.49
## 61  -0.37  0.19  0.68  0.46  0.15
## 142 -0.35  0.26  0.24 -1.93  0.88
## 27  -0.34 -1.56 -1.01 -0.98 -0.82
## 238 -0.31  0.31 -0.12 -0.40 -1.16
## 59  -0.31 -1.02 -2.07 -0.51  0.17
## 170 -0.30 -0.22 -1.11  0.23 -0.49
## 183 -0.30  0.13  0.19  0.15  0.21
## 143 -0.30  1.45 -0.47  0.02  0.18
## 141 -0.28 -0.02  0.30  0.36 -0.32
## 20  -0.26 -1.10 -0.02 -1.10 -0.72
## 124 -0.24  0.52 -0.87 -0.42  0.79
## 4   -0.23  0.64  0.32 -0.97 -0.23
## 77  -0.23 -1.30 -1.45  1.45 -0.12
## 151 -0.21  0.72  0.36 -0.43 -0.91
## 206 -0.20  1.74  1.29  0.54 -1.45
## 130 -0.19  1.20  0.36  0.08  1.31
## 91  -0.19 -0.94  0.38  0.49  0.69
## 225 -0.13  1.10  1.08 -1.20  1.23
## 11  -0.11  0.01  0.78  0.72  0.85
## 229 -0.09 -0.84 -0.38  1.52  0.09
## 10  -0.07 -0.17  0.04  0.48 -0.51
## 67  -0.06  1.36 -0.53  1.22 -0.47
## 203 -0.05 -2.10  1.94 -0.48  0.46
## 135 -0.04 -1.22 -0.14 -0.07  1.03
## 95  -0.04  1.47 -0.38  0.38 -0.16
## 212 -0.04  1.15  0.99 -0.23  0.18
## 5   -0.02 -0.14 -1.42 -0.35  0.38
## 73   0.00  0.88  0.04  0.68  0.74
## 125  0.00  2.56 -1.08  0.60  0.07
## 129  0.02 -0.78  0.63 -0.60 -0.71
## 134  0.03 -1.46 -0.72 -1.41 -0.97
## 35   0.03 -0.23 -0.89  1.11 -0.25
## 29   0.03  0.48  1.11 -0.92  0.60
## 56   0.03  2.93 -2.17 -0.82 -0.29
## 16   0.05 -0.41 -0.56  0.06 -0.49
## 105  0.07 -0.25 -0.33 -0.37  0.26
## 181  0.08 -1.72  0.02  0.50  0.83
## 79   0.09  0.51 -0.07 -1.02 -0.20
## 159  0.09  0.67 -0.23 -0.09 -0.66
## 226  0.12 -0.57 -2.45  0.22  0.15
## 7    0.16  0.77  0.19 -0.02 -1.11
## 51   0.17  1.67  2.12  1.03  0.19
## 108  0.18 -0.62  1.30 -0.12  0.09
## 154  0.19 -0.56 -0.24 -0.01 -1.51
## 42   0.21  1.88 -0.26  0.62 -0.38
## 81   0.22  1.17 -1.38  1.63  0.41
## 146  0.22 -0.44  2.37 -0.48 -0.05
## 97   0.24  0.00  1.99  0.60 -0.04
## 131  0.25 -0.35  0.33  0.75 -0.42
## 54   0.27  0.86 -1.12  1.41 -0.39
## 37   0.27  0.15 -0.06 -0.22 -0.16
## 180  0.28 -0.02  0.98  0.21  0.50
## 120  0.32  0.40  0.01  0.10 -0.11
## 144  0.32  1.02  0.65  1.07 -0.22
## 148  0.32 -1.52  1.04  2.51 -0.19
## 164  0.32 -2.22 -0.39 -0.35 -0.02
## 239  0.33  0.74 -0.74 -0.12 -0.16
## 115  0.34 -0.09 -0.78 -1.45  0.36
## 17   0.39 -1.08  1.08 -0.35 -0.19
## 26   0.40 -1.64  0.35  0.21  0.13
## 8    0.45  0.59 -0.50 -0.50  0.08
## 22   0.46  1.21 -1.12  1.72  0.65
## 93   0.47 -0.06 -1.43 -0.47  0.19
## 198  0.51  0.55  1.82  0.66  0.23
## 48   0.52  0.12  1.28 -0.99 -0.56
## 114  0.52  0.53  0.17  0.81 -1.13
## 128  0.54  0.81  0.54  0.32  0.55
## 68   0.60  0.34  1.28  0.94 -0.35
## 92   0.62  2.38 -0.44 -1.88 -0.37
## 6    0.65  1.90 -0.29 -0.88  0.41
## 45   0.66  0.08 -0.09 -0.80  0.12
## 139  0.66  1.19 -0.69  1.75 -0.08
## 13   0.69  0.14  1.52 -0.17 -1.09
## 190  0.69  2.06 -0.40 -1.92 -0.40
## 63   0.71 -0.83 -1.06  0.18  0.15
## 53   0.72  0.48 -0.47  0.40  0.27
## 101  0.73 -0.06 -0.08  0.37 -0.88
## 204  0.76  2.06 -0.64  0.18  0.08
## 185  0.76 -2.34 -0.45 -0.68 -0.14
## 121  0.77  0.12  0.53 -0.30  0.37
## 98   0.78  0.36 -0.53 -1.67 -1.19
## 100  0.79  1.96  0.12 -1.59  0.45
## 107  0.79 -0.14  0.60  0.75 -0.21
## 18   0.80 -0.76 -0.82  0.48 -1.10
## 189  0.83 -0.67  1.57 -0.12  0.96
## 96   0.85  2.42 -1.56 -0.17  0.12
## 94   0.86 -1.51  0.40  0.05  0.92
## 191  0.86  1.30 -0.56  0.06  0.34
## 57   0.87 -0.49  2.11 -0.25 -0.75
## 150  0.89 -1.00 -0.32  0.30 -0.94
## 15   0.92 -1.64 -0.70 -2.52 -0.06
## 132  0.94 -0.39  1.34  0.63  0.08
## 157  0.95  1.62  0.13 -0.38  0.27
## 28   0.97 -0.52 -0.63 -0.08  1.04
## 65   0.97 -0.82  0.05 -1.04  0.37
## 230  0.98  0.38  1.03  0.92 -0.05
## 109  1.00  1.70 -0.07  1.93 -0.27
## 44   1.01  0.50 -1.13  0.05 -0.75
## 78   1.02 -1.65 -0.95 -1.84 -0.47
## 113  1.06 -1.76 -1.55  2.47 -0.10
## 219  1.07 -0.79 -0.43  0.18 -0.59
## 161  1.08 -0.77  1.28  2.22 -0.94
## 167  1.09  0.22  1.52  2.15  0.17
## 21   1.09 -0.74  0.89  1.29  0.48
## 39   1.12 -1.95 -0.85 -0.45 -0.51
## 110  1.13  0.29  0.70 -0.10  0.09
## 75   1.16  0.59 -0.87 -0.61  0.30
## 209  1.18 -0.64  0.67  0.59 -0.46
## 245  1.19  0.36 -0.60 -1.03 -0.41
## 149  1.20 -0.21 -0.70 -0.21 -0.37
## 179  1.20  0.49  0.23 -0.87  0.55
## 137  1.21 -1.12 -0.65 -0.77  0.24
## 23   1.23 -1.56 -0.25  1.27  0.43
## 188  1.29 -1.75 -1.04  0.71  0.49
## 140  1.29 -0.85 -0.45 -0.72 -0.24
## 104  1.37  0.58 -1.64  0.07  0.21
## 147  1.38  1.97 -1.80 -0.09  0.18
## 84   1.39 -2.06 -0.19  0.01 -0.28
## 171  1.39  0.58  0.35  0.74  0.61
## 38   1.39  0.45 -1.50 -2.55 -0.11
## 34   1.42  0.68 -0.21 -0.34 -0.19
## 47   1.45  0.40 -0.38  0.45  0.34
## 112  1.48  1.09 -1.34  0.36 -0.21
## 64   1.50 -0.83 -0.48  0.79 -0.14
## 193  1.62  1.29  2.14 -0.84  1.57
## 60   1.68 -0.31  0.07  0.57  1.01
## 182  1.73 -0.14  1.66  0.37 -0.16
## 236  1.74  0.17  0.94  0.09  0.15
## 46   1.75 -0.66 -1.11 -1.08  0.03
## 184  1.75 -1.32  0.53 -0.22 -0.10
## 126  1.77  1.71  2.06 -0.36 -0.52
## 172  1.79  0.41  0.46  0.47  0.16
## 173  1.89 -0.14 -0.23  0.48  0.18
## 136  1.94  1.15 -1.45  0.59 -0.76
## 200  1.96 -1.32  0.91  0.44  0.31
## 168  1.98 -0.64 -0.28 -0.27 -0.79
## 89   1.99 -1.17 -0.16 -1.22  0.93
## 32   2.01 -1.76 -0.64 -2.38  0.21
## 30   2.01  1.24  0.25  0.95 -1.02
## 217  2.08 -1.56  1.17  0.89 -1.06
## 1    2.16  0.04  0.01 -1.54 -1.16
## 223  2.16 -0.51 -1.68  0.69  0.34
## 221  2.17  0.54 -0.66  0.02  0.33
## 14   2.18  0.92 -0.16  0.65 -0.51
## 58   2.27  0.60  1.05 -0.68  0.10
## 233  2.30 -1.27 -0.52  0.46  0.22
## 3    2.53 -0.56  1.18  0.90  0.28
## 210  2.56 -1.74 -0.40 -1.07  0.56
## 244  2.56 -0.71  0.86 -0.28  0.70
## 138  2.57  0.23  0.79 -1.03  0.04
## 85   2.72  0.22 -0.79 -1.43  0.25
## 197  2.84  0.01 -0.25 -0.35  0.51
## 243  3.33 -0.94  0.70  1.58  0.21
## 202  3.93  3.10  1.02  0.73 -0.43
round(res$ind$coord[c(10,11),c(1:2)], 2)
##    Dim.1 Dim.2
## 10 -0.07 -0.17
## 11 -0.11  0.01
# Vérifier les moyennes
round(colMeans(interest[,c(4:15)]), 2)
##    vocab  reading sentcomp mathmtcs geometry analyrea   socdom sociabty 
##     0.09     0.13     0.07     0.11     0.11     0.17     0.10     0.06 
##   stress    worry impulsve thrillsk 
##    -0.02     0.00     0.05     0.14
# véfifier les moyennes de ces individus
round(head(interest[c(10,11),4:15]), 2) # scores proches de la moyenne partout
##    vocab reading sentcomp mathmtcs geometry analyrea socdom sociabty stress
## 10  0.47    0.38     0.80    -0.03    -0.79     0.14   0.36    -0.58   0.61
## 11 -0.96    0.54    -0.04    -0.25     0.97     0.30   0.89     0.02  -0.14
##    worry impulsve thrillsk
## 10  0.01     0.82    -0.12
## 11  1.43     0.49     0.75
# Autre façon de vérifier les moyennes (avec ecart.type et minimum/maximum)
res$summary.quanti
##    group variable moyenne ecart.type minimum maximum
## 1      2     educ   12.30       1.61    8.00   18.00
## 2      2      age   39.55      10.02   11.00   65.00
## 3      3    vocab    0.09       1.00   -2.62    2.63
## 4      3  reading    0.13       0.99   -2.47    2.70
## 5      3 sentcomp    0.07       0.99   -2.47    2.73
## 6      4 mathmtcs    0.11       1.05   -3.71    3.06
## 7      4 geometry    0.11       1.03   -3.32    3.86
## 8      4 analyrea    0.18       1.05   -2.83    3.50
## 9      5   socdom    0.10       1.00   -2.72    2.90
## 10     5 sociabty    0.06       1.02   -3.09    2.76
## 11     6   stress   -0.02       0.94   -2.56    2.78
## 12     6    worry    0.00       1.00   -3.07    2.42
## 13     7 impulsve    0.05       0.99   -3.04    2.62
## 14     7 thrillsk    0.14       1.03   -2.96    3.00
# Les atypiques (souvent aux extrêmes des axes): 
# Dimension 1 
# 111 vs. 243
head(interest[c(111,243,202),(1:9)]) # mauvais aux tests vs. bons aux tests
##     gender educ age vocab reading sentcomp mathmtcs geometry analyrea
## 111      H    8  45 -2.01   -2.47    -2.47    -3.71    -2.59    -2.67
## 243      F   12  32  2.10    2.64     1.52     3.06     2.60     2.35
## 202      H   16  29  2.63    2.23     2.55     1.38     3.86     3.50
# Dimension 1 => résulats aux tests scolaires.

# Dimension 2
#  56 vs. 164
head(interest[c(56,164),(1:15)]) # goût du risque vs. anxiété
##     gender educ age vocab reading sentcomp mathmtcs geometry analyrea socdom
## 56       H   12  34  0.82    0.25     0.97    -0.22    -0.13    -0.46  -1.34
## 164      F   12  47  0.06    0.25     0.91     0.20     0.21    -0.55  -0.64
##     sociabty stress worry impulsve thrillsk
## 56      1.08  -2.56 -3.07     0.26     2.24
## 164    -1.10   0.51  1.28    -2.58    -0.09
# Dimension 2 => traits de caractère

# Et la famille sociabilité ?
# Dimension 3 ?
# Vérification de la contribution de chaque variable à chaque dimension.
# En pourcentage.
round(res$quanti.var$contrib)
##          Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## vocab       17     0     0     0     2
## reading     15     0     1     0     1
## sentcomp    15     0     0     0     1
## mathmtcs    16     0     1     1     2
## geometry    14     0     0     1     2
## analyrea    15     0     0     2     1
## socdom       1     8    38     3     2
## sociabty     2    11    32     4     1
## stress       0    20    12    18    43
## worry        0    22    14    13    42
## impulsve     4    19     0    25     2
## thrillsk     1    19     1    31     1
# Sociabilité est à observer en dimension 3 car elle explique 70% de la variation mise en valeur en dim 3 (38% et 32% soit 70%).

#VERIF : la somme des contributions par dimension est bien de 100 par dimension.
sum(as.data.frame(res$quanti.var$contrib)[,1]) # Dim 1
## [1] 100
sum(as.data.frame(res$quanti.var$contrib)[,2]) # Dim 2
## [1] 100
# Attention : il est souvent recommandé d'utiliser le cosinus carré pour vérifier pour vérifier la qualité de représentation des variables et des individus. Bonne qualité = interprétabilité.

# Cos2 : qualité de représentation.
round(res$quanti.var$cos2, 2)
##          Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## vocab     0.79  0.00  0.01  0.01  0.01
## reading   0.70  0.00  0.02  0.00  0.01
## sentcomp  0.69  0.00  0.01  0.01  0.01
## mathmtcs  0.74  0.00  0.02  0.03  0.02
## geometry  0.65  0.00  0.00  0.03  0.01
## analyrea  0.70  0.01  0.00  0.04  0.01
## socdom    0.04  0.14  0.57  0.04  0.01
## sociabty  0.05  0.20  0.48  0.05  0.01
## stress    0.00  0.33  0.17  0.23  0.24
## worry     0.00  0.37  0.20  0.16  0.23
## impulsve  0.10  0.33  0.00  0.33  0.01
## thrillsk  0.02  0.33  0.01  0.41  0.01

Cours Husson : https://youtu.be/8qw0bNfK4H0?t=2184

Pistes sur les cas où la contribution est élevée mais la qualité de représentation est faible. DIAPO 23 (Cours d’Angelina Roche) https://www.ceremade.dauphine.fr/~roche/Enseignement/ADD/ADD_Cours2.pdf

Rôle des groupes dans la distinction des individus

round(res$group$contrib, 4)
##            Dim.1   Dim.2   Dim.3   Dim.4   Dim.5
## ling     46.9864  0.1245  1.3603  0.9529  4.2052
## math_log 45.4715  0.2181  1.1823  4.5949  4.6748
## soc       3.0452 19.2306 70.0473  7.0468  2.9020
## stress    0.1012 42.2269 26.5042 30.7308 85.2174
## impuls    4.3956 38.2000  0.9059 56.6746  3.0006
round(res$group$cos2, 4)
##           Dim.1  Dim.2  Dim.3  Dim.4  Dim.5
## ling     0.7154 0.0000 0.0002 0.0001 0.0002
## math_log 0.6687 0.0000 0.0001 0.0016 0.0003
## soc      0.0029 0.0449 0.4146 0.0035 0.0001
## stress   0.0000 0.2049 0.0562 0.0629 0.0893
## impuls   0.0057 0.1709 0.0001 0.2182 0.0001
plot(res, choix = "group", axes=c(1,2))

plot(res, choix = "group", axes=c(3,4))

plot(res, choix = "group", axes=c(1,4))

Corrélations entre toutes les variables

Cours Husson : https://youtu.be/8qw0bNfK4H0?t=1242

Graphique : cercle des corrélations

Flèches proches : corrélées positivement (ling & math_log & educ) Flèches opposées : corrélées négativement (soc vs. stress) Flèches à angle droit : pas de corrélation (stress vs. ling & math_log & educ)

#FactoMineR
#plot(res, axes = c(1,2), choix = "var", habillage = "group", repel=T)

# graphique des individus (pour une mise en regard)
plot(res, choix = "ind", axes = c(1,2), repel=F)
## Warning: ggrepel: 144 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

#factoextra
fviz_mfa_var(res, axes = c(1,2), choice= "quanti.var",col.var.sup = "lightgrey", repel = T)
## Warning: ggrepel: 1 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

# Quand les gens sont bons, ils sont généralement bons partout aux tests.
# Si je veux 2 indicateurs uniquement :
round(res$quanti.var$cor,2) # corrélation positive maximale => 1, pas de corrélation => 0, corrélation négative => -1
##          Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## vocab     0.89  0.05 -0.08  0.10 -0.12
## reading   0.84 -0.03 -0.13  0.04 -0.11
## sentcomp  0.83  0.02 -0.09  0.10 -0.12
## mathmtcs  0.86  0.01 -0.16  0.17  0.13
## geometry  0.80  0.00  0.00  0.17  0.12
## analyrea  0.84  0.08 -0.07  0.21  0.11
## socdom    0.20  0.38  0.76 -0.21 -0.11
## sociabty  0.22  0.45  0.69 -0.23  0.07
## stress   -0.05 -0.58  0.42  0.48 -0.49
## worry    -0.01 -0.61  0.44  0.40  0.48
## impulsve -0.31  0.57  0.04  0.57  0.11
## thrillsk -0.15  0.57 -0.11  0.64 -0.07
# si valeur absolue est proche de 1 : contribution forte à la création des axes (clairement discriminante)
# invitation à regarder d'autres axes (impulsivité et sociabilité)

# graphique des individus (mise en regard)

plot(res, choix = "ind", axes = c(2,3), repel=F)
## Warning: ggrepel: 188 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

plot(res, choix = "var", axes = c(2,3), repel=F)
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

head(interest[c(51,175),(10:15)])
##     socdom sociabty stress worry impulsve thrillsk
## 51    1.67     2.63   0.31  0.72     1.08     2.09
## 175  -2.32    -2.82  -1.30 -1.02    -0.80     0.17

5 Classification hiérarchique.

Dendrogramme et carte factorielle

hc <- HCPC(res,nb.clust=-1) # -1 => laisser le programme décider du nombre de cluster.

# help: plot.HCPC

plot(hc, choice="bar")

# vérifier sur quelles dimensions la projection des clusters est la plus pertiente.
hc$desc.axes
## 
## Link between the cluster variable and the quantitative variables
## ================================================================
##             Eta2      P-value
## Dim.1 0.59641433 2.153094e-49
## Dim.2 0.50880305 7.414374e-39
## Dim.3 0.03147584 1.925936e-02
## 
## Description of each cluster by quantitative variables
## =====================================================
## $`1`
##           v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2  -3.736229       -0.2994481  1.081080e-17      0.7771222   1.067402
## Dim.1 -11.679339       -1.1811511 -3.663736e-17      0.8993907   1.346874
##            p.value
## Dim.2 1.868009e-04
## Dim.1 1.625549e-31
## 
## $`2`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2 10.931164        1.1403425  1.081080e-17      0.7000404   1.067402
## Dim.1  3.480337        0.4581305 -3.663736e-17      0.8552737   1.346874
##            p.value
## Dim.2 8.179224e-28
## Dim.1 5.007837e-04
## 
## $`3`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1  9.204156        1.2352508 -3.663736e-17      0.7886062  1.3468745
## Dim.3  2.782159        0.2702827  1.496026e-17      0.9335627  0.9749721
## Dim.2 -6.952736       -0.7394825  1.081080e-17      0.7531347  1.0674022
##            p.value
## Dim.1 3.443680e-20
## Dim.3 5.399856e-03
## Dim.2 3.582696e-12
# Ici dim 1 et 2 pour la plupart des clusters sauf cluster 3. Vérifier la variation au sein des individus pour cluster après les premières analyses.

Meilleure visualisation avec factoextra

https://rpkgs.datanovia.com/factoextra/reference/fviz_cluster.html https://agroninfotech.blogspot.com/2020/06/visualizing-clusters-in-r-hierarchical.html

# Projeter les clusters sur la carte factorielles (dim 1 et 2)
library(factoextra)
fviz_cluster(hc, data = interest[1:15],
             main = "Clustering Plot",
             axes=c(1,2), 
            # ellipse.type = "norm",
             repel=F,
             pointsize = 0.5,labelsize = 0)

fviz_dend(hc, cex = 0.8, k=3, #attention aux codes couleur qui ne correspondent pas au graphique avec la fonction fviz_cluster()
          show_labels = F,
          k_colors = c("#F8766D", "#00BCD8", "#00BA38"),
          rect = TRUE,
          rect_border = "gray",
          rect_fill = F, 
          horiz = F)

5 Inspecter les diagnostiques : les points communs entre les individus d’un même cluster.

Les variables ayant contribué le mieux à la caractérisation des clusters (dans l’ensemble)

NB: Présence d’une variable = caractérise significativement les clusters (au moins un) Absence d’une variable = n’aide pas suffisemment à caractériser les clusters (souvent : valeur partagée par tous les groupes, trop peu représentée, trop de variation etc.)

Bilan du diagnostique ci-dessous : les résultats aux tests linguistiques disciminent bien les groupes, viennent ensuite les tests scientifiques. Moins discriminant : âge. Pas assez discriminant : sexe (absent)

hc$desc.var$quanti.var
##                Eta2      P-value
## vocab    0.53131186 2.260320e-41
## sentcomp 0.45222467 5.216812e-33
## reading  0.43630696 1.793785e-31
## mathmtcs 0.40184547 2.731834e-28
## analyrea 0.37884744 2.883948e-26
## geometry 0.29880869 9.137148e-20
## worry    0.27054994 1.202132e-17
## stress   0.21846156 6.016826e-14
## impulsve 0.19221415 3.557015e-12
## thrillsk 0.17598841 4.147297e-11
## educ     0.16144335 3.599587e-10
## sociabty 0.11947787 1.497697e-07
## socdom   0.10657869 9.025145e-07
## age      0.04806836 2.279354e-03

Rôle des variables dans la caractérisation de chaque cluster : profilage

Cluster 1

Anxieux, plus âgés que la moyenne, résultats aux tests inférieurs à la moyenne. Taux d’éducation légèrement plus bas que la moyenne.

library(factoextra)
hc$desc.var$quanti$`1`
##              v.test Mean in category Overall mean sd in category Overall sd
## worry      2.219293        0.1696154      0.00224      0.8627605  1.0044237
## age        2.006287       41.0576923     39.54800     10.0611849 10.0215616
## socdom    -4.884391       -0.2661538      0.10120      0.9954534  1.0016455
## sociabty  -4.956553       -0.3205769      0.05968      0.9300732  1.0217326
## educ      -5.851420       11.5961538     12.30400      1.2520693  1.6110816
## geometry  -8.397261       -0.5379808      0.11252      0.8454145  1.0316920
## analyrea  -9.518059       -0.5788462      0.17500      0.8315143  1.0548100
## mathmtcs  -9.755152       -0.6652885      0.10548      0.8572260  1.0522764
## reading   -9.954697       -0.6039423      0.13496      0.7778514  0.9885506
## sentcomp -10.194856       -0.6840385      0.07356      0.7539008  0.9896871
## vocab    -11.053168       -0.7367308      0.09016      0.6648546  0.9963256
##               p.value
## worry    2.646683e-02
## age      4.482569e-02
## socdom   1.037488e-06
## sociabty 7.175462e-07
## educ     4.873947e-09
## geometry 4.570134e-17
## analyrea 1.764439e-21
## mathmtcs 1.753382e-22
## reading  2.405541e-23
## sentcomp 2.090541e-24
## vocab    2.116140e-28
#Synthèse:
fviz_cluster(hc, data = interest[1:15],
             main = "Clustering Plot",
             axes=c(1,2), 
            # ellipse.type = "norm",
             repel=F,
             pointsize = 0.5,labelsize = 0)+
  annotate("label", x = -3, y = 0, label = "Anxieux, 40 ans, pas sociable", size=2.5) + annotate("label", x = -3, y = -1, label = "moins bon aux test, moins d'études", size=2.5)

Cluster 2

Goût marqué pour le risque, très sociables, résultats supérieurs aux tests, plus jeunes que la moyenne. Taux d’éducation non significatif.

hc$desc.var$quanti$`2`
##             v.test Mean in category Overall mean sd in category Overall sd
## thrillsk  5.785666        0.7259459      0.14096      0.9915371  1.0345495
## impulsve  4.741496        0.5100000      0.05248      0.8225274  0.9873108
## sociabty  4.617917        0.5208108      0.05968      0.8951110  1.0217326
## socdom    4.043436        0.4970270      0.10120      0.9573806  1.0016455
## analyrea  3.590420        0.5451351      0.17500      0.8940165  1.0548100
## mathmtcs  3.486649        0.4640541      0.10548      0.7903453  1.0522764
## vocab     3.385971        0.4198649      0.09016      0.7199502  0.9963256
## sentcomp  3.115067        0.3748649      0.07356      0.7398616  0.9896871
## geometry  2.944944        0.4094595      0.11252      0.9387166  1.0316920
## reading   2.862181        0.4114865      0.13496      0.7095196  0.9885506
## age      -3.456925       36.1621622     39.54800     10.1675518 10.0215616
## stress   -6.973680       -0.6547297     -0.01696      0.7946871  0.9357527
## worry    -7.828190       -0.7662162      0.00224      0.8234136  1.0044237
##               p.value
## thrillsk 7.222562e-09
## impulsve 2.121459e-06
## sociabty 3.876118e-06
## socdom   5.267351e-05
## analyrea 3.301455e-04
## mathmtcs 4.891127e-04
## vocab    7.092685e-04
## sentcomp 1.839029e-03
## geometry 3.230132e-03
## reading  4.207369e-03
## age      5.463769e-04
## stress   3.087564e-12
## worry    4.949425e-15
#Synthèse:
fviz_cluster(hc, data = interest[1:15],
             main = "Clustering Plot",
             axes=c(1,2), 
            # ellipse.type = "norm",
             repel=F,
             pointsize = 0.5,labelsize = 0)+
  annotate("label", x = 0.5, y = 2.5, label = "Aime le risque, 36 ans, sociable", size=2.5) + annotate("label", x = 0.5, y = 2, label = "bon aux test, études NS", size=2.5)

Cluster 3

Excellents résultats aux tests, n’aiment pas le risque, sujets à l’anxiété et au stress. Sociabilité : non significatif => trop de variation au sein du groupe OU valeurs trop proches de la moyenne générale de l’échantillon pour que ces variables soient discriminantes.

hc$desc.var$quanti$`3`
##             v.test Mean in category Overall mean sd in category Overall sd
## vocab     8.617715        0.9456944      0.09016      0.6665100  0.9963256
## sentcomp  7.956561        0.8581944      0.07356      0.6923838  0.9896871
## reading   7.950085        0.9180556      0.13496      0.7220373  0.9885506
## mathmtcs  7.103371        0.8502778      0.10548      0.7722190  1.0522764
## analyrea  6.740692        0.8834722      0.17500      0.7612529  1.0548100
## geometry  6.171429        0.7469444      0.11252      0.8083379  1.0316920
## worry     5.475824        0.5502778      0.00224      0.8850125  1.0044237
## educ      5.200763       13.1388889     12.30400      1.9098106  1.6110816
## stress    5.063232        0.4551389     -0.01696      0.8228946  0.9357527
## thrillsk -5.316423       -0.4070833      0.14096      0.9514440  1.0345495
## impulsve -6.544847       -0.5913889      0.05248      0.9428625  0.9873108
##               p.value
## vocab    6.830358e-18
## sentcomp 1.768872e-15
## reading  1.863829e-15
## mathmtcs 1.217504e-12
## analyrea 1.576338e-11
## geometry 6.767543e-10
## worry    4.354809e-08
## educ     1.984721e-07
## stress   4.122084e-07
## thrillsk 1.058269e-07
## impulsve 5.955652e-11
#Synthèse:
fviz_cluster(hc, data = interest[1:15],
             main = "Clustering Plot",
             axes=c(1,2), 
            # ellipse.type = "norm",
             repel=F,
             pointsize = 0.5,labelsize = 0)+
  annotate("label", x = 1, y = -0.5, label = "Fort aux tests, n'aime pas le risque", size=2.5) + annotate("label", x = 1, y = -1, label = "anxieux, plus d'études, sociable NS", size=2.5)

Des individus dans des clusters distincts peuvent-ils avoir des points communs ?

Graphique des individus partiels

Tuto Husson : https://youtu.be/wCTaFaVKGAM?t=1653 Tuto Husson : https://youtu.be/miCPrUe7Yq8?t=664 Tuto Husson : https://youtu.be/g0lM2qQ4lvs?t=483

  • On peut identifier des individus classés dans des groupes différents et comparer leurs scores respectifs sur un graphique.
  • Chaque individu est situé au barycentre de ses scores par famille de variables.
  • Les scores par famille de variables sont situés au bout des droites qui partent de ce barycentre.

Prenons deux individus situés au même endroit en dimension 1 mais de part et d’autre de la dimension 2 (202 et 243). Le graphique des individus partiels va mettre en regard leur point commun (bons résultats aux tests ling. et math) : les droites de chaque individus convergent vers les valeurs hautes de la dimension 1. Ils sont cependant très différents du point de vue du caractère : 202 est très sociable alors que 243 est moins sociable et très anxieux.

fviz_mfa_ind(res, partial = c(202, 243, 111), alpha=0.1,pointsize=0.5, labelsize=3, repel=T)
## Warning: ggrepel: 240 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

Vérification des scores pour chaque individu :

interest[c(111,202,243),c(1:15)]
##     gender educ age vocab reading sentcomp mathmtcs geometry analyrea socdom
## 111      H    8  45 -2.01   -2.47    -2.47    -3.71    -2.59    -2.67  -0.90
## 202      H   16  29  2.63    2.23     2.55     1.38     3.86     3.50   2.47
## 243      F   12  32  2.10    2.64     1.52     3.06     2.60     2.35   0.82
##     sociabty stress worry impulsve thrillsk
## 111    -0.93  -0.25  0.07     2.62     1.56
## 202     2.50  -0.68 -1.42     0.91     2.12
## 243     0.00   1.17  1.73    -0.38     0.50

Encore plus de diagnostiques !

Liste des diagnostiques disponibles dans l’AFM

res # taper le nom du vecteur dans lequel sont stockés les résultats de l'analyse.
## **Results of the Multiple Factor Analysis (MFA)**
## The analysis was performed on 250 individuals, described by 15 variables
## *Results are available in the following objects :
## 
##    name                 description                                           
## 1  "$eig"               "eigenvalues"                                         
## 2  "$separate.analyses" "separate analyses for each group of variables"       
## 3  "$group"             "results for all the groups"                          
## 4  "$partial.axes"      "results for the partial axes"                        
## 5  "$inertia.ratio"     "inertia ratio"                                       
## 6  "$ind"               "results for the individuals"                         
## 7  "$quanti.var"        "results for the quantitative variables"              
## 8  "$quanti.var.sup"    "results for the quantitative supplementary variables"
## 9  "$quali.var.sup"     "results for the categorical supplementary variables" 
## 10 "$summary.quanti"    "summary for the quantitative variables"              
## 11 "$summary.quali"     "summary for the categorical variables"               
## 12 "$global.pca"        "results for the global PCA"

Quels groupes sont les plus discriminants au sein des dim 1 et 2

plot(res, choix = "axes")

Pour les 3 premières dimensions, quels groupes de variables permettent de distinguer les individus ? / Que représentent les axes

Dim 1: si on a été bon (+) au test ou non (-).

library(factoextra)
fviz_contrib(res, choice = "group", axes = 1, top = 10)

Dim 2: si on est impulsif (+) anxieux (-).

fviz_contrib(res, choice = "group", axes = 2, top = 10)

Dim 3: si l’on est sociable (+) si l’on est anxieux (-)

fviz_contrib(res, choice = "group", axes = 3, top = 10)

Quels autres diagnostiques puis-je avoir sur l’analyse en cluster

hc # taper le nom du vecteur dans lequel sont stockés les résultats de l'analyse.
## **Results for the Hierarchical Clustering on Principal Components**
##    name                   
## 1  "$data.clust"          
## 2  "$desc.var"            
## 3  "$desc.var$quanti.var" 
## 4  "$desc.var$quanti"     
## 5  "$desc.axes"           
## 6  "$desc.axes$quanti.var"
## 7  "$desc.axes$quanti"    
## 8  "$desc.ind"            
## 9  "$desc.ind$para"       
## 10 "$desc.ind$dist"       
## 11 "$call"                
## 12 "$call$t"              
##    description                                             
## 1  "dataset with the cluster of the individuals"           
## 2  "description of the clusters by the variables"          
## 3  "description of the cluster var. by the continuous var."
## 4  "description of the clusters by the continuous var."    
## 5  "description of the clusters by the dimensions"         
## 6  "description of the cluster var. by the axes"           
## 7  "description of the clusters by the axes"               
## 8  "description of the clusters by the individuals"        
## 9  "parangons of each clusters"                            
## 10 "specific individuals"                                  
## 11 "summary statistics"                                    
## 12 "description of the tree"

Quelles dimensions sont significativement liées à au moins un cluster?

Les dimensions 1 à 3 sont liées à la création d’au moins un cluster cluster 1 et 2 : dim 1 et 2 cluster 3 : dim 1, 2, 3 => variation plus complexe ?

Tuto F. Husson : https://youtu.be/6AqPc_kZQ0g?t=739

hc$desc.axes
## 
## Link between the cluster variable and the quantitative variables
## ================================================================
##             Eta2      P-value
## Dim.1 0.59641433 2.153094e-49
## Dim.2 0.50880305 7.414374e-39
## Dim.3 0.03147584 1.925936e-02
## 
## Description of each cluster by quantitative variables
## =====================================================
## $`1`
##           v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2  -3.736229       -0.2994481  1.081080e-17      0.7771222   1.067402
## Dim.1 -11.679339       -1.1811511 -3.663736e-17      0.8993907   1.346874
##            p.value
## Dim.2 1.868009e-04
## Dim.1 1.625549e-31
## 
## $`2`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2 10.931164        1.1403425  1.081080e-17      0.7000404   1.067402
## Dim.1  3.480337        0.4581305 -3.663736e-17      0.8552737   1.346874
##            p.value
## Dim.2 8.179224e-28
## Dim.1 5.007837e-04
## 
## $`3`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1  9.204156        1.2352508 -3.663736e-17      0.7886062  1.3468745
## Dim.3  2.782159        0.2702827  1.496026e-17      0.9335627  0.9749721
## Dim.2 -6.952736       -0.7394825  1.081080e-17      0.7531347  1.0674022
##            p.value
## Dim.1 3.443680e-20
## Dim.3 5.399856e-03
## Dim.2 3.582696e-12

Si je devais résumer mes groupes grâce à 3 variables, lesquelles choisir ?

Tuto F. Husson : https://youtu.be/6AqPc_kZQ0g?t=599

hc$desc.var$quanti.var
##                Eta2      P-value
## vocab    0.53131186 2.260320e-41
## sentcomp 0.45222467 5.216812e-33
## reading  0.43630696 1.793785e-31
## mathmtcs 0.40184547 2.731834e-28
## analyrea 0.37884744 2.883948e-26
## geometry 0.29880869 9.137148e-20
## worry    0.27054994 1.202132e-17
## stress   0.21846156 6.016826e-14
## impulsve 0.19221415 3.557015e-12
## thrillsk 0.17598841 4.147297e-11
## educ     0.16144335 3.599587e-10
## sociabty 0.11947787 1.497697e-07
## socdom   0.10657869 9.025145e-07
## age      0.04806836 2.279354e-03

Quels sont les 5 individus les plus atypiques ? (dont la variation est la plus distante du barycentre des autres groupes

Etude des parangons Tuto Husson : https://youtu.be/6AqPc_kZQ0g?t=823

hc$desc.ind$para
## Cluster: 1
##       215       162       195        50       224 
## 0.5718232 0.6363363 0.8722314 0.8724501 0.8822210 
## ------------------------------------------------------------ 
## Cluster: 2
##       191       239        95       120         8 
## 0.7217699 0.7476107 0.7797455 0.7847797 0.8177736 
## ------------------------------------------------------------ 
## Cluster: 3
##       209       184       219       140       107 
## 0.8057050 0.8635835 0.9172002 1.0682234 1.0911210

Quels sont les 5 individus les plus représentatifs de chaque groupe ? (dont la variation est la plus distante de celle des autres groupes)

Etude de la spécificité Tuto Husson : https://youtu.be/6AqPc_kZQ0g?t=860

hc$desc.ind$dist
## Cluster: 1
##      111      227       69       52       90 
## 5.263764 4.688660 4.490841 4.453420 4.226787 
## ------------------------------------------------------------ 
## Cluster: 2
##      202       56       92       96      190 
## 4.818188 4.125359 3.778871 3.682296 3.534990 
## ------------------------------------------------------------ 
## Cluster: 3
##       32      243      113      210      217 
## 4.076258 3.992306 3.925148 3.764718 3.679051

Liens utiles:

** Jeux de données François Husson ** https://husson.github.io/data.html

** Tuto @ mate par François Husson ** https://youtu.be/OGG2Aeg0IN0

** Tuto @ mate par François Husson, section: AFM ** https://youtu.be/OGG2Aeg0IN0?t=2428

** Tuto @ mate par François Husson, section : analyse de données textuelles (typologie d’auteurs français sur la base de fréquences lexicales) ** https://youtu.be/OGG2Aeg0IN0?t=5417

** Références bibliographiques (par ordre de pertinence) **

Manuels

Pagès 2013, analyse factorielle multiple avec R http://math.agrocampus-ouest.fr/infoglueDeliverLive/enseignement/support2cours/livres/AFM

Escofier & Pagès 2008, analyses factorielles simples et mutiples https://univ-scholarvox-com.ezproxy.u-paris.fr/catalog/book/docid/45001767

Lebart & Salem 1994, la statistique textes et les analyses factorielles. https://issuu.com/sfleury/docs/st-1994-lebart_salem

Publications de recherche

Ecole française de l’analyse multivariée : https://arxiv.org/pdf/0805.2879.pdf https://www.jstatsoft.org/article/view/v073i06/v73i06.pdf

Application à l’écologie : https://www.kmae-journal.org/articles/kmae/pdf/1990/03/kmae199031806.pdf

Plus de publications par l’Agro Campus : http://math.agrocampus-ouest.fr/infoglueDeliverLive/recherche/publications/articles

Application à la sociolinguistique : Amand 2019 http://www.theses.fr/2019UNIP7040

Analyses factorielles en sociologie : https://www.cairn.info/analyse-factorielle-simple-en-sociologie–9782804102180-page-1.htm

Tutoriels R AFM avec FactoMineR http://www.sthda.com/french/articles/38-methodes-des-composantes-principales-dans-r-guide-pratique/77-afm-analyse-factorielle-multiple-avec-r-l-essentiel/

https://cran.r-project.org/web/packages/FactoMineR/FactoMineR.pdf

factoextra (visualisation) http://www.sthda.com/english/wiki/factoextra-r-package-easy-multivariate-data-analyses-and-elegant-visualization

https://cran.r-project.org/web/packages/factoextra/factoextra.pdf