Soit un tableau $\mathbf{N}$ qui croise un ensemble d'individus $\{i\}_{i=1}^I$ et un ensemble de variables $\{j\}_{j=1}^Q$. Chaque individu $\mathbf{n_i}$ est décrit par $Q$ valeurs : $n_{i,1},\dots,n_{i,Q}$.
Nous considérons la situation où chaque variable $j$ est catégorielle. Mettons que la variable $j_1$ ait 2 modalités, la variable $j_2$ ait 3 modalités,\dots, la variable $j_Q$ ait 2 modalités. Notons $J$ le nombre total de modalités toutes variables confondues. Nous constuisons le tableau binaire $\mathbf{Z}$, nommé \emph{tableau disjonctif complet}.
Nous construisons la \emph{matrice de Burt} $\mathbf{C} = \mathbf{Z}^T\mathbf{Z}$. C'est une matrice $J \times J$ symétrique. Les blocs diagonaux sont les histogrammes de chaque variable catégorielle. Les autres blocs sont les tables de contingence entre paires de variables catégorielles. Prenons un petit exemple numérique pour fixer les idées. Nous partons d'un tableau disjonctif complet $\mathbf{Z}$, voir Table \@ref(tab:05-d-mat-Z), puis nous calculons la matrice de Burt $\mathbf{B}$, voir Table \@ref(tab:05-d-mat-B).
L'analyse des correspondances du tableau disjonctif complet $\mathbf{Z}$ ou l'analyse des correspondances de la matrice de Burt $\mathbf{B}$ sont très proches. Les deux analyses diffèrent en ceci que :
* L'analyse de $\mathbf{B}$ ne donne des résultats que pour les catégories (les individus n'apparaissent plus).
* Pour chaque facteur principal, l'inertie associée par l'analyse de $\mathbf{B}$ est le carré de celle associée par l'analyse de $\mathbf{Z}$.
* $\mathbf{B}$ étant une matrice symétrique définie positive, la décomposition en valeurs singulières est identique à une décomposition en valeurs propres.
Le passage par la matrice de Burt ne permet pas de trouver directement les coordonnées principales des individus (seulement celles des variables). Cependant, nous pouvons a posteriori associer à chaque individu ses coordonnées principales. Pour ce faire, il faut utiliser les formules de transition (voir section \@ref(c-05-c-transition-formula)) qui permettent d'exprimer les coordonnées principales d'un profil ligne supplémentaire (noté $f^*_{is,k}$) comme barycentre des coordonnées standards des profils colonnes pondérés par le profil ligne supplémentaire. Nous notons $b^*_{is,j}$ la représentation de la $j$-ème composante de l'individu supplémentaire $is$ comme ligne supplémentaire du tableau disjonctif complet. La $j$-ème composante du profil ligne de cet individu supplémentaire est : $\frac{b^*_{is,j}}{b^*_{is,+}}$ (où $b^*_{is,+}$ signifie la somme des éléments de la ligne supplémentaire $\mathbf{b^*_{is}}$ au tableau disjonctif complet).
Sur notre exemple jouet de la Table \@ref(tab:05-d-mat-Z), considérons le premier individu : $\mathbf{b^*_1} = [0,1,0,1,0,0,1]^T$. Nous le notons $\mathbf{b^*_1}$ car nous faisons comme si nous l'ajoutions comme ligne supplémentaire au tableau de Burt $\mathbf{B}$ de la Table \@ref(tab:05-d-mat-B). D'après les formules de transition, nous avons :
Pour gérer des variables supplémentaires, il suffit de faire la tabulation croisée des nouvelles variables avec les variables actives (c'est-à-dire celles qui ont été utilisées pour calculer les axes factoriels). Notons $\mathbf{Z^*}$ le tableau disjonctif complet des variables supplémentaires (voir Table \@ref(tab:05-d-mat-Z-sup)). Alors, $\mathbf{B^*} \triangleq \mathbf{Z^{*T}}\mathbf{Z}$ produit de nouvelles lignes de la matrice de Burt qui correspondent aux variables supplémentaires. Par les formules de transition, les coordonnées principales de la $s$-ème variable supplémentaire sont :
Sur notre exemple jouet, mettons que nous ajoutions une variable supplémentaire $js$ à trois modalités dont le codage disjonctif complet est donné par la Table \@ref(tab:05-d-mat-Z-sup).
`housing` est un jeu de données célèbre aux nombreuses vertues pédagogiques^[https://www.kaggle.com/datasets/harrywang/housing]. Il permet d'expérimenter sur un problème de régression réaliste, viz. prédire la valeur médiane d'une maison en fonction des caractéristiques de son quartier. Nous allons faire une analyse exploratoire de ce jeu de données par analyse des correspondances.
```{r}
dat <- read.csv(file="data/housing.csv", header=TRUE)
str(dat)
```
## Analyse individuelle des variables et discrétisation
Nous analysons chaque variable du jeu de données. Nous proposons également une discrétisation de chaque variable afin de mener dans un second une analyse des correspondances.
### Proximité de l'océan
La variable `ocean_proximity` est du type `chr`. C'est en fait une variable catégorielle avec des modalités comme "NEAR BAY", "NEAR OCEAN", etc. Nous la transformons explicitement en variable catégorielle, aussi appelée \emph{facteur} dans le langage R.
La distribution des longitudes apparait comme étant bi-modale, avec un premier pic autour de -122°, près de la côte ouest, et un second pic autour de -118°, plus dans les terres.
```{r}
hist(dat$longitude)
```
Nous pouvons découper la longitude en, par exemple, 4 intervalles d'égales densités.
Alternativement, nous pouvons adopter une approche par clustering pour découper la variable en intervalles.
```{r}
cuts <- kcuts(x = dat$longitude, centers = 4)
cuts
```
```{r}
hist(dat$longitude)
abline(v=cuts, lwd=4)
```
Nous proposons de discrétiser les longitudes en une nouvelle variable catégorielle `c_longitude` avec pour modalités `LO-W` (West), `LO-M` (Mid-West), `LO-ME` (Mid-East), `LO-E` (East).
Analyser des données peut être vu comme initier un dialogue avec elles et les laisser nous guider vers un modèle. C'est un processus itératif. Par exemple, nous venons, en première intention, de tester un découpage des longitudes en quatre modalités obtenues par l'application d'un algorithme de classification par moyennes mobiles (k-means). Nous pourrions, plus tard, revenir sur ce choix.
### Latitude
Nous procédons similairement pour les latitudes. Nous les discrétisons en une nouvelle variable catégorielle nommée `c_latitude` avec pour modalités `LA-S` (South), `LA-MS` (Mid-South), `LA-MN` (Mid-North) and `LA-N` (North).
L'histogramme de la variable `housing_median_age` parait unimodal.
```{r}
hist(dat$housing_median_age)
```
Les valeurs supérieures à 50 semblent étonnamment nombreuses. Nous comptons les valeurs différentes supérieures à 45 pour mieux comprendre ce phénomène.
Une limite semble avoir été fixée à la valeur 52. Elle apparait clairement sur un histogramme avec plus d'intervalles. Ce phénomène pourrait avoir un impact sur les analyses à venir.
`r pc_age_52`% des observations ont un âge médian des habitations égal à 52. C'est sans doute suffisant pour qu'il soit intéressant de les regrouper dans une catégorie à part.
Nous sommes guidés par l'analyse des quantiles pour discrétiser cette variable en une nouvelle variable catégorielle nommée `c_age` avec des modalités dont les frontières correspondent à des nombres entiers faciles à saisir.
Sur l'histogramme de la variable `total_rooms`, nous observons des valeurs élevées peu fréquentes (l'histogramme est dit à longue queue). Par ailleurs, les valeurs, qui s'étendent de `r min(dat$total_rooms)` à `r format(max(dat$total_rooms), scientific = FALSE)`, sont difficiles à interpréter puisqu'elles dépendent du nombre de foyers.
```{r}
cuts <- quantile(dat$total_rooms)
hist(dat$total_rooms)
abline(v=cuts, lwd=3)
```
Nous créons une nouvelle variable `rooms` pour compter le nombre relatif de pièces par foyers.
Nous sommes guidés par l'analyse des quantiles pour discrétiser cette variable en une nouvelle variable catégorielle nommée `c_rooms` avec pour modalités : `R<=4` moins de 4 pièces, `R(4,6]` entre 4 et 6 pièces, `R(6,8]` entre 6 et 8 pièces, `R>8` plus de 8 pièces. Nous ajoutons cette dernière catégorie, `R>8`, pour prendre en compte la longue queue de la distribution : seulement `r pc_rooms_gt_8`% des observations appartiennent à cette catégorie.
Pour mieux visualiser les coupures, nous affichons un histogramme après une transformation logarithmique des nombres de pièces.
Comme pour les pièces, nous créons une nouvelle variable `bedrooms` pour compter le nombre relatif de chambres par foyers. Nous remarquons par ailleurs que cette variable possède des valeurs manquantes indiquées par le symbole `NA`. Nous devons demander à certaines fonctions du langage R d'ignorer les valeurs manquantes. Pour ce faire, nous fixons le paramètre `na.rm` à `TRUE`.
Nous sommes guidés par l'analyse des quantiles pour discrétiser cette variable en une nouvelle variable catégorielle nommée `c_bedrooms` avec pour modalités : `B<=1` 1 chambre ou moins, `B>1` plus de 1 chambre .
Comme pour les variables comptant les pièces et les chambres, nous créons une nouvelle variable `pop` pour compter le nombre de personnes par foyers.
```{r}
dat$pop <- dat$population / dat$households
quantile(dat$pop, probs = seq(0,1,1/4))
```
Nous sommes guidés par l'analyse des quantiles pour discrétiser cette variable en une nouvelle variable catégorielle nommée `c_pop` avec pour modalités : `P<=2`, `P(2,3]`, `P(3,4]` et `P>4`.
Après une analyse des quantiles, nous créons une variable catégorielle `c_households` avec pour modalités : moins de 300, entre 300 et 400, entre 400 et 600, plus de 600.
Nous pouvons compter le nombre de valeurs distinctes supérieures à 14 pour mieux mesurer ce phénomène.
```{r}
table(dat$median_income[dat$median_income>14])
```
Nous observons une limite, sans doute artificielle, pour les revenus plus grand que 15. Elle apparait clairement sur un histogramme aux intervalles plus fins. Ce phénomène pourrait impacter les analyses à venir.
Seules `r pc_income_gt_15`% des observations correspondent à un revenu médian supérieur à 15. Nous les isolons cependant dans une catégorie à part, elle pourrait nous être utile plus tard.
## Analyse des correspondances du jeu de données `housing`
### Ventilation des petites modalités
Nous commençons par ventiler les modalités avec de trop petits effectifs, c'est-à-dire que nous les répartissons aléatoirement parmi les autres modalités.
```{r}
dat.all <- dat
dat <- dat.all[c('ocean_proximity', 'c_longitude', 'c_latitude', 'c_age',
Nous considérons `c_house_value` comme variable supplémentaire. C'est-à-dire, comme nous l'avons vu au début de ce chapitre, qu'elle ne doit pas influencer le calcul des facteurs.
Nous reprenons dans une fonction `datasetHousing.mca` (voir code source en annexe de ce chapitre) toutes les transformations opérées sur le jeu de données.
La fonction `mca` (voir code source en annexe de ce chapitre) reprend la méthode introduite en début de chapitre pour calculer l'analyse des correpondances du tableau disjonctif complet.
Observons les corrélations des modalités supplémentaires (i.e., valeurs des habitations) avec les axes factoriels (voir Table \@ref(tab:05-d-mat-cor-sup)).
```{r 05-d-mat-cor-sup}
kbl( round_preserve_sum(1000 * cam$sjcor)[,1:7],
caption = "Corrélations des modalités supplémentaires avec les axes factoriels",
booktabs = TRUE ) %>%
kable_styling(latex_options = "striped")
```
Créons une carte des deux premiers axes factoriels en ajoutant la représentation des modalités supplémentaires (voir Figure \@ref(fig:05-d-map-1-2-jsup))
```{r 05-d-map-1-2-jsup, fig.width = 7, fig.cap = "Carte selon les facteurs 1 (x) et 2 (y) avec modalités supplémentaires"}
plotjsup.mca(cam)
```
### Clustering des individus
Calculons les corrélations des clusters d'individus avec les différents axes factoriels (voir Tables \@ref(tab:05-d-clust-cor-1-33), \@ref(tab:05-d-clust-cor-34-66) et \@ref(tab:05-d-clust-cor-67-100)).
```{r}
clstcor <- clstcor.mca(cam)
```
```{r 05-d-clust-cor-1-33}
kbl( clstcor[1:33,],
caption = "Corrélations des clusters d'individus avec les axes factoriels (1/3)",
booktabs = TRUE ) %>%
kable_styling(latex_options = "striped")
```
```{r 05-d-clust-cor-34-66}
kbl( clstcor[34:66,],
caption = "Corrélations des clusters d'individus avec les axes factoriels (2/3)",
booktabs = TRUE ) %>%
kable_styling(latex_options = "striped")
```
```{r 05-d-clust-cor-67-100}
kbl( clstcor[67:100,],
caption = "Corrélations des clusters d'individus avec les axes factoriels (3/3)",
booktabs = TRUE ) %>%
kable_styling(latex_options = "striped")
```
Créons une carte des deux premiers axes factoriels en ajoutant la représentation des clusters d'individus (voir Figure \@ref(fig:05-d-map-1-2-tot))
```{r 05-d-map-1-2-tot, fig.width = 7, fig.cap = "Carte selon les facteurs 1 (x) et 2 (y) avec modalités supplémentaires et clusters d'individus"}
plotisupjsup.mca(cam)
```
Observons par exemple un diagramme en bâtons de la variable catégorielle supplémentaire `c_house_value` pour les individus du cluster 8 (voir Figure \@ref(fig:05-d-bar-clst-8-c-house-value)).
```{r 05-d-bar-clst-8-c-house-value, fig.width = 7, fig.cap = "Barplot de house value pour le cluster 8"}