Python : trier les n-grammes

Résolu/Fermé
GwendoDrum Messages postés 5 Date d'inscription samedi 2 juillet 2022 Statut Membre Dernière intervention 2 juillet 2022 - 2 juil. 2022 à 11:10
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 - 2 juil. 2022 à 13:35
Bonjour,

J'ai calculé les bigrammes (et n-grammes) présents dans un texte assez volumineux, ainsi que leurs fréquences respectives grâce au code suivant :

bigrams = nltk.bigrams(tokens)

fdist = nltk.FreqDist(bigrams)
for x,y in fdist.items():
print (x,y)

Ce qui me donne une longue liste de résultats sous la forme :
('mot1', 'mot2) n

avec n la fréquence d'apparition de chaque bigramme.

Maintenant, pour pouvoir exploiter ces bigrammes, j'aimerais :
1. Trier cette liste, pour afficher en premier les n les plus grands vers les n les plus petits
2. Filtrer cette liste pour ne faire apparaitre que certains mots qui m'intéressent

Je suis encore débutante sur Python et j'ai du mal à savoir quelles méthodes et fonctions utiliser pour quel format, par conséquent je n'ai pas la moindre idée de comment je peux m'y prendre pour atteindre ces objectifs.

Configuration: Macintosh / Firefox 102.0

5 réponses

yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juil. 2022 à 11:30
bonjour,
nous pourrons être plus précis si tu partages ton code (veille à utiliser les balises : https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code.
au minimum, décris précisément le type et le contenu de ta liste de résultats.

un exemple de tri qui précise que la clé de tri est le second élément de chaque tuple.
l=[(("a","b"),5),(("x","y"),12),(("k","l"),3)]
print(type(l),l)
for x in l:
    print(type(x),x)
l.sort( key=lambda e: e[1])
print(type(l),l)
0
GwendoDrum Messages postés 5 Date d'inscription samedi 2 juillet 2022 Statut Membre Dernière intervention 2 juillet 2022
2 juil. 2022 à 11:57
Merci pour la réponse, et désolée pour le code, je n'ai pas encore l'habitude d'utiliser cette façon de faire. Du coup, je suis partie d'un DataFrame qui contient une colonne de texte (Commentaire) sur laquelle j'ai fait tous les traitements pour le nettoyage. Ensuite j'ai importé ce texte dans une liste que j'ai ensuite tokenisée pour pouvoir créer mes bigrammes, ce qui donne :
text = ""
for comment in df["Commentaire"]:
    text += comment

tokens = nltk.word_tokenize(text)

bigrams = nltk.bigrams(tokens)

fdist = nltk.FreqDist(bigrams)
for x,y in fdist.items():
  print (x,y) 


Au niveau de la sortie, voici un petit exemple de ce que je peux avoir (parmi quelques milliers de lignes) :
('salle', 'fitness') 1
('fitness', 'fermes') 1
('fermes', 'travaux') 1
('travaux', 'occasionnent') 1
('occasionnent', 'bruit') 1

Si je comprends bien ta réponse, il faudrait que je commence par créer un tuple qui prenne en résultat ma sortie ? J'ai fait un essai en modifiant la dernière partie de mon code comme ça :
bigrams = nltk.bigrams(tokens)
l = []

fdist = nltk.FreqDist(bigrams)
for x,y in fdist.items():
  l = x,y


Mais quand je vérifie avec un print(l) je n'ai qu'un seul bigramme qui s'est enregistré dedans.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juil. 2022 à 12:12
moi je ferais plutôt
print(type(fdist),fdist)
pour comprendre ce que contient fdist.
Tu fais un import que tu ne nous montres pas?
0
GwendoDrum Messages postés 5 Date d'inscription samedi 2 juillet 2022 Statut Membre Dernière intervention 2 juillet 2022
2 juil. 2022 à 12:21
Pour les imports j'utilise seulement nltk que j'importe comme ça

import nltk
nltk.download('punkt')


J'ai utilisé la fonction FreqDist de nltk qui permet de calculer la fréquence et je l'ai utilisée pour chaque bigramme de la façon dont j'ai montré dans mon message précédent.

Je ne suis pas toujours très à l'aise avec les types, mais j'ai essayé la ligne que tu proposes et voilà ce que me ressort mon jupyter notebook

<class 'nltk.probability.FreqDist'> <FreqDist with 80625 samples and 106634 outcomes>
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juil. 2022 à 12:35
Pour obtenir une liste triée, je pense que tu peux faire:
ltri=sorted(fdist.items(),key= lambda x: -x[1]) 
for i in range(10):
    print(ltri[i])

Cela devrait afficher les 10 premiers éléments, pour vérifier si le tri est correct.
1
GwendoDrum Messages postés 5 Date d'inscription samedi 2 juillet 2022 Statut Membre Dernière intervention 2 juillet 2022
2 juil. 2022 à 12:49
Ouah super ça a marché ! Merci beaucoup !

Par contre je ne comprends pas bien ce qui se passe au niveau du key= lambda x: -x[1]
Que fais exactement le -x ?
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juil. 2022 à 12:58
Si x est un élément dans le résultat,
x c'est
('mot1', 'mot2) n

x[1], c'est n

Et on prends -x[1] comme clé de tri, puisque tu veux un tri descendant sur n
1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
GwendoDrum Messages postés 5 Date d'inscription samedi 2 juillet 2022 Statut Membre Dernière intervention 2 juillet 2022
2 juil. 2022 à 13:10
Super merci beaucoup !
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juil. 2022 à 13:35
Le moment venu, peux-tu marquer la discussion comme résolue, via les
...
en dessous de ta question initiale?
0