Pré-partition par algorithme des kmeans avant CAH: sous quel format renseigner les "centers" dans la fonction HCPC ?

49 views
Skip to first unread message

Marie H

unread,
Jun 13, 2024, 8:26:52 AMJun 13
to FactoMineR users
Bonjour,

Je me tourne vers ce groupe après avoir échangé avec vous sur le forum du MOOC "Analyse des données multidimensionnelles" (sous l'intitulé "particularités du traitement de gros jeux de données"). Ma question est dans la continuité de celles que je vous ai précédemment posées:

Je traite un gros jeu de données (plus de 300 000 individus) par AFDM avec 8 variables actives, avec pour objectif de réaliser une classification de mes individus à partir du résultat.

Comme j'ai trop d'individus pour utiliser HCPC directement, j'ai commencé par utiliser l'argument kk. Toutefois, la taille des clusters que j'obtenais variait beaucoup d'une itération à l'autre, alors qu'il faudrait que j'ai des résultats un miminum reproductibles (bien que j'ai entièrement conscience que par définition l'utilisation de l'algorithme des kmeans implique qu'ils ne le seront jamais totalement).

J'ai ainsi fait le choix d'utiliser la fonction kmeans séparément, dans l'idée d'exporter les coordonnées de mes centres (sur 5 dimensions) en format csv, pour ensuite pouvoir les importer et utiliser en entrée de la fonction HCPC (sous la forme d'un dataframe donc). 

Hors, le nuage des individus que j'obtiens au final en sortie de la CAH (plot avec choice = "map") est totalement différent de celui des mes barycentres obtenu suite à la fonction kmeans.

Je me demandais ainsi: pourquoi ? HCPC réalise-t-elle une ACP sur mes coordonnées ? Et est-ce que ça ne viendrait pas du format sous lequel je fournis les coordonnées de mes barycentres à HCPC ? J'ai pourtant vu dans la documentation que la fonction HCPC pouvait prendre en argument le résultat d'une analyse factorielle OU un dataframe.
Et enfin, comment finalement réaliser une CAH avec HCPC sur les coordonnées de mes barycentres ? (qui seront sous la forme d'un dataframe au départ, avec donc 5 colonnes Dim.1, Dim.2 etc) 

C'est important pour moi d'avoir mes résultats de l'algorithme des kmeans "en dur", sur un fichier séparé, pour ensuite avoir un bout de script reproductible (la CAH à partir des barycentres). J'ai en effet vu des bouts de scripts en ligne utilisant directement "res.kmeans$centers" (par exemple ici), mais ce ne serait donc pas une option ici.

Merci d'avance ! N'hésitez pas à me dire si quelque chose n'est pas clair et je reformulerai.

Bien cordialement,
Marie Hermès

François Husson

unread,
Jun 13, 2024, 9:29:22 AMJun 13
to factomin...@googlegroups.com
Bonjour,

L'argument kk de HCPC lance une fonction k-means. Donc il y a de l'instabilité, mais cela est liée à la méthode, et non à la fonction. Donc si vous refaites vous-même un k-means, vous aurez la même instabilité. L'avantage d'utiliser l'argument kk est que les classes sont pondérées directement par l'effectif de la classe dans la suite de l'analyse. Tandis que si vous le faites vous-même, vous aurez à gérer ces poids car chaque centre de classe n'est pas lié au même effectif.
Sinon, pour l'instabilité, elle est présente quand vous faites votre k-means, mais une fois la classification hiérarchique faite, le haut de l'arbre est généralement stable (il faut prendre pour kk une valeur relativement élevée, kk=100 par exemple).

HCPC ne fait pas d'ACP pour faire les classes ou l'arbre, seulement pour représenter éventuellement les classes sur un plan d'ACP.

FH
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "FactoMineR users".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse factominer-use...@googlegroups.com.
Cette discussion peut être lue sur le Web à l'adresse https://groups.google.com/d/msgid/factominer-users/cbdc44ea-6a12-437a-b324-c492bfaee5d1n%40googlegroups.com.

--
François Husson
Department Statistics & Computer Science
L'Institut Agro
65 rue de St-Brieuc - 35042 Rennes
Tel: +33 2 23 48 58 86
https://husson.github.io/
https://www.youtube.com/@HussonFrancois/videos
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Marie H

unread,
Jun 21, 2024, 6:12:11 AMJun 21
to FactoMineR users

Bonjour,

Je vous remercie d’avoir pris le temps de répondre à mes questions !

Je me permets de vous joindre cette fois des illustrations du problème auquel je suis confrontée, qui seront peut-être plus parlantes, ainsi que le passage de script en question en fin de mail.

Pour l’utilisation de l’argument kk, je suis toujours gênée par le fait de ne pas pouvoir avoir de « bout » de script qui soit reproductible. Ci-dessous à titre d’exemple les effectifs de classes que j’obtiens avec 3 itérations (typokk1, typokk2 et typokk3) de la fonction HCPC, argument kk = 1000 :

tableau_effectifs_kktypo123.png

J’ai bien conscience du fait que les n° de clusters peuvent changer d’une itération à l’autre, mais il y a ici par exemple une différence de 68 422 individus entre les clusters ayant le plus d’individus des typokk1 et 3. Cela me semble être trop (pour rappel, j’ai environ 400 000 individus au total), alors que vous insistiez dans un précédent message sur l’interprétabilité des classes qui primait sur le reste. Le nombre de clusters suggérés et le diagramme des gains d’inertie changent aussi beaucoup d’une itération à l’autre. Comment alors s’arrêter à une itération en se disant que c’est la bonne ? A titre d'illustration, les arbres obtenus à l'issue des 3 classifications (le découpage en 8 classes est basé sur la typo du milieu):

arbre_typokk1.pngarbre_typokk2.pngarbre_typokk3.png

Un dernier élément m’interpelle dans cet essai : le plan factoriel des individus avec coloration par cluster semble ne pas présenter de lien logique et ainsi ne pas découler d’une CAH (même pour l'essai "bien découpé", en illustration ci-dessous). Quelle est l’origine de cette apparence ?

plan_typokk2.png

Utiliser la fonction kmeans séparément me semblait ainsi être un bon compromis, parce qu’elle me permettait :

  • D'augmenter le nombre d’itérations de l’algorithme et de positions de départ des barycentres différentes (avec l’argument nstart), en faisant l’hypothèse que la position des barycentres serait ainsi plus stable. J’ai cru comprendre qu’il y avait 5 itérations avec l’argument kk dans HCPC (nombre de fois où le message d’avertissement « les étapes de quick-transfer ont dépassé le maximum » s’affiche), je ne sais pas pour le nombre de positions de départ différentes des barycentres.
  • D’exporter un fichier csv des coordonnées des 1000 barycentres sur les 5 dimensions conservées de l’AFDM (et d’ainsi obtenir toujours les mêmes classes une fois que je lance HCPC à partir de ce fichier).

Toutefois, je ne comprends pas pourquoi le plan factoriel (avec les positions des individus) dans lequel sont colorés les clusters en sortie d’HCPC ne correspond pas à celui obtenu en sortie de kmeans, et ne présente pas non plus de ressemblance avec celui obtenu en sortie d’AFDM. Ci-dessous les 3 nuages de points :

individus_typo7.pngbarycentres_kmeans_1000_100iter_100nstart_typo7.pngplan_typo7_13types.png

1. individus de l'AFDM sur les 2 premiers axes   2. 1000 barycentres obtenus par k-means     3. plan factoriel en sortie d'HCPC

Je me demandais également quelle était l’origine de l’inertie affichée sur les axes en sortie d’HCPC ? Quand vous parlez de « représenter éventuellement les classes sur un plan d'ACP », sur quoi cette dernière est-elle réalisée, et pourquoi ?

Il me semble enfin avoir déjà vu des précédents d’utilisation des centres kmeans dans HCPC sans les pondérer. Ainsi:

  • En quoi cela pose-t-il précisément problème ?
  • Comment effectueriez-vous cette pondération ?
Encore merci ! C’est une immense chance de pouvoir ainsi échanger avec la personne à l’origine de ces outils (et le reste des utilisateurs !).

Bien cordialement,

Marie H

Les extraits de code concernés:

  • res = FAMD(tabAFDM, sup.var = 1:7, graph = FALSE)
  • kktypo = kmeans(res$ind$coord, 1000, iter.max = 100, nstart = 100)
  • tabexport_kmeans = cbind(exp20typo[exp20typo$NOM_DOSSIER != *******,], data.frame(res$ind$coord))
  • tabexport_kmeans$cluster.kmeans = kktypo$cluster
  • write.csv2(tabexport_kmeans, "clusters_kmeans_typo7.csv", row.names = FALSE)
  • write.csv(data.frame(kktypo$centers), "centers_kmeans_typo7.csv", row.names = FALSE)
  • centers = fread("centers_kmeans_typo7.csv")
  • typo = HCPC(centers, nb.clust = 13, description = FALSE, graph = FALSE)

Serge Heiden

unread,
Jun 21, 2024, 7:18:35 AMJun 21
to factomin...@googlegroups.com

Bonjour,

Vous dites dans la réponse ci-dessous que la méthode HCPC n'utilise pas le résultat d'une ACP pour calculer son arborescence :

Le 13/06/2024 à 15:29, François Husson a écrit :
...

HCPC ne fait pas d'ACP pour faire les classes ou l'arbre, seulement pour représenter éventuellement les classes sur un plan d'ACP.

Et dans cette vidéo d'introduction à la Classification Ascendante Hiérarchique datant du 17 avr. 2013 vous dites ceci  :

3:59    ... je vais faire la
4:01    classification en utilisant uniquement
4:03    les cinq premières composantes de la CP
4:05    donc je [ne] vais pas utiliser l'ensemble des
4:07    données mais uniquement les cinq
4:09    premières composantes alors si je veux
4:10    utiliser l'ensemble des composantes de
4:12    l'ACP et bien dans la fonction PCA il
4:15    faut que je précise l'argument NCP =
4:19    inf alors ça peut être intéressant de ne
4:22    pas utiliser toutes les composantes de
4:23    la CP parce que bien justement les
4:25    dernières composantes on peut considérer
4:27    bien souvent que c'est du bruit et donc
4:30    d'enlever ces dernières composantes va
4:31    permettre de stabiliser les résultats

https://www.youtube.com/watch?v=3tT29UtHqd0
17 avr. 2013  Classification Ascendante Hiérarchique

Ce qui pour moi exprime le contraire.

Est-ce que le code d'HCPC a changé sur cet aspect entre 2013 et 2024 ?

Cordialement,
Serge Heiden

François Husson

unread,
Jun 21, 2024, 7:22:09 AMJun 21
to factomin...@googlegroups.com
Bonjour,

Si vous utilisez HCPC directement sur un jeu de données, alors la classification est faite sur le jeu de données, et pas sur les composantes de l'ACP. Si vous faites une ACP avant, alors vous pouvez choisir un nombre de dimensions à conserver pour la classification (rq : en prenant toutes les dimensions, on retrouve les données brutes).
Donc je confirme ce que je vous ai dit. Il n'y a pas de contradiction entre les 2 choses que j'ai dites.

Et le code HCPC n'a pas changé, en tout cas pas sur ce point, entre 2013 et 2024.

FH
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "FactoMineR users".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse factominer-use...@googlegroups.com.

François Husson

unread,
Jun 21, 2024, 8:42:16 AMJun 21
to factomin...@googlegroups.com
Bonjour,

Pour avoir un script reproductible, il suffit d'initialiser une graine de générateur du nombre au hasard. Ainsi la méthode Kmeans choisira les mêmes initialisations au hasard.
Donc juste avant d'utiliser HCPC avec l'argument kk, vous pouvez écrire :
set.seed(12345)

Vous avez vraiment beaucoup d'individus, et vous faites 8 classes. Donc il est plutôt normal que des individus changent de classes d'une simulation à l'autre. Au niveau de l'interprétabilité, vous devriez cependant trouver des choses à dire qui sont communes (en cherchant à interpréter les classes à partir des variables, par exemple : les individus de cette classe ont tendance à prendre de faibles valeurs pour telle et telle variables ...)

Comme je vous l'ai dit, si vous faites vous-même une partition avec kmeans et qu'ensuite vous faites une classification hiérarchique avec HCPC sur les centre de classes, il faut pondérer les centres de classes par leur effetctif. En effet, dans la distance utiliser pour faire la classification et avec le critère de Ward, le poids des classes joue sur la classification (le poids des classes joue dans le critère de Ward qui a tendance à agréger des classes de plus faible effectif pour éviter de construire une classification avec plein de petites classes). Donc il vous faut utiliser les poids après avec utiliser K-means.
Ensuite, si vous prenez seulement qq dimensions de l'AFDM, et que vous supprimez les dernières, alors vous modifier l'inertie totale du nuage de point, et donc les inerties qui sont conservées sur les dimensions après classification ne correspondent pas aux inerties d'origine. Tout cela est parfaitement géré dans la fonction HCPC (le poids, les inerties), et c'est pour cela que je vous conseille d'utiliser HCPC avec l'argument kk.

Cdt
FH


Le 20/06/2024 à 14:03, Marie H a écrit :

Bonjour,

Je vous remercie d’avoir pris le temps de répondre à mes questions !

Je me permets de vous joindre cette fois des illustrations du problème auquel je suis confrontée, qui seront peut-être plus parlantes, ainsi que le passage de script en question en fin de mail.

Pour l’utilisation de l’argument kk, je suis toujours gênée par le fait de ne pas pouvoir avoir de « bout » de script qui soit reproductible. Ci-dessous à titre d’exemple les effectifs de classes que j’obtiens avec 3 itérations (typokk1, typokk2 et typokk3) de la fonction HCPC, argument kk = 1000 :

tableau_effectifs_kktypo123.png

J’ai bien conscience du fait que les n° de clusters peuvent changer d’une itération à l’autre, mais il y a ici par exemple une différence de 68 422 individus entre les clusters ayant le plus d’individus des typokk1 et 3. Cela me semble être trop (pour rappel, j’ai environ 400 000 individus au total), alors que vous insistiez dans un précédent message sur l’interprétabilité des classes qui primait sur le reste. Le nombre de clusters suggérés et le diagramme des gains d’inertie changent aussi beaucoup d’une itération à l’autre. Comment alors s’arrêter à une itération en se disant que c’est la bonne ? A titre d’illustration, ci-dessous les arbres obtenus à l’issue des 3 itérations (le découpage en 8 classes est basé sur la 2ème illustration) :

arbre_typokk1.pngarbre_typokk2.pngarbre_typokk3.png

Un dernier élément m’interpelle dans cet essai : le plan factoriel des individus avec coloration par cluster semble ne pas présenter de lien logique et ainsi ne pas découler d’une CAH. Quelle est l’origine de cette apparence ? Illustration avec le plan factoriel issu du « bon découpage » :

plan_typokk2.png

Utiliser la fonction kmeans séparément me semblait ainsi être un bon compromis, parce qu’elle me permet :

  • D’augmenter le nombre d’itérations de l’algorithme et de positions de départ des barycentres différentes (avec l’argument nstart), en faisant l’hypothèse que la position des barycentres serait ainsi plus stable. J’ai cru comprendre qu’il y avait 5 itérations avec l’argument kk dans HCPC (nombre de fois où le message d’avertissement « les étapes de quick-transfer ont dépassé le maximum » s’affiche), et je ne sais pas pour le nombre de positions de départ différentes des barycentres.
  • D’exporter un fichier csv des coordonnées des 1000 barycentres sur les 5 dimensions conservées de l’AFDM (et d’ainsi obtenir toujours les mêmes classes une fois que je lance HCPC à partir de ce fichier).

Toutefois, je ne comprends pas pourquoi le plan factoriel (avec les positions des individus) dans lequel sont colorés les clusters en sortie d’HCPC ne correspond pas à celui obtenu en sortie de kmeans, et ne présente pas non plus de ressemblance avec celui obtenu en sortie d’AFDM. Ci-dessous les 3 nuages de points :

individus_typo7.pngbarycentres_kmeans_1000_100iter_100nstart_typo7.pngplan_typo7_13types.png

1. individus projetés par l'AFDM     2. 1000 barycentres issus des k-means   3. plan factoriel en sortie d'HCPC

Je me demandais également quelle était l’origine de l’inertie affichée sur les axes en sortie d’HCPC ? Quand vous parlez de « représenter éventuellement les classes sur un plan d'ACP », sur quoi cette dernière est-elle réalisée, et pourquoi ?

Il me semble enfin avoir déjà vu des précédents d’utilisation des centres kmeans dans HCPC sans les pondérer. Ainsi :

  • En quoi cela pose-t-il précisément problème ?
  • Comment effectueriez-vous cette pondération ?

Merci encore ! C’est une immense chance de pouvoir ainsi échanger avec la personne à l’origine de ces outils (et les autres utilisateurs !).

Bien cordialement,

Marie H

Les extraits de script en question :

    • res = FAMD(tabAFDM, sup.var = 1:7, graph = FALSE)
    • kktypo = kmeans(res$ind$coord, 1000, iter.max = 100, nstart = 100)
    • tabexport_kmeans = cbind(exp20typo[exp20typo$NOM_DOSSIER != *******,], data.frame(res$ind$coord))
    • tabexport_kmeans$cluster.kmeans = kktypo$cluster
    • write.csv2(tabexport_kmeans, "clusters_kmeans_typo7.csv", row.names = FALSE)
    • write.csv(data.frame(kktypo$centers), "centers_kmeans_typo7.csv", row.names = FALSE)
    • centers = fread("centers_kmeans_typo7.csv")
    • typo = HCPC(centers, nb.clust = 13, description = TRUE, graph = FALSE)

    Le jeudi 13 juin 2024 à 15:29:22 UTC+2, François Husson a écrit :

    Serge Heiden

    unread,
    Jun 21, 2024, 8:47:37 AMJun 21
    to factomin...@googlegroups.com

    Re-bonjour,

    Merci, c'est très clair : ça dépend du type de données fournies à HCPC (tableau ou ACP).

    Par contre, en ce qui concerne la remarque ("rq : en prenant toutes les dimensions, on retrouve les données brutes") dans le cas d'une AFC, confirmez vous que le cas de l'application HCPC(tableau) est différent de l'application HCPC(AFC(tableau)) en prenant toutes les dimensions car le nombre de dimensions factorielles disponibles est dans ce cas limité par le rang du tableau brut ? (même si le résultat ne doit pas être bien différent)

    --SLH

    François Husson

    unread,
    Jun 21, 2024, 9:31:00 AMJun 21
    to factomin...@googlegroups.com
    Si vous prenez toutes les dimensions de l'AFC, vous retombez bien sur l'inertie du tableau brut.
    FH

    Marie H

    unread,
    Jun 21, 2024, 12:02:41 PMJun 21
    to FactoMineR users
    Bonjour,

    Je vous remercie encore pour votre réponse ! Je vais réessayer en utilisant set.seed() !

    Pour l'interprétabilité c'est vrai, mais le plan factoriel avec des barycentres (obtenus avec l'argument kk) très éloignés (sur les 2 premiers axes) classés dans les mêmes clusters m'interpelle - à quoi cela est-il dû ? Au trop faible nombre de classes que vous mentionnez par rapport à l'instabilité des effectifs ? Ou alors les barycentres seraient proches sur les autres axes non représentés ?

    Par curiosité, et si vous avez encore la patience, comment seraient codés ces poids affectés aux barycentres ? J'avoue ne pas voir, et la fonction HCPC() ne contient par exemple pas l'argument row.w présent dans PCA().

    Je comprends maintenant pour les inerties, merci beaucoup ! Les coordonnées des individus sur les 2 premiers axes sont-elles ainsi différentes pour la même raison ?

    Bien à vous,
    Marie H

    François Husson

    unread,
    Jun 24, 2024, 3:50:49 AMJun 24
    to factomin...@googlegroups.com
    Bonjour,

    Pour les poids, vous pouvez regarder le code de la fonction HCPC. Lignes 127 et 128 vous voyez l'utilisation de kmeans puis d'une ACP avec des poids. Ensuite, on retrouve la fonction HCPC sur l'objet résultat de l'ACP :
            cla <- kmeans(res, centers=kk, iter.max = 100, nstart = 4)
            res <- PCA(cla$centers, row.w=cla$size, scale.unit = FALSE, ncp = Inf, graph = FALSE)

    Il est possible que 2 centres de gravité soient éloignés sur les 2 premiers axes et dans une même classe ensuite, mais c'est assez surprenant. Dans ce cas, ils sont certainement très proches sur les dimensions suivantes, et vous avez conservez beaucoup de dimensions pour faire votre classification.

    FH
    Reply all
    Reply to author
    Forward
    0 new messages