{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Classes Word et nltk\n", "#### Jouons un peu avec un fichier taggé et nltk\n", "Un peu de POO avec nos propres classes puis celles de nltk" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Classes Word pour lecture de fichiers taggés en pos" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import re\n", "\n", "class Word:\n", " \"\"\" Classe Word : définit un mot simple de la langue \"\"\"\n", "\n", " type = \"simple\"\n", "\n", " def __init__(self, *args):\n", " self.form, self.lemma, self.pos = args\n", "\n", " def is_inflected(self):\n", " if self.form != self.lemma:\n", " return True\n", " else:\n", " return False\n", "\n", " def magic_compare(self, other_word):\n", " diff = []\n", " for key in self.__dict__.keys():\n", " if self.__dict__[key] != other_word.__dict__[key]:\n", " diff.append(key)\n", " return diff\n", "\n", " def __str__(self):\n", " return \" \".join((self.form, self.lemma, self.pos))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`__str__` est une méthode que partagent tous les objets, elle est appellée par la fonction `print`.\n", "Ici nous 'surchargeons' la méthode pour spécifier la sortie désirée. On peut aussi implémenter une ou plus méthodes d'output (text, xml, json, ...)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "obj = Word(\"été\", \"été\", \"NOM\")\n", "print(obj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour les imports de données aux formats TreeTagger, Brow et Sem nous allons utiliser des classes qui héritent de Word.\n", "Les classes se contentent d'avoir un constructeur différent." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class WordTreeTagger(Word):\n", " def __init__(self, formatted_str):\n", " \"\"\"\n", " import a formatted_str in treetagger format\n", " \"\"\"\n", " self.form, self.lemma, self.pos = formatted_str.split(\"\\t\")\n", "\n", "class WordBrown(Word):\n", " def __init__(self, formatted_str):\n", " \"\"\"\n", " import a formatted_str in brown format\n", " \"\"\"\n", " self.form, self.lemma, self.pos = formatted_str.split(\"/\")\n", "\n", "class WordSem(Word):\n", " def __init__(self, formatted_str):\n", " \"\"\"\n", " import a formatted_str in sem format (brown with no lemmas\n", " \"\"\"\n", " self.form, self.pos = formatted_str.split(\"/\")\n", " self.lemma = \"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un objet WordBrown est aussi un objet Word" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "obj_brown = WordBrown(\"été/être/V\")\n", "if isinstance(obj_brown, WordBrown):\n", " print(\"Évidemment obj_brown est une instance de WordBrown\")\n", "if isinstance(obj_brown, Word):\n", " print(\"C'est aussi une instance de la classe Word, je peux lui appliquer les méthodes de Word\")\n", "obj_brown.magic_compare(obj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lecture et chargement du fichier `lecun-pos.txt`, transcription tagguée avec Sem (http://apps.lattice.cnrs.fr/sem) d'une présentation de l'intelligence artificielle de Yann LeCun au collège de France (https://www.college-de-france.fr/site/yann-lecun/Recherches-sur-l-intelligence-artificielle.htm)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "words = []\n", "with open('lecun-pos.txt') as file:\n", " for line in file:\n", " if '/' in line:\n", " line = line.rstrip()\n", " words.extend([WordSem(item) for item in line.split(\" \")])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for word in words[:10]:\n", " print(word)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le fichier est chargé en mémoire dans une liste d'objets Word.\n", "Je voudrais maintenant faire des calculs simples sur les fréquences de mots, trouver les hapax, les mots d'une certaine catégorie, etc...\n", "Je peux faire ça à la main sans trop de difficultés, je peux aussi utiliser le package `nltk` et plus particulièrement le module `nltk.probablity`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Utilisation du module `nltk.probability`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from nltk.probability import FreqDist, ConditionalFreqDist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si vous avez un message d'erreur c'est que le package `nltk` n'est pas installé sur votre machine : `sudo pip3 install nltk`\n", "\n", "Nous aurons aussi besoin de matplotlib. Si vous êtes sur une debian-based utilisez apt-get pour l'installer (`python3-matplotlib`), sinon pip." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il faut commencer par lire ou au moins parcourir la [doc de `nltk.probability`](http://www.nltk.org/api/nltk.html?highlight=nltk.probability#module-nltk.probability)\n", "Nous allons utiliser les classes `FreqDist` et `ConditionalFreqDist`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fdist = FreqDist(word.form.lower() for word in words)\n", "fdist.hapaxes()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et voilà. C'est aussi simple que ça de trouver les hapax.\n", "À vous de jouer, trouvez le mot le plus fréquent, puis les 20 mots les plus fréquents, trouvez les fréquences de 'le', 'artificielle' et 'réseaux'.\n", "\n", "Enfin affichez un graphe des fréquences des 20 mots les plus fréquents." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#fdist.max()\n", "#for form, occ in fdist.most_common(20):\n", "# print(form)\n", "#fdist['le']\n", "%matplotlib inline\n", "fdist.plot(10)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`ConditionalFreqDist` permet de faire des calculs de fréquences selon une certaine condition. Ici nous allons utiliser le pos comme condition." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# cfdist = ConditionalFreqDist((word.pos, word.form) for word in words)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cfdist['V']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On obtient très facilement la liste des mots étiquetés comme verbes et leur fréquence." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" } }, "nbformat": 4, "nbformat_minor": 1 }