From ed0963fd1910424ecbe73ab70ca52c0c022e4d62 Mon Sep 17 00:00:00 2001 From: SUR Frederic <frederic.sur@univ-lorraine.fr> Date: Sun, 17 Nov 2024 20:37:52 +0000 Subject: [PATCH] 2024-2025 --- TP2/TP2_ex3_sujet.ipynb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/TP2/TP2_ex3_sujet.ipynb b/TP2/TP2_ex3_sujet.ipynb index 5e5322e..3c89307 100644 --- a/TP2/TP2_ex3_sujet.ipynb +++ b/TP2/TP2_ex3_sujet.ipynb @@ -39,7 +39,7 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "%matplotlib notebook" + "%matplotlib inline" ] }, { @@ -66,6 +66,9 @@ "print(categories)\n", "\n", "dataset = fetch_20newsgroups(subset='all', categories=categories)\n", + "# si le chargement du dataset ne fonctionne pas, \n", + "# commentez la ligne précédente, téléchargez le fichier sur Arche, sauvegardez-le dans votre répertoire de travail, et décommentez la ligne suivante:\n", + "#dataset = fetch_20newsgroups(data_home=\"./\", subset='all', categories=categories)\n", "\n", "print(f\"{len(dataset.data)} documents\")\n", "print(f\"{len(dataset.target_names)} catégories\")\n", @@ -94,7 +97,7 @@ "print(f\"contenu de l'attribut target_names: {dataset.target_names}\")\n", "\n", "print(\"\\n\")\n", - "no_doc = 10 # essayez avec d'autres documents parmi les 3929 chargés\n", + "no_doc = 20 # essayez avec d'autres documents parmi les 3929 chargés\n", "print(f\"Document no: {no_doc}\")\n", "print(f\"numéro de catégorie: {dataset.target[no_doc]}\") \n", "print(f\"ce qui correspond au sujet: {dataset.target_names[dataset.target[no_doc]]}\")\n", @@ -125,7 +128,7 @@ "\n", "Dans les cellules suivantes, on associe à chaque document du corpus un vecteur TF-IDF. Pour former le \"sac de mots\" ( _bag of words_ ) de taille $N$, on ne tient pas compte des termes trop courants (`max_df`: les termes présents dans plus de 50% des documents sont éliminés), ainsi que des termes trop courants en anglais (`stop_words`, contenus dans une liste pré-définie). De manière à limiter les temps de calcul et éviter la malédiction de la dimension, on construit des vecteurs de dimension $N$ limitée en ne gardant comme vocabulaire que les $N$ termes les plus fréquents dans tout le corpus (après avoir ignoré les termes \"trop fréquents\"). Les termes rares ne seront donc pas considérés dans notre représentation des documents.\n", "\n", - "Tout d'abord, nous commençons par recharger le jeu de données en éliminant l'en-tête et la citation en bas de page des documents: l'information qu'elles contiennent n'est généralement pas pertinente pour déterminer le sujet d'un document." + "Tout d'abord, nous commençons par recharger le jeu de données en éliminant l'en-tête (_header_) et la signature / citation en bas de page (_footer_) des documents: l'information qu'elles contiennent n'est généralement pas pertinente pour déterminer le sujet d'un document." ] }, { @@ -134,7 +137,7 @@ "metadata": {}, "outputs": [], "source": [ - "dataset = fetch_20newsgroups(subset='all', categories=categories, remove=('headers', 'footers'))\n", + "dataset = fetch_20newsgroups(subset='all', categories=categories, remove=('headers', 'footers')) # si vous avez chargé le fichier sur Arche, ajoutez l'option data_home=\"./\" comme précédemment\n", "print(\"Le texte sans header et footer est:\")\n", "print()\n", "print(dataset.data[no_doc]) # vérifiez que headers et footers ont été éliminés" @@ -274,7 +277,7 @@ "metadata": {}, "source": [ "Quelques remarques:\n", - "* comme on le voit, les termes dont la statistique TFIDF est la plus élevée ont l'air d'avoir effectivement un rapport avec le sujet: il semble donc raisonnable d'utiliser comme représentation vectorielle d'un document le profil TF-IDF et de faire un partitionnement de ces profils\n", + "* comme on le voit, les termes dont la statistique TF-IDF est la plus élevée ont l'air d'avoir effectivement un rapport avec le sujet: il semble donc raisonnable d'utiliser comme représentation vectorielle d'un document le profil TF-IDF et de faire un partitionnement de ces profils\n", "* on constate que, généralement, seuls quelques mots parmi les $N$ sont présents dans un document donné (donc beaucoup de 0 dans le vecteur TF-IDF)\n", "* le document 1000 correspond à un très long document (faire `print(dataset.data[1000])`). Beaucoup des mots du sac sont donc présents." ] @@ -288,8 +291,8 @@ "__Question 2__ : utilisez les algorithmes de classification hiérarchique (single-linkage, Ward) et k-means pour identifier des groupements parmi les vecteurs TF-IDF (donc parmi les documents associés) en quatre groupes. Les `labels` (valeurs entre 0 et 3) calculés pour chaque vecteur TF-IDF correspondent au numéro du groupe identifié.\n", "\n", "_Indications_ :\n", - "* On utilisera `AgglomerativeClustering` avec les options `linkage='single'` et `linkage='ward'` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html)), ainsi que `KMeans` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html), faire `n_init=10`). Si vous avez le temps, vous pouvez essayer `MiniBatchKMeans` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html)). \n", - "* Les algorithmes travaillent sur des bases de données sous forme de tableau ( _array_ ): il faudra donc travailler avec `vectors.toarray()` qui transforme `vectors` (les vecteurs TFIDF associés au document) en tableau dont la ligne $i$ contient la représentation TFIDF du document no $i$.\n", + "* On utilisera `AgglomerativeClustering` (voir exercice précédent) avec les options `linkage='single'` et `linkage='ward'` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html)), ainsi que `KMeans` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html), faire `n_init=10`). Si vous avez le temps, vous pouvez essayer `MiniBatchKMeans` (cf [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html)). \n", + "* Les algorithmes travaillent sur des bases de données sous forme de tableau ( _array_ ): il faudra donc travailler avec `vectors.toarray()` qui transforme `vectors` (les vecteurs TF-IDF associés au document) en tableau dont la ligne $i$ contient la représentation TF-IDF du document no $i$.\n", "* Sauvegardez les labels identifiés par chaque méthode dans des variables `labels_single`, `labels_ward`, et `labels_KM`.\n", "* Observez les différences de temps de calcul (obtenus en faisant la différence entre les valeurs retournées par `time.time()`)." ] @@ -338,7 +341,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "La cellule suivante renumérote les labels attribués de manière à leur associer le \"vrai\" label majoritaire dans le groupe identifié (fonction `mode` de `scipy`). \n", + "La cellule suivante renumérote les labels attribués de manière à associer à un groupe le \"vrai label\" majoritaire dans ce groupe (fonction `mode` de `scipy`). \n", "Cette manipulation permet de mieux comprendre quels sont les labels bien identifiés en comparant les labels obtenus aux \"vrais\" labels, qui doivent être les mêmes si le partitionnement s'est bien déroulé." ] }, -- GitLab