TF-IDF¶
La méthode term frequency–inverse document frequency est une manière de transformer des mots en chiffres. Cela se base sur une intuition: un mot qui est très présent dans un document et qui n’est pas très présent dans le reste du corpus est un mot qui peut bien caractériser ce document.
Concrètement la formule fonctionne comme suit:
fréquence d’un mot dans un document: on compte combien de fois un mot apparaît dans un document
fréquence inverse: on regarde combien de fois ce mot apparaît dans le reste du corpus
Finalement on applique la formule suivante:
inverse_document_frequency = log(total number of documents / number of documents with term) + 1
Par exemple: admettons que le mot “amour” apparaisse 10 fois dans 1 document et qu’il aparaisse au total dans 5 documents sur 10 analysés. son idf sera:
# Import math Library
import math
math.log(10/5)+1
1.6931471805599454
Considérons que le log de 1 est 0 ce qui signifie que si le mot apparaît dans tout les documents la idf est 1.
math.log(1)
0.0
math.log(1)+1
1.0
Le tf-idf d’amour sera donc:
tf-idf = term_frequency * inverse_document_frequency
Son tf-idf sera :
liste = []
liste.append(10 * (math.log(10/5)+1))
10 * (math.log(10/5)+1)
16.931471805599454
Si amour apparaissait dans tous les documents il aurait un plus bas résultat:
liste.append(10 * (math.log(10/10)+1))
10 * (math.log(10/10)+1)
10.0
Si amour n’apparaissait que dans ce document alors son idf serait:
liste.append(10 * (math.log(10/1)+1))
10 * (math.log(10/1)+1)
33.02585092994046
Donc résultat élevé car le mot apparaît seulement dans le document et il y est 10 fois.
Et encore si amour aparaissait 1 fois dans chaque document:
liste.append(1 * (math.log(10/10)+1))
1 * (math.log(10/10)+1)
1.0
liste
[16.931471805599454, 10.0, 33.02585092994046, 1.0]
import numpy as np
from sklearn import preprocessing
x_array = np.array(liste)
normalized_arr = preprocessing.normalize([x_array])
print(normalized_arr)
[[0.44035349 0.26007986 0.85893588 0.02600799]]
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
pd.set_option("max_rows", 600)
from pathlib import Path
import glob
import requests
import json
/home/marcello/.local/lib/python3.7/site-packages/sklearn/feature_extraction/image.py:167: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
dtype=np.int):
data = requests.get('http://anthologia.ecrituresnumeriques.ca/api/v1/entities').json()
mes_textes = []
for epigram in data:
titre = epigram['title']
if 'Greek Anthology 5' in titre or 'Greek Anthology 4' in titre:
for version in epigram['versions']:
if version['id_language'] == 2:
texte = version['text_translated']
dictio = {'title': titre, 'texte' : texte}
mes_textes.append(dictio)
mes_textes[70]
{'title': 'Greek Anthology 5.60',
'texte': 'Une jeune fille aux pieds d’argent se baignait, arrosant les pommes d’or de ses seins de lait\xa0; ses fesses rondes palpitaient, d’un mouvement inconscient, et l’on voyait frissonner leur chair plus onduleuse que l’eau\xa0; cependant, de sa main étendue, elle voilait le renflement de son… Eurotas, non pas en entier, mais tout ce qu’elle en pouvait couvrir. '}
stopwords = requests.get('https://raw.githubusercontent.com/stopwords-iso/stopwords-fr/master/stopwords-fr.txt').text.split('\n')
stopwords
['a',
'abord',
'absolument',
'afin',
'ah',
'ai',
'aie',
'aient',
'aies',
'ailleurs',
'ainsi',
'ait',
'allaient',
'allo',
'allons',
'allô',
'alors',
'anterieur',
'anterieure',
'anterieures',
'apres',
'après',
'as',
'assez',
'attendu',
'au',
'aucun',
'aucune',
'aucuns',
'aujourd',
"aujourd'hui",
'aupres',
'auquel',
'aura',
'aurai',
'auraient',
'aurais',
'aurait',
'auras',
'aurez',
'auriez',
'aurions',
'aurons',
'auront',
'aussi',
'autant',
'autre',
'autrefois',
'autrement',
'autres',
'autrui',
'aux',
'auxquelles',
'auxquels',
'avaient',
'avais',
'avait',
'avant',
'avec',
'avez',
'aviez',
'avions',
'avoir',
'avons',
'ayant',
'ayez',
'ayons',
'b',
'bah',
'bas',
'basee',
'bat',
'beau',
'beaucoup',
'bien',
'bigre',
'bon',
'boum',
'bravo',
'brrr',
'c',
'car',
'ce',
'ceci',
'cela',
'celle',
'celle-ci',
'celle-là',
'celles',
'celles-ci',
'celles-là',
'celui',
'celui-ci',
'celui-là',
'celà',
'cent',
'cependant',
'certain',
'certaine',
'certaines',
'certains',
'certes',
'ces',
'cet',
'cette',
'ceux',
'ceux-ci',
'ceux-là',
'chacun',
'chacune',
'chaque',
'cher',
'chers',
'chez',
'chiche',
'chut',
'chère',
'chères',
'ci',
'cinq',
'cinquantaine',
'cinquante',
'cinquantième',
'cinquième',
'clac',
'clic',
'combien',
'comme',
'comment',
'comparable',
'comparables',
'compris',
'concernant',
'contre',
'couic',
'crac',
'd',
'da',
'dans',
'de',
'debout',
'dedans',
'dehors',
'deja',
'delà',
'depuis',
'dernier',
'derniere',
'derriere',
'derrière',
'des',
'desormais',
'desquelles',
'desquels',
'dessous',
'dessus',
'deux',
'deuxième',
'deuxièmement',
'devant',
'devers',
'devra',
'devrait',
'different',
'differentes',
'differents',
'différent',
'différente',
'différentes',
'différents',
'dire',
'directe',
'directement',
'dit',
'dite',
'dits',
'divers',
'diverse',
'diverses',
'dix',
'dix-huit',
'dix-neuf',
'dix-sept',
'dixième',
'doit',
'doivent',
'donc',
'dont',
'dos',
'douze',
'douzième',
'dring',
'droite',
'du',
'duquel',
'durant',
'dès',
'début',
'désormais',
'e',
'effet',
'egale',
'egalement',
'egales',
'eh',
'elle',
'elle-même',
'elles',
'elles-mêmes',
'en',
'encore',
'enfin',
'entre',
'envers',
'environ',
'es',
'essai',
'est',
'et',
'etant',
'etc',
'etre',
'eu',
'eue',
'eues',
'euh',
'eurent',
'eus',
'eusse',
'eussent',
'eusses',
'eussiez',
'eussions',
'eut',
'eux',
'eux-mêmes',
'exactement',
'excepté',
'extenso',
'exterieur',
'eûmes',
'eût',
'eûtes',
'f',
'fais',
'faisaient',
'faisant',
'fait',
'faites',
'façon',
'feront',
'fi',
'flac',
'floc',
'fois',
'font',
'force',
'furent',
'fus',
'fusse',
'fussent',
'fusses',
'fussiez',
'fussions',
'fut',
'fûmes',
'fût',
'fûtes',
'g',
'gens',
'h',
'ha',
'haut',
'hein',
'hem',
'hep',
'hi',
'ho',
'holà',
'hop',
'hormis',
'hors',
'hou',
'houp',
'hue',
'hui',
'huit',
'huitième',
'hum',
'hurrah',
'hé',
'hélas',
'i',
'ici',
'il',
'ils',
'importe',
'j',
'je',
'jusqu',
'jusque',
'juste',
'k',
'l',
'la',
'laisser',
'laquelle',
'las',
'le',
'lequel',
'les',
'lesquelles',
'lesquels',
'leur',
'leurs',
'longtemps',
'lors',
'lorsque',
'lui',
'lui-meme',
'lui-même',
'là',
'lès',
'm',
'ma',
'maint',
'maintenant',
'mais',
'malgre',
'malgré',
'maximale',
'me',
'meme',
'memes',
'merci',
'mes',
'mien',
'mienne',
'miennes',
'miens',
'mille',
'mince',
'mine',
'minimale',
'moi',
'moi-meme',
'moi-même',
'moindres',
'moins',
'mon',
'mot',
'moyennant',
'multiple',
'multiples',
'même',
'mêmes',
'n',
'na',
'naturel',
'naturelle',
'naturelles',
'ne',
'neanmoins',
'necessaire',
'necessairement',
'neuf',
'neuvième',
'ni',
'nombreuses',
'nombreux',
'nommés',
'non',
'nos',
'notamment',
'notre',
'nous',
'nous-mêmes',
'nouveau',
'nouveaux',
'nul',
'néanmoins',
'nôtre',
'nôtres',
'o',
'oh',
'ohé',
'ollé',
'olé',
'on',
'ont',
'onze',
'onzième',
'ore',
'ou',
'ouf',
'ouias',
'oust',
'ouste',
'outre',
'ouvert',
'ouverte',
'ouverts',
'o|',
'où',
'p',
'paf',
'pan',
'par',
'parce',
'parfois',
'parle',
'parlent',
'parler',
'parmi',
'parole',
'parseme',
'partant',
'particulier',
'particulière',
'particulièrement',
'pas',
'passé',
'pendant',
'pense',
'permet',
'personne',
'personnes',
'peu',
'peut',
'peuvent',
'peux',
'pff',
'pfft',
'pfut',
'pif',
'pire',
'pièce',
'plein',
'plouf',
'plupart',
'plus',
'plusieurs',
'plutôt',
'possessif',
'possessifs',
'possible',
'possibles',
'pouah',
'pour',
'pourquoi',
'pourrais',
'pourrait',
'pouvait',
'prealable',
'precisement',
'premier',
'première',
'premièrement',
'pres',
'probable',
'probante',
'procedant',
'proche',
'près',
'psitt',
'pu',
'puis',
'puisque',
'pur',
'pure',
'q',
'qu',
'quand',
'quant',
'quant-à-soi',
'quanta',
'quarante',
'quatorze',
'quatre',
'quatre-vingt',
'quatrième',
'quatrièmement',
'que',
'quel',
'quelconque',
'quelle',
'quelles',
"quelqu'un",
'quelque',
'quelques',
'quels',
'qui',
'quiconque',
'quinze',
'quoi',
'quoique',
'r',
'rare',
'rarement',
'rares',
'relative',
'relativement',
'remarquable',
'rend',
'rendre',
'restant',
'reste',
'restent',
'restrictif',
'retour',
'revoici',
'revoilà',
'rien',
's',
'sa',
'sacrebleu',
'sait',
'sans',
'sapristi',
'sauf',
'se',
'sein',
'seize',
'selon',
'semblable',
'semblaient',
'semble',
'semblent',
'sent',
'sept',
'septième',
'sera',
'serai',
'seraient',
'serais',
'serait',
'seras',
'serez',
'seriez',
'serions',
'serons',
'seront',
'ses',
'seul',
'seule',
'seulement',
'si',
'sien',
'sienne',
'siennes',
'siens',
'sinon',
'six',
'sixième',
'soi',
'soi-même',
'soient',
'sois',
'soit',
'soixante',
'sommes',
'son',
'sont',
'sous',
'souvent',
'soyez',
'soyons',
'specifique',
'specifiques',
'speculatif',
'stop',
'strictement',
'subtiles',
'suffisant',
'suffisante',
'suffit',
'suis',
'suit',
'suivant',
'suivante',
'suivantes',
'suivants',
'suivre',
'sujet',
'superpose',
'sur',
'surtout',
't',
'ta',
'tac',
'tandis',
'tant',
'tardive',
'te',
'tel',
'telle',
'tellement',
'telles',
'tels',
'tenant',
'tend',
'tenir',
'tente',
'tes',
'tic',
'tien',
'tienne',
'tiennes',
'tiens',
'toc',
'toi',
'toi-même',
'ton',
'touchant',
'toujours',
'tous',
'tout',
'toute',
'toutefois',
'toutes',
'treize',
'trente',
'tres',
'trois',
'troisième',
'troisièmement',
'trop',
'très',
'tsoin',
'tsouin',
'tu',
'té',
'u',
'un',
'une',
'unes',
'uniformement',
'unique',
'uniques',
'uns',
'v',
'va',
'vais',
'valeur',
'vas',
'vers',
'via',
'vif',
'vifs',
'vingt',
'vivat',
'vive',
'vives',
'vlan',
'voici',
'voie',
'voient',
'voilà',
'voire',
'vont',
'vos',
'votre',
'vous',
'vous-mêmes',
'vu',
'vé',
'vôtre',
'vôtres',
'w',
'x',
'y',
'z',
'zut',
'à',
'â',
'ça',
'ès',
'étaient',
'étais',
'était',
'étant',
'état',
'étiez',
'étions',
'été',
'étée',
'étées',
'étés',
'êtes',
'être',
'ô']
tfidf_vectorizer = TfidfVectorizer(stop_words=stopwords)
len(mes_textes)
214
tfidf_vector = tfidf_vectorizer.fit_transform([texte['texte'] for texte in mes_textes])
/home/marcello/.local/lib/python3.7/site-packages/sklearn/feature_extraction/text.py:301: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['quelqu'] not in stop_words.
'stop_words.' % sorted(inconsistent))
tfidf_df = pd.DataFrame(tfidf_vector.toarray(), index=[texte['title'] for texte in mes_textes], columns=tfidf_vectorizer.get_feature_names())
tfidf_slice = tfidf_df[['amour', 'mort', 'éros', 'fille', 'garçon', 'fleur', 'pouvoir']]
tfidf_slice.sort_index().round(decimals=2).head(20)
amour | mort | éros | fille | garçon | fleur | pouvoir | |
---|---|---|---|---|---|---|---|
Greek Anthology 4.1 | 0.00 | 0.00 | 0.03 | 0.00 | 0.0 | 0.10 | 0.00 |
Greek Anthology 4.2 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 4.3 | 0.02 | 0.00 | 0.00 | 0.03 | 0.0 | 0.03 | 0.00 |
Greek Anthology 4.4 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 4.5 | 0.00 | 0.14 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.0 | 0.00 | 0.00 | 0.20 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.1 | 0.16 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.10 | 0.00 | 0.00 | 0.14 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.100 | 0.00 | 0.00 | 0.12 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.101 | 0.00 | 0.00 | 0.00 | 0.19 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.102 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.103 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.23 |
Greek Anthology 5.104 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.105 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.106 | 0.00 | 0.00 | 0.00 | 0.14 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.107 | 0.10 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.108 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.109 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.11 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
Greek Anthology 5.110 | 0.00 | 0.00 | 0.00 | 0.00 | 0.0 | 0.00 | 0.00 |
tfidf_df = tfidf_df.stack().reset_index()
tfidf_df = tfidf_df.rename(columns={0:'tfidf', 'level_0': 'document','level_1': 'term', 'level_2': 'term'})
tfidf_df.sort_values(by=['document','tfidf'], ascending=[True,False]).groupby(['document']).head(10)
document | term | tfidf | |
---|---|---|---|
2954 | Greek Anthology 4.1 | ajouté | 0.232646 |
3933 | Greek Anthology 4.1 | fleurs | 0.187602 |
4869 | Greek Anthology 4.1 | poète | 0.162023 |
4511 | Greek Anthology 4.1 | muses | 0.135984 |
3540 | Greek Anthology 4.1 | cueillie | 0.116323 |
... | ... | ... | ... |
305104 | Greek Anthology 5.99 | joueuse | 0.323712 |
306230 | Greek Anthology 5.99 | toucher | 0.323712 |
305043 | Greek Anthology 5.99 | instrument | 0.306048 |
305289 | Greek Anthology 5.99 | milieu | 0.256255 |
304687 | Greek Anthology 5.99 | faire | 0.238591 |
2140 rows × 3 columns
epigramtitle= 'Greek Anthology 5.2'
myfilter = tfidf_df['document'] == epigramtitle
tfidf_df[myfilter].sort_values(by=['document','tfidf'], ascending=[True,False]).groupby(['document']).head(10)
document | term | tfidf | |
---|---|---|---|
14635 | Greek Anthology 5.2 | barbare | 0.226372 |
15024 | Greek Anthology 5.2 | côtés | 0.226372 |
15055 | Greek Anthology 5.2 | devrai | 0.226372 |
15183 | Greek Anthology 5.2 | désirent | 0.226372 |
15520 | Greek Anthology 5.2 | gratuitement | 0.226372 |
16759 | Greek Anthology 5.2 | sthénélaïde | 0.226372 |
16774 | Greek Anthology 5.2 | supplier | 0.226372 |
17035 | Greek Anthology 5.2 | villes | 0.226372 |
14348 | Greek Anthology 5.2 | accorde | 0.210205 |
14722 | Greek Anthology 5.2 | brûler | 0.210205 |
Les mots-clés avec le résultat le plus élévé:
tfidf_df.sort_values(by='tfidf', ascending=False).head(50)
document | term | tfidf | |
---|---|---|---|
282602 | Greek Anthology 5.91 | parfum | 0.833659 |
452379 | Greek Anthology 5.147 | tresserai | 0.831331 |
430376 | Greek Anthology 5.143 | couronne | 0.769574 |
350366 | Greek Anthology 5.115 | démô | 0.747863 |
547996 | Greek Anthology 5.182 | dorcas | 0.712228 |
279737 | Greek Anthology 5.90 | parfum | 0.707856 |
154091 | Greek Anthology 5.81 | roses | 0.707594 |
138386 | Greek Anthology 5.42 | déteste | 0.695684 |
591619 | Greek Anthology 5.197 | jure | 0.651053 |
268582 | Greek Anthology 5.86 | rapides | 0.630348 |
471045 | Greek Anthology 5.154 | gracieuse | 0.629178 |
117372 | Greek Anthology 5.34 | zeus | 0.607010 |
475504 | Greek Anthology 5.155 | âme | 0.600876 |
116390 | Greek Anthology 5.34 | or | 0.573892 |
427511 | Greek Anthology 5.142 | couronne | 0.567477 |
298692 | Greek Anthology 5.97 | dieu | 0.564334 |
363537 | Greek Anthology 5.119 | tourne | 0.560606 |
86234 | Greek Anthology 5.24 | avertit | 0.559712 |
439544 | Greek Anthology 5.146 | grâces | 0.558608 |
558754 | Greek Anthology 5.186 | aimes | 0.544756 |
427601 | Greek Anthology 5.142 | denys | 0.540659 |
453869 | Greek Anthology 5.148 | grâces | 0.526554 |
489341 | Greek Anthology 5.160 | sabbat | 0.518416 |
532536 | Greek Anthology 5.176 | terrible | 0.515981 |
234114 | Greek Anthology 5.71 | protomachos | 0.509846 |
309779 | Greek Anthology 5.101 | bonjour | 0.500076 |
237653 | Greek Anthology 5.72 | vite | 0.496751 |
331205 | Greek Anthology 5.108 | nom | 0.491863 |
411970 | Greek Anthology 5.136 | répète | 0.488525 |
70163 | Greek Anthology 5.1 | jeunes | 0.471226 |
87079 | Greek Anthology 5.24 | fuir | 0.469380 |
150680 | Greek Anthology 5.292 | nature | 0.468573 |
150123 | Greek Anthology 5.292 | gagner | 0.468573 |
147815 | Greek Anthology 5.45 | nature | 0.468573 |
147258 | Greek Anthology 5.45 | gagner | 0.468573 |
364639 | Greek Anthology 5.120 | dormir | 0.462042 |
107795 | Greek Anthology 5.31 | or | 0.459855 |
292947 | Greek Anthology 5.95 | dercylis | 0.458494 |
292392 | Greek Anthology 5.95 | aphrodites | 0.458494 |
484620 | Greek Anthology 5.159 | ceintures | 0.456738 |
414868 | Greek Anthology 5.137 | santé | 0.456704 |
108782 | Greek Anthology 5.31 | âge | 0.456385 |
128438 | Greek Anthology 5.38 | simylos | 0.455288 |
547963 | Greek Anthology 5.182 | dis | 0.451048 |
474331 | Greek Anthology 5.155 | modelée | 0.447760 |
146343 | Greek Anthology 5.45 | art | 0.447596 |
149208 | Greek Anthology 5.292 | art | 0.447596 |
49069 | Greek Anthology 5.19 | bouche | 0.446698 |
37609 | Greek Anthology 5.14 | bouche | 0.446698 |
40474 | Greek Anthology 5.15 | bouche | 0.446698 |
def getep(c):
for t in mes_textes:
if t['title'] == 'Greek Anthology '+c:
print(t)
getep('5.143')
{'title': 'Greek Anthology 5.143', 'texte': 'La couronne d’Héliodôra sur sa tête se flétrit\xa0; mais elle-même elle resplendit, couronne de sa couronne. '}