.. _artificieltokenizerst: ============ Tokenisation ============ .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`PDF `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/lectures/artificiel_tokenize.ipynb|*` La tokenisation consiste à découper un texte en *token*, le plus souvent des mots. Le notebook utilise un extrait d’un article du monde. .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: Tokenizer --------- .. code:: ipython3 texte = """ Mardi 20 février, à la médiathèque des Mureaux (Yvelines), le chef de l’Etat a accompagné la locataire de la rue de Valois pour la remise officielle du rapport sur les bibliothèques, rédigé par leur ami commun, l’académicien Erik Orsenna, avec le concours de Noël Corbin, inspecteur général des affaires culturelles. L’occasion de présenter les premières mesures en faveur d’un « plan bibliothèques ». """ nltk ~~~~ La librairie la plus connue pour faire du traitement du langage naturel est `nltk `__ (ou *Natural Language Toolkit*). .. code:: ipython3 from nltk.tokenize import word_tokenize ' - '.join(word_tokenize(texte)) .. parsed-literal:: 'Mardi - 20 - février - , - à - la - médiathèque - des - Mureaux - ( - Yvelines - ) - , - le - chef - de - l - ’ - Etat - a - accompagné - la - locataire - de - la - rue - de - Valois - pour - la - remise - officielle - du - rapport - sur - les - bibliothèques - , - rédigé - par - leur - ami - commun - , - l - ’ - académicien - Erik - Orsenna - , - avec - le - concours - de - Noël - Corbin - , - inspecteur - général - des - affaires - culturelles - . - L - ’ - occasion - de - présenter - les - premières - mesures - en - faveur - d - ’ - un - « - plan - bibliothèques - » - .' .. code:: ipython3 from nltk.tokenize import WordPunctTokenizer to = WordPunctTokenizer() ' - '.join(to.tokenize(texte)) .. parsed-literal:: 'Mardi - 20 - février - , - à - la - médiathèque - des - Mureaux - ( - Yvelines - ), - le - chef - de - l - ’ - Etat - a - accompagné - la - locataire - de - la - rue - de - Valois - pour - la - remise - officielle - du - rapport - sur - les - bibliothèques - , - rédigé - par - leur - ami - commun - , - l - ’ - académicien - Erik - Orsenna - , - avec - le - concours - de - Noël - Corbin - , - inspecteur - général - des - affaires - culturelles - . - L - ’ - occasion - de - présenter - les - premières - mesures - en - faveur - d - ’ - un - « - plan - bibliothèques - ».' .. code:: ipython3 from difflib import context_diff, ndiff print('\n'.join(context_diff(word_tokenize(texte), to.tokenize(texte), fromfile='word_tokenize', tofile='WordPunctTokenizer'))) .. parsed-literal:: *** word_tokenize --- WordPunctTokenizer *************** *** 9,16 **** Mureaux ( Yvelines ! ) ! , le chef de --- 9,15 ---- Mureaux ( Yvelines ! ), le chef de *************** *** 77,81 **** « plan bibliothèques ! » ! . --- 76,79 ---- « plan bibliothèques ! ». gensim ~~~~~~ La documentation de la librairie `nltk `__ est assez longue et ce n’est pas la plus simple d’accès. `gensim `__ est une autre option plus récente. .. code:: ipython3 from gensim.utils import tokenize " - ".join(tokenize(texte, deacc=True, lower=True)) .. parsed-literal:: 'mardi - fevrier - a - la - mediatheque - des - mureaux - yvelines - le - chef - de - l - etat - a - accompagne - la - locataire - de - la - rue - de - valois - pour - la - remise - officielle - du - rapport - sur - les - bibliotheques - redige - par - leur - ami - commun - l - academicien - erik - orsenna - avec - le - concours - de - noel - corbin - inspecteur - general - des - affaires - culturelles - l - occasion - de - presenter - les - premieres - mesures - en - faveur - d - un - plan - bibliotheques' .. code:: ipython3 from gensim.utils import tokenize " - ".join(tokenize("chiffres 20 ch20", deacc=True, lower=True)) .. parsed-literal:: 'chiffres - ch' spacy ~~~~~ Un dernier module a vu le jour `spacy `__. On suit l’exemple présenté dans `spacy-101 `__. Il faut télécharger un paquet de ressource depuis `spacy-models `__. **Note :** sous Windows, il faut faudra ruser et installer le module `fr_core_news_sm `__ vous même (et bidouiller le fichier setup.py). .. code:: ipython3 import spacy nlp = spacy.load('fr_core_news_sm') # Il faut exécuter ceci depuis la ligne de commande au moins une fois. # python -m spacy download fr_core_news_sm .. code:: ipython3 doc = nlp(texte) .. code:: ipython3 ' - '.join(t.text for t in doc) .. parsed-literal:: '\n - Mardi - 20 - février - , - à - la - médiathèque - des - Mureaux - ( - Yvelines - ) - , - le - chef - de - l’ - Etat - a - accompagné - \n - la - locataire - de - la - rue - de - Valois - pour - la - remise - officielle - du - rapport - \n - sur - les - bibliothèques - , - rédigé - par - leur - ami - commun - , - l’ - académicien - \n - Erik - Orsenna - , - avec - le - concours - de - Noël - Corbin - , - inspecteur - général - \n - des - affaires - culturelles - . - L’ - occasion - de - présenter - les - premières - \n - mesures - en - faveur - d’ - un - « - plan - bibliothèques - » - . - \n' .. code:: ipython3 ' - '.join(t.text for t in doc if t.is_alpha) .. parsed-literal:: 'Mardi - février - à - la - médiathèque - des - Mureaux - Yvelines - le - chef - de - Etat - a - accompagné - la - locataire - de - la - rue - de - Valois - pour - la - remise - officielle - du - rapport - sur - les - bibliothèques - rédigé - par - leur - ami - commun - académicien - Erik - Orsenna - avec - le - concours - de - Noël - Corbin - inspecteur - général - des - affaires - culturelles - occasion - de - présenter - les - premières - mesures - en - faveur - un - plan - bibliothèques' On voit que la tokenisation des apostrophes est différente et qu’on a plus d’information sur chaque token. .. code:: ipython3 el = doc[1] .. code:: ipython3 el.text, el.is_alpha .. parsed-literal:: ('Mardi', True) Supprimer les stopwords ----------------------- nltk ~~~~ Le module `nltk `__ fournit une liste de stopwords. Il suffit de supprimer tous les mots dans cette liste. .. code:: ipython3 from nltk.corpus import stopwords ' - '.join(stopwords.words('english')) .. parsed-literal:: "i - me - my - myself - we - our - ours - ourselves - you - you're - you've - you'll - you'd - your - yours - yourself - yourselves - he - him - his - himself - she - she's - her - hers - herself - it - it's - its - itself - they - them - their - theirs - themselves - what - which - who - whom - this - that - that'll - these - those - am - is - are - was - were - be - been - being - have - has - had - having - do - does - did - doing - a - an - the - and - but - if - or - because - as - until - while - of - at - by - for - with - about - against - between - into - through - during - before - after - above - below - to - from - up - down - in - out - on - off - over - under - again - further - then - once - here - there - when - where - why - how - all - any - both - each - few - more - most - other - some - such - no - nor - not - only - own - same - so - than - too - very - s - t - can - will - just - don - don't - should - should've - now - d - ll - m - o - re - ve - y - ain - aren - aren't - couldn - couldn't - didn - didn't - doesn - doesn't - hadn - hadn't - hasn - hasn't - haven - haven't - isn - isn't - ma - mightn - mightn't - mustn - mustn't - needn - needn't - shan - shan't - shouldn - shouldn't - wasn - wasn't - weren - weren't - won - won't - wouldn - wouldn't" .. code:: ipython3 ' - '.join(stopwords.words('french')) .. parsed-literal:: 'au - aux - avec - ce - ces - dans - de - des - du - elle - en - et - eux - il - ils - je - la - le - les - leur - lui - ma - mais - me - même - mes - moi - mon - ne - nos - notre - nous - on - ou - par - pas - pour - qu - que - qui - sa - se - ses - son - sur - ta - te - tes - toi - ton - tu - un - une - vos - votre - vous - c - d - j - l - à - m - n - s - t - y - été - étée - étées - étés - étant - étante - étants - étantes - suis - es - est - sommes - êtes - sont - serai - seras - sera - serons - serez - seront - serais - serait - serions - seriez - seraient - étais - était - étions - étiez - étaient - fus - fut - fûmes - fûtes - furent - sois - soit - soyons - soyez - soient - fusse - fusses - fût - fussions - fussiez - fussent - ayant - ayante - ayantes - ayants - eu - eue - eues - eus - ai - as - avons - avez - ont - aurai - auras - aura - aurons - aurez - auront - aurais - aurait - aurions - auriez - auraient - avais - avait - avions - aviez - avaient - eut - eûmes - eûtes - eurent - aie - aies - ait - ayons - ayez - aient - eusse - eusses - eût - eussions - eussiez - eussent' .. code:: ipython3 st = set(stopwords.words('french')) ' - '.join(w for w in word_tokenize(texte) if w not in st) .. parsed-literal:: 'Mardi - 20 - février - , - médiathèque - Mureaux - ( - Yvelines - ) - , - chef - ’ - Etat - a - accompagné - locataire - rue - Valois - remise - officielle - rapport - bibliothèques - , - rédigé - ami - commun - , - ’ - académicien - Erik - Orsenna - , - concours - Noël - Corbin - , - inspecteur - général - affaires - culturelles - . - L - ’ - occasion - présenter - premières - mesures - faveur - ’ - « - plan - bibliothèques - » - .' gensim ~~~~~~ .. code:: ipython3 from gensim.parsing.preprocessing import STOPWORDS " - ".join(STOPWORDS) .. parsed-literal:: 'co - again - alone - doesn - two - one - kg - con - latter - own - thin - however - along - hers - further - first - had - three - de - because - nevertheless - ours - using - thereafter - mostly - ten - same - down - just - every - above - anyway - already - five - she - both - ourselves - twenty - anywhere - former - before - third - else - herein - across - next - full - should - fifty - whenever - the - fire - hereupon - take - could - became - where - therefore - mill - about - more - perhaps - almost - never - whole - anyhow - was - wherein - hasnt - myself - nobody - me - whether - found - be - out - fifteen - becoming - as - becomes - we - please - nowhere - another - our - this - amount - then - enough - somewhere - being - very - while - behind - over - only - get - between - most - he - last - put - have - besides - himself - ltd - still - none - am - yourselves - whence - latterly - us - doing - what - seemed - does - cannot - onto - upon - noone - name - beyond - front - except - whereby - thereupon - although - throughout - whatever - unless - other - either - regarding - moreover - become - not - that - each - call - eg - among - whom - anyone - made - used - computer - amongst - detail - off - amoungst - his - their - empty - namely - mine - if - quite - wherever - yet - nor - whereafter - him - some - nine - didn - themselves - together - everyone - they - yourself - around - hence - un - interest - cry - why - who - done - say - thick - make - sixty - eleven - beside - everything - been - anything - has - of - ie - describe - and - rather - per - up - those - part - but - otherwise - thence - give - now - keep - seems - well - least - to - too - serious - might - inc - km - itself - meanwhile - her - few - whereas - find - neither - via - formerly - at - etc - must - when - within - see - somehow - eight - often - four - various - do - sincere - whereupon - your - such - don - twelve - on - with - were - hereafter - or - you - herself - towards - my - for - go - them - by - in - nothing - all - can - afterwards - under - thus - will - once - which - any - indeed - bottom - system - whoever - from - against - whose - many - thereby - show - elsewhere - without - how - everywhere - an - during - much - are - here - below - would - a - cant - beforehand - always - hundred - sometime - due - bill - though - someone - since - after - others - six - forty - yours - back - move - ever - into - less - did - may - toward - i - no - so - it - couldnt - several - its - side - these - even - seem - whither - really - therein - top - until - something - thru - re - there - is - than - hereby - through - fill - sometimes - also - seeming' spacy ~~~~~ Encore plus simple avec `spacy `__ où chaque token contient l’information souhaitée. .. code:: ipython3 docw = nlp(texte) ' - '.join(t.text for t in docw if t.is_stop) .. parsed-literal:: 'à - la - des - le - de - l’ - a - la - de - la - de - pour - la - du - sur - les - par - leur - l’ - avec - le - de - des - L’ - de - les - en - d’ - un' .. code:: ipython3 ' - '.join(t.text for t in docw if not t.is_stop) .. parsed-literal:: '\n - Mardi - 20 - février - , - médiathèque - Mureaux - ( - Yvelines - ) - , - chef - Etat - accompagné - \n - locataire - rue - Valois - remise - officielle - rapport - \n - bibliothèques - , - rédigé - ami - commun - , - académicien - \n - Erik - Orsenna - , - concours - Noël - Corbin - , - inspecteur - général - \n - affaires - culturelles - . - occasion - présenter - premières - \n - mesures - faveur - « - plan - bibliothèques - » - . - \n' Autres modules -------------- - `textblob `__, `textblob-fr `__ : Simplified Text Processing - `corpora `__, `pycorpora `__ : corpus de texte - `regex4dummies `__ : expression régulière pour extraire des informations dans un texte Il existe une quantité de modules différentes. Lorsque les sources sont connues et très utilisées comme `wikipedia `__. n-grams ------- Petit intermède : après un découpage en mots, on ne considère plus l’ordre avec une approche *bag-of-words*. Si l’information contenu par l’ordre des mots s’avère importante, il faut considérer un découpage en couple de mots (bi-grammes), triplets de mots (3-grammes)… .. code:: ipython3 from nltk.util import ngrams generated_ngrams = ngrams(word_tokenize(texte), 4, pad_left=True, pad_right=True) list(generated_ngrams)[:7] .. parsed-literal:: [(None, None, None, 'Mardi'), (None, None, 'Mardi', '20'), (None, 'Mardi', '20', 'février'), ('Mardi', '20', 'février', ','), ('20', 'février', ',', 'à'), ('février', ',', 'à', 'la'), (',', 'à', 'la', 'médiathèque')] Versions utilisées pour ce notebook ----------------------------------- `spacy `__ s’est montré quelque peu fantasques cette année avec quelques erreurs notamment celle-ci : `ValueError: cymem.cymem.Pool has the wrong size, try recompiling `__. Voici les versions utilisées… .. code:: ipython3 def version(module): try: ver = getattr(module, '__version__', None) if ver is None: ver = [_ for _ in os.listdir(os.path.join(module.__file__, '..', '..')) \ if module.__name__ in _][-1] return ver except Exception as e: return str(e) .. code:: ipython3 import os import thinc print("thinc", version(thinc)) import preshed print("preshed", version(preshed)) import cymem print("cymem", version(cymem)) import murmurhash print("murmurhash", version(murmurhash)) import plac print("plac", plac.__version__) import spacy print("spacy", spacy.__version__) .. parsed-literal:: thinc 7.4.1 preshed preshed-3.0.2.dist-info cymem cymem-2.0.2.dist-info murmurhash murmurhash-1.0.2.dist-info plac 0.9.6 spacy 2.3.2