<jupyter_start><jupyter_text>TP2 - <NAME>  Extraire les mots-clés relatifs à l'année 1865<jupyter_code>import os
import yake<jupyter_output><empty_output><jupyter_text>Extraire les mots clés d'un document avec Yake https://github.com/LIAAD/yake<jupyter_code># Création d'une liste de mots à ignorer
ignored = set(["conseil communal", "conseil général"])
ignored
# Instantier l'extracteur de mots clés
kw_extractor = yake.KeywordExtractor(lan="fr", top=50)
kw_extractor
# Lister les Fichiers
data_path = "../data/txt/"
files = os.listdir(data_path)
# Enlever les fichiers qui ne commencent pas par Bxl_1865
bxl_files = [f for f in files if f.startswith('Bxl_1865')]
len(bxl_files)
# Lister les fichiers de cette année
data_path = '../data'
txt_path = '../data/txt'
txts = [f for f in os.listdir(txt_path) if os.path.isfile(os.path.join(txt_path, f)) and str(1865) in f]
txts
# Stocker le contenu de ces fichiers dans une liste
content_list = []
for txt in txts:
    with open(os.path.join(txt_path, txt), 'r') as f:
        content_list.append(f.read())
# Compter le nombre d'éléments (=fichiers) dans la liste
len(content_list)
# Imprimer les 200 premiers caractères du contenu du premier fichier
content_list[0][:200]
# Ecrire tout le contenu dans un fichier temporaire
temp_path = '../data/tmp'
if not os.path.exists(temp_path):
    os.mkdir(temp_path)
with open(os.path.join(temp_path, f'{1865}.txt'), 'w') as f:
    f.write(' '.join(content_list))
# Imprimer le contenu du fichier et constater les "déchets"
with open(os.path.join(temp_path, f'{1865}.txt'), 'r') as f:
    before = f.read()

before[:500]
# Extraire les mots clés de ce texte
keywords = kw_extractor.extract_keywords(before)
keywords<jupyter_output><empty_output><jupyter_text>Liste de stopwords et un nuage de mots pour l'année 1865<jupyter_code>from collections import Counter
from wordcloud import WordCloud
import os
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
from IPython.display import Image
# Stopwords
sw = stopwords.words("french")
sw += ["les", "plus", "cette", "fait", "faire", "être", "deux", "comme", "dont", "tout",
       "ils", "bien", "sans", "peut", "tous", "après", "ainsi", "donc", "cet", "sous",
       "celle", "entre", "encore", "toutes", "pendant", "moins", "dire", "cela", "non",
       "faut", "trois", "aussi", "dit", "avoir", "doit", "contre", "depuis", "autres",
       "van", "het", "autre", "jusqu", "ville", "alors", "au", "aucuns", "aussi",
       "autre", "avant", "avec", "avoir", "bon", "car", "ce", "cela", "ces", "ceux",
       "chaque", "ci", "comme", "comment", "dans", "des", "du", "dedans", "dehors",
       "depuis", "devrait", "doit", "donc", "dos", "début", "elle", "elles", "en",
       "encore", "essai", "est", "et", "eu", "fait", "faites", "fois", "font", "hors",
       "ici", "il", "ils", "je", "la", "le", "les", "leur", "là", "ma", "maintenant",
       "mais", "mes", "mien", "moins", "mon", "mot", "même", "ni", "nommés", "notre",
       "nous", "ou", "où", "par", "parce", "pas", "peut", "peu", "plupart", "pour",
       "pourquoi", "quand", "que", "quel", "quelle", "quelles", "quels", "qui", "sa",
       "sans", "ses", "seulement", "si", "sien", "son", "sont", "sous", "soyez	sujet",
       "sur", "ta", "tandis", "tellement", "tels", "tes", "ton", "tous", "tout",
       "trop", "très", "tu", "voient", "vont", "votre", "vous", "vu", "ça", "étaient",
       "état", "étions", "été", "être"]
sw = set(sw)<jupyter_output><empty_output><jupyter_text>Créer un fichier contenant le texte de tous les bulletins d'une année donnée<jupyter_code># Choisir une année
year = 1865
# Lister les fichiers de cette année
data_path = '../data'
txt_path = '../data/txt'
txts = [f for f in os.listdir(txt_path) if os.path.isfile(os.path.join(txt_path, f)) and str(year) in f]
txts
# Stocker le contenu de ces fichiers dans une liste
content_list = []
for txt in txts:
    with open(os.path.join(txt_path, txt), 'r') as f:
        content_list.append(f.read())
# Compter le nombre d'éléments (=fichiers) dans la liste
len(content_list)
# Ecrire tout le contenu dans un fichier temporaire
temp_path = '../data/tmp'
if not os.path.exists(temp_path):
    os.mkdir(temp_path)
with open(os.path.join(temp_path, f'{year}.txt'), 'w') as f:
    f.write(' '.join(content_list))
# Imprimer le contenu du fichier et constater les "déchets"
with open(os.path.join(temp_path, f'{year}.txt'), 'r') as f:
    before = f.read()

before[:500]<jupyter_output><empty_output><jupyter_text>Nettoyer le fichier à l'aide d'une fonction de nettoyage  Créer la fonction de nettoyage<jupyter_code>def clean_text(year, folder=None):
    if folder is None:
        input_path = f"{year}.txt"
        output_path = f"{year}_clean.txt"
    else:
        input_path = f"{folder}/{year}.txt"
        output_path = f"{folder}/{year}_clean.txt"
    output = open(output_path, "w", encoding='utf-8')
    with open(input_path, encoding='utf-8') as f:
        text = f.read()
        words = nltk.wordpunct_tokenize(text)
        kept = [w.lower() for w in words if len(w) > 2 and w.isalpha() and w.lower() not in sw]
        kept_string = " ".join(kept)
        output.write(kept_string)
    return f'Output has been written in {output_path}!'<jupyter_output><empty_output><jupyter_text>Appliquer la fonction sur le fichier complet de l'année<jupyter_code>clean_text(year, folder=temp_path)
# Vérifier le résultat
with open(os.path.join(temp_path, f'{year}_clean.txt'), 'r') as f:
    after = f.read()

after[:500]<jupyter_output><empty_output><jupyter_text>Nuage de mots  Afficher les termes les plus fréquents<jupyter_code>frequencies = Counter(after.split())
print(frequencies.most_common(10))<jupyter_output>[('rue', 2052), ('collège', 983), ('bruxelles', 922), ('conseil', 908), ('section', 780), ('travaux', 775), ('bourgmestre', 726), ('francs', 721), ('projet', 576), ('rapport', 547)]<jupyter_text>Créer, stocker et afficher le nuage de mots<jupyter_code>cloud = WordCloud(width=2000, height=1000, background_color='khaki').generate_from_frequencies(frequencies)
cloud.to_file(os.path.join(temp_path, f"{year}.png"))
Image(filename=os.path.join(temp_path, f"{year}.png"))<jupyter_output><empty_output><jupyter_text>Comment trouver les entités nommées principales (personnes, organisations et lieux) pertinentes pour l'année 1865 avec SpaCy<jupyter_code>from collections import defaultdict
import sys
import spacy
from spacy.lang.fr.examples import sentences
nlp = spacy.load('fr_core_news_md')
# Charger le texte
n=900000
text = open("../data/tmp/1865_clean.txt", encoding='utf-8').read()[:n]
%%time
# Traiter le texte

doc = nlp(text)<jupyter_output>CPU times: user 1min 51s, sys: 5.34 s, total: 1min 57s
Wall time: 2min 1s<jupyter_text>Personnes<jupyter_code># Compter les entités
people = defaultdict(int)
for ent in doc.ents:
    if ent.label_ == "PER" and len(ent.text) > 3:
        people[ent.text] += 1
# Trier et imprimer

sorted_people = sorted(people.items(), key=lambda kv: kv[1], reverse=True)

for person, freq in sorted_people[:50]:
    print(f"{person} apparait {freq} fois dans les corpus de 1865")<jupyter_output>echevin watteeu apparait 79 fois dans les corpus de 1865
anspach apparait 74 fois dans les corpus de 1865
beyaert apparait 53 fois dans les corpus de 1865
<NAME> apparait 31 fois dans les corpus de 1865
goffart apparait 30 fois dans les corpus de 1865
messieurs apparait 28 fois dans les corpus de 1865
fontainas apparait 27 fois dans les corpus de 1865
bischoffsheim apparait 24 fois dans les corpus de 1865
watteeu apparait 22 fois dans les corpus de 1865
vadder apparait 21 fois dans les corpus de 1865
<NAME> apparait 18 fois dans les corpus de 1865
waux hall apparait 18 fois dans les corpus de 1865
lacomblé collège anspach apparait 16 fois dans les corpus de 1865
<NAME> apparait 16 fois dans les corpus de 1865
leclercq apparait 16 fois dans les corpus de 1865
lacomblé apparait 15 fois dans les corpus de 1865
walter apparait 14 fois dans les corpus de 1865
jacobs apparait 13 fois dans les corpus de 1865
depaire apparait 13 fois dans les corpus de 1865
anspach lacomb[...]<jupyter_text>Organisations<jupyter_code># Compter les organisations
organisation = defaultdict(int)
for ent in doc.ents:
    if ent.label_ == "ORG" and len(ent.text) > 3:
        organisation[ent.text] += 1
# Trier et imprimer

sorted_organisation = sorted(organisation.items(), key=lambda kv: kv[1], reverse=True)

for organisation, freq in sorted_organisation[:50]:
    print(f"{organisation} apparait {freq} fois dans les corpus de 1865")<jupyter_output>arenberg apparait 8 fois dans les corpus de 1865
anspach lacomblé apparait 6 fois dans les corpus de 1865
section desfinances apparait 4 fois dans les corpus de 1865
vanrotterdam rue apparait 3 fois dans les corpus de 1865
dewit apparait 3 fois dans les corpus de 1865
collège anspach apparait 2 fois dans les corpus de 1865
anspach lacomblé prix pain apparait 1 fois dans les corpus de 1865
blaes idem idem apparait 1 fois dans les corpus de 1865
porle apparait 1 fois dans les corpus de 1865
wyns rue apparait 1 fois dans les corpus de 1865
union artistes liégeois remerciments donateur apparait 1 fois dans les corpus de 1865
tarlier don bibliothèque populaire exemplaire recueil consulaire apparait 1 fois dans les corpus de 1865
vadder apparait 1 fois dans les corpus de 1865
conseil godefroy apparait 1 fois dans les corpus de 1865
godefroy apparait 1 fois dans les corpus de 1865
beiges elite apparait 1 fois dans les corpus de 1865
bruxelles programme arrêté apparait 1 fois dans les corpus d[...]<jupyter_text>Lieux<jupyter_code># Compter les lieux 
lieux = defaultdict(int)
for ent in doc.ents:
    if ent.label_ == "LOC" and len(ent.text) > 3:
        lieux[ent.text] += 1
# Trier et imprimer

sorted_lieux = sorted(lieux.items(), key=lambda kv: kv[1], reverse=True)

for lieux, freq in sorted_lieux[:50]:
    print(f"{lieux} apparait {freq} fois dans les corpus de 1865")<jupyter_output>bruxelles apparait 530 fois dans les corpus de 1865
paris apparait 28 fois dans les corpus de 1865
belgique apparait 23 fois dans les corpus de 1865
echevins bruxelles apparait 20 fois dans les corpus de 1865
rue namur apparait 17 fois dans les corpus de 1865
rue cantersteen apparait 15 fois dans les corpus de 1865
etterbeek apparait 10 fois dans les corpus de 1865
londres apparait 10 fois dans les corpus de 1865
singelé apparait 10 fois dans les corpus de 1865
rue granvelle apparait 9 fois dans les corpus de 1865
vanobbergen apparait 8 fois dans les corpus de 1865
rue parc apparait 8 fois dans les corpus de 1865
rue madeleine apparait 8 fois dans les corpus de 1865
rue anderlecht apparait 7 fois dans les corpus de 1865
etat apparait 7 fois dans les corpus de 1865
vilvorde apparait 6 fois dans les corpus de 1865
lacomblé collège anspach apparait 5 fois dans les corpus de 1865
angleterre apparait 5 fois dans les corpus de 1865
molenbeek apparait 5 fois dans les corpus de 1865
herpels ru[...]<jupyter_text>10 phrases dans les documents de l’année 1865 analysés à l’aide du Textblob-FR Documentation: https://textblob.readthedocs.io/en/dev/<jupyter_code>import sys
from textblob import Blobber
from textblob_fr import PatternTagger, PatternAnalyzer
tb = Blobber(pos_tagger=PatternTagger(), analyzer=PatternAnalyzer())

def get_sentiment(input_text):
    blob = tb(input_text)
    polarity, subjectivity = blob.sentiment
    polarity_perc = f"{100*abs(polarity):.0f}"
    subjectivity_perc = f"{100*subjectivity:.0f}"
    if polarity > 0:
        polarity_str = f"{polarity_perc}% positif"
    elif polarity < 0:
        polarity_str = f"{polarity_perc}% négatif"
    else:
        polarity_str = "neutre"
    if subjectivity > 0:
        subjectivity_str = f"{subjectivity}% subjectif"
    else:
        subjectivity_str = "parfaitement objectif"
    print(f"Ce texte est {polarity_str} et {subjectivity_str}.")<jupyter_output><empty_output><jupyter_text>Tokenizer "punky" pour diviser un texte en une liste de phrases<jupyter_code>nltk.download('punkt')
import random<jupyter_output>[nltk_data] Downloading package punkt to /root/nltk_data...
[nltk_data]   Package punkt is already up-to-date!<jupyter_text>Sélectionner arbitrairement des phrases dans les documents de l’année 1865<jupyter_code>text = open("../data/tmp/1865.txt", encoding='utf-8').read()[:n]
sentence = nltk.tokenize.sent_tokenize(text)
random_sentence = random.choice (sentence)<jupyter_output><empty_output><jupyter_text>Les 10 phrases arbitrairement choisies dans les documents de l’année de 1865<jupyter_code># Phrase N°1
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°2
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°3
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°4
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°5
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°6
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°7
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°8
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°9
print (random_sentence) 
get_sentiment(random_sentence)
# Phrase N°10
print (random_sentence) 
get_sentiment(random_sentence)
from tabulate import tabulate

l = [["Phrase N°1", 2, "0.10000000000000002% subjectif"], ["Phrase N°2", 0, "parfaitement objectif"], ["Phrase N°3", 14, "0.47500000000000003% subjectif"], ["Phrase N°4", 12, "0.35000000000000003% subjectif"],
     ["Phrase N°5", 0, "parfaitement objectif"], ["Phrase N°6", 25, "0.1% subjectif"], ["Phrase N°7", -10, "parfaitement objectif"], ["Phrase N°8", 4, "0.1875% subjectif"],
     ["Phrase N°9", -5, "0.1% subjectif"], ["Phrase N°10", 22, "0.265% subjectif"]]
table = tabulate(l, headers=['N° de Phrase', 'Polarité', 'Subjectivité'], tablefmt='orgtbl')

print(table)<jupyter_output>| N° de Phrase   |   Polarité | Subjectivité                   |
|----------------+------------+--------------------------------|
| Phrase N°1     |          2 | 0.10000000000000002% subjectif |
| Phrase N°2     |          0 | parfaitement objectif          |
| Phrase N°3     |         14 | 0.47500000000000003% subjectif |
| Phrase N°4     |         12 | 0.35000000000000003% subjectif |
| Phrase N°5     |          0 | parfaitement objectif          |
| Phrase N°6     |         25 | 0.1% subjectif                 |
| Phrase N°7     |        -10 | parfaitement objectif          |
| Phrase N°8     |          4 | 0.1875% subjectif              |
| Phrase N°9     |         -5 | 0.1% subjectif                 |
| Phrase N°10    |         22 | 0.265% subjectif               |
{'fraction_non_alphanumeric': 0.12695166018954115, 'fraction_numerical': 0.04615804186268494, 'mean_word_length': 4.483364485981308, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 68, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '23446', 'license': 'MIT', 'n_tokens_mistral': 5826, 'n_tokens_neox': 5140, 'n_words': 1613, 'path': 'TP2/tp2.ipynb', 'repo_name': 'svalmara/tac', 'size': '14704'}