Nettoyer un texte : des exercices pour découvrir l’approche bag-of-words

Ce chapitre continue de présenter l’approche de nettoyage de données du NLP en s’appuyant sur le corpus de trois auteurs anglo-saxons : Mary Shelley, Edgar Allan Poe, H.P. Lovecraft. Dans cette série d’exercice nous mettons en oeuvre de manière plus approfondie les différentes méthodes présentées précédemment.

NLP
Exercice
Author

Lino Galiana

Published

2024-04-27

Cette page approfondit certains aspects présentés dans la partie introductive. Après avoir travaillé sur le Comte de Monte Cristo, on va continuer notre exploration de la littérature avec cette fois des auteurs anglophones :

Les données sont disponibles sur un CSV mis à disposition sur Github. L’URL pour les récupérer directement est https://github.com/GU4243-ADS/spring2018-project1-ginnyqg/raw/master/data/spooky.csv.

Le but va être dans un premier temps de regarder dans le détail les termes les plus fréquemment utilisés par les auteurs et de les représenter graphiquement. Il s’agit donc d’une approche basée sur l’analyse de fréquences. On prendra appui sur l’approche bag of words présentée dans le chapitre précédent1. Il n’y aura pas de modélisation particulière, ceci est réservé aux chapitres suivants.

Ce chapitre s’inspire de plusieurs ressources disponibles en ligne:

Les chapitres suivants permettront d’introduire aux enjeux de modélisation de corpus textuels. Dans un premier temps, le modèle LDA permettra d’explorer le principe des modèles bayésiens à couche cachées pour modéliser les sujets (topics) présents dans un corpus et segmenter ces topics selon les mots qui les composent.

Le dernier chapitre de la partie visera à prédire quel texte correspond à quel auteur à partir d’un modèle Word2Vec. Cela sera un pas supplémentaire dans la formalisation puisqu’il s’agira de représenter chaque mot d’un texte sous forme d’un vecteur de grande dimension, ce qui nous permettra de rapprocher les mots entre eux dans un espace complexe. Cette technique, dite des plongements de mots (Word Embeddings), permet ainsi de transformer une information complexe difficilement quantifiable comme un mot en un objet numérique qui peut ainsi être rapproché d’autres par des méthodes algébriques. Pour découvrir ce concept, ce post de blog est particulièrement utile. En pratique, la technique des plongements de mots permet d’obtenir des tableaux comme celui-ci :

Figure 1: Illustration de l’intérêt des embeddings (Galiana and Castillo 2022)

1 Librairies nécessaires

Cette page évoquera les principales librairies pour faire du NLP, notamment :

A celles-ci s’ajoute des librairies de représentations graphiques synthétiques comme WordCloud, Gensim et Pywaffle.

La liste des modules à importer est assez longue, la voici :

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import base64
import string
import re
import nltk

from collections import Counter
from time import time

# from sklearn.feature_extraction.stop_words import ENGLISH_STOP_WORDS as stopwords
from sklearn.metrics import log_loss
import matplotlib.pyplot as plt

#!pip install pywaffle
from pywaffle import Waffle

from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.decomposition import NMF, LatentDirichletAllocation

nltk.download("stopwords")
nltk.download("punkt")
nltk.download("genesis")
nltk.download("wordnet")
nltk.download("omw-1.4")
[nltk_data] Downloading package stopwords to /github/home/nltk_data...
[nltk_data]   Package stopwords is already up-to-date!
[nltk_data] Downloading package punkt to /github/home/nltk_data...
[nltk_data]   Package punkt is already up-to-date!
[nltk_data] Downloading package genesis to /github/home/nltk_data...
[nltk_data]   Unzipping corpora/genesis.zip.
[nltk_data] Downloading package wordnet to /github/home/nltk_data...
[nltk_data] Downloading package omw-1.4 to /github/home/nltk_data...
True

2 Données utilisées

Si vous ne faites pas l’exercice 1, pensez à charger les données en executant la fonction get_data.py :

import requests

url = "https://raw.githubusercontent.com/linogaliana/python-datascientist/master/content/NLP/get_data.py"
r = requests.get(url, allow_redirects=True)
open("getdata.py", "wb").write(r.content)

import getdata

train = getdata.create_train_dataframes()

Ce code introduit une base nommée train dans l’environnement.

Le jeu de données met ainsi en regard un auteur avec une phrase qu’il a écrite :

train.head()
Text Author ID
Id
id26305 This process, however, afforded me no means of... EAP 26305
id17569 It never once occurred to me that the fumbling... HPL 17569
id11008 In his left hand was a gold snuff box, from wh... EAP 11008
id27763 How lovely is spring As we looked from Windsor... MWS 27763
id12958 Finding nothing else, not even gold, the Super... HPL 12958

On peut se rendre compte que les extraits des 3 auteurs ne sont pas forcément équilibrés dans le jeu de données. Il faudra en tenir compte dans la prédiction.

fig = plt.figure()
g = sns.barplot(
    x=["Edgar Allen Poe", "Mary W. Shelley", "H.P. Lovecraft"],
    y=train["Author"].value_counts(),
)

2.1 Fréquence d’un mot

Avant de s’adonner à une analyse systématique du champ lexical de chaque auteur, on va se focaliser dans un premier temps sur un unique mot, le mot fear.

A l’issue de la question 1, vous devriez obtenir le tableau de fréquence suivant :

Text ID wordtoplot
Author
EAP This process, however, afforded me no means of... 2630511008096741351519322166071718908441148621... 70
HPL It never once occurred to me that the fumbling... 1756912958197641888620836080752790708121117330... 160
MWS How lovely is spring As we looked from Windsor... 2776322965009121673712799131170076400683052582... 211

Ceci permet d’obtenir le waffle chart suivant :

Figure 2.1: Répartition du terme fear dans le corpus de nos trois auteurs

On remarque ainsi de manière très intuitive le déséquilibre de notre jeu de données lorsqu’on se focalise sur le terme “peur” où Mary Shelley représente près de 50% des observations.

Si on reproduit cette analyse avec le terme “horror”, on peut en conclure que la peur est plus évoquée par Mary Shelley (sentiment assez naturel face à la créature du docteur Frankenstein) alors que Lovecraft n’a pas volé sa réputation d’écrivain de l’horreur !

2.2 Premier wordcloud

Pour aller plus loin dans l’analyse du champ lexical de chaque auteur, on peut représenter un wordcloud qui permet d’afficher chaque mot avec une taille proportionnelle au nombre d’occurrence de celui-ci.

Le wordcloud pour nos différents auteurs est le suivant :

Enfin, si on fait un histogramme des fréquences, cela donnera :

On voit ici que ce sont des mots communs, comme “the”, “of”, etc. sont très présents. Mais ils sont peu porteurs d’information, on peut donc les éliminer avant de faire une analyse syntaxique poussée. Ceci est une démonstration par l’exemple qu’il vaut mieux nettoyer le texte avant de l’analyser (sauf si on est intéressé par la loi de Zipf, cf. exercice suivant).

A noter que l’histogramme produit par le biais de Matplotlib ou Seaborn est peu lisible. Il vaut mieux privilégier Plotly pour faire celui-ci afin d’avoir les mots qui s’affichent en passant sa souris sur chaque barre.

2.3 Aparté : la loi de Zipf

Un modèle exponentiel peut se représenter par un modèle de Poisson ou, si les données sont très dispersées, par un modèle binomial négatif. Pour plus d’informations, consulter l’annexe de Galiana et al. (2020). La technique économétrique associée pour l’estimation est les modèles linéaires généralisés (GLM) qu’on peut utiliser en Python via le package statsmodels2:

\[ \mathbb{E}\bigg( f(n_i)|n_i \bigg) = \exp(\beta_0 + \beta_1 \log(n_i)) \]

Prenons les résultats de l’exercice précédent et enrichissons les du rang et de la fréquence d’occurrence d’un mot :

count_words = pd.DataFrame(
    {
        "counter": train.groupby("Author")
        .apply(lambda s: " ".join(s["Text"]).split())
        .apply(lambda s: Counter(s))
        .apply(lambda s: s.most_common())
        .explode()
    }
)
count_words[["word", "count"]] = pd.DataFrame(
    count_words["counter"].tolist(), index=count_words.index
)
count_words = count_words.reset_index()

count_words = count_words.assign(
    tot_mots_auteur=lambda x: (x.groupby("Author")["count"].transform("sum")),
    freq=lambda x: x["count"] / x["tot_mots_auteur"],
    rank=lambda x: x.groupby("Author")["count"].transform("rank", ascending=False),
)
/tmp/ipykernel_5393/3685081206.py:3: DeprecationWarning:

DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.

Commençons par représenter la relation entre la fréquence et le rang:

from plotnine import *

g = (
    ggplot(count_words)
    + geom_point(aes(y="freq", x="rank", color="Author"), alpha=0.4)
    + scale_x_log10()
    + scale_y_log10()
    + theme_minimal()
)

Nous avons bien, graphiquement, une relation log-linéaire entre les deux :

Avec statsmodels, vérifions plus formellement cette relation:

import statsmodels.api as sm

exog = sm.add_constant(np.log(count_words["rank"].astype(float)))

model = sm.GLM(
    count_words["freq"].astype(float), exog, family=sm.families.Poisson()
).fit()

# Afficher les résultats du modèle
print(model.summary())
                 Generalized Linear Model Regression Results                  
==============================================================================
Dep. Variable:                   freq   No. Observations:                69301
Model:                            GLM   Df Residuals:                    69299
Model Family:                 Poisson   Df Model:                            1
Link Function:                    Log   Scale:                          1.0000
Method:                          IRLS   Log-Likelihood:                -23.011
Date:                Sat, 27 Apr 2024   Deviance:                     0.065676
Time:                        19:51:34   Pearson chi2:                   0.0656
No. Iterations:                     5   Pseudo R-squ. (CS):          0.0002431
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const         -2.4388      1.089     -2.239      0.025      -4.574      -0.303
rank          -0.9831      0.189     -5.196      0.000      -1.354      -0.612
==============================================================================

Le coefficient de la régression est presque 1 ce qui suggère bien une relation quasiment log-linéaire entre le rang et la fréquence d’occurrence d’un mot. Dit autrement, le mot le plus utilisé l’est deux fois plus que le deuxième mot le plus fréquent qui l’est trois plus que le troisième, etc.

3 Nettoyage d’un texte

Les premières étapes dans le nettoyage d’un texte, qu’on a développé au cours du chapitre précédent, sont :

  • suppression de la ponctuation ;
  • suppression des stopwords.

Cela passe par la tokenisation d’un texte, c’est-à-dire la décomposition de celui-ci en unités lexicales (les tokens). Ces unités lexicales peuvent être de différentes natures, selon l’analyse que l’on désire mener. Ici, on va définir les tokens comme étant les mots utilisés.

Plutôt que de faire soi-même ce travail de nettoyage, avec des fonctions mal optimisées, on peut utiliser la librairie nltk comme détaillé précédemment.

Pour rappel, au début de l’exercice, train présente l’aspect suivant :

Text Author ID wordtoplot
Id
id26305 This process, however, afforded me no means of... EAP 26305 0
id17569 It never once occurred to me that the fumbling... HPL 17569 0

Après tokenisation, il devrait avoir cet aspect :

/tmp/ipykernel_5393/3502394793.py:4: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.
ID     Author
00001  MWS       [Idris, was, well, content, with, this, resolv...
00002  HPL       [I, was, faint, even, fainter, than, the, hate...
dtype: object

Après le retrait des stopwords, cela donnera :

Ce petit nettoyage permet d’arriver à un texte plus intéressant en termes d’analyse lexicale. Par exemple, si on reproduit l’analyse précédente… :

Pour aller plus loin dans l’harmonisation d’un texte, il est possible de mettre en place les classes d’équivalence développées dans la partie précédente afin de remplacer différentes variations d’un même mot par une forme canonique :

  • la racinisation (stemming) assez fruste mais rapide, notamment en présence de fautes d’orthographe. Dans ce cas, chevaux peut devenir chev mais être ainsi confondu avec chevet ou cheveux. Cette méthode est généralement plus simple à mettre en oeuvre, quoique plus fruste.

  • la lemmatisation qui requiert la connaissance des statuts grammaticaux (exemple : chevaux devient cheval). Elle est mise en oeuvre, comme toujours avec nltk, à travers un modèle. En l’occurrence, un WordNetLemmatizer (WordNet est une base lexicographique ouverte). Par exemple, les mots “women”, “daughters” et “leaves” seront ainsi lemmatisés de la manière suivante :

from nltk.stem import WordNetLemmatizer

lemm = WordNetLemmatizer()

for word in ["women", "daughters", "leaves"]:
    print(f"The lemmatized form of {word} is: {lemm.lemmatize(word)}")
The lemmatized form of women is: woman
The lemmatized form of daughters is: daughter
The lemmatized form of leaves is: leaf

On va se restreindre au corpus d’Edgar Allan Poe et repartir de la base de données brute :

Le WordNetLemmatizer donnera le résultat suivant :

This process , however , afforded me no means of ascertaining the dimensions of my dungeon ; as I might make its circuit , and return to the point whence I set out , without being aware of the fact ; so perfectly
---------------------------
This process , however , afforded me no mean of ascertaining the dimension of my dungeon ; a I might make it circuit , and return to the point whence I set out , without being aware of the fact ; so perfectly 

4 TF-IDF: calcul de fréquence

Le calcul tf-idf (term frequency–inverse document frequency) permet de calculer un score de proximité entre un terme de recherche et un document (c’est ce que font les moteurs de recherche).

  • La partie tf calcule une fonction croissante de la fréquence du terme de recherche dans le document à l’étude ;
  • La partie idf calcule une fonction inversement proportionnelle à la fréquence du terme dans l’ensemble des documents (ou corpus).

Le score total, obtenu en multipliant les deux composantes, permet ainsi de donner un score d’autant plus élevé que le terme est surréprésenté dans un document (par rapport à l’ensemble des documents). Il existe plusieurs fonctions, qui pénalisent plus ou moins les documents longs, ou qui sont plus ou moins smooth.

aaem ab aback abaft abandon abandoned abandoning abandonment abaout abased ... zodiacal zoilus zokkar zone zones zopyrus zorry zubmizzion zuro á¼
0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0 0.0 0.253506 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

5 rows × 24937 columns

Les lignes où les termes de abandon sont non nuls sont les suivantes :

Index([    4,   116,   215,   571,   839,  1042,  1052,  1069,  2247,  2317,
        2505,  3023,  3058,  3245,  3380,  3764,  3886,  4425,  5289,  5576,
        5694,  6812,  7500,  9013,  9021,  9077,  9560, 11229, 11395, 11451,
       11588, 11827, 11989, 11998, 12122, 12158, 12189, 13666, 15259, 16516,
       16524, 16759, 17547, 18019, 18072, 18126, 18204, 18251],
      dtype='int64')
aaem ab aback abaft abandon abandoned abandoning abandonment abaout abased ... zodiacal zoilus zokkar zone zones zopyrus zorry zubmizzion zuro á¼
4 0.0 0.0 0.0 0.0 0.000000 0.253506 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
116 0.0 0.0 0.0 0.0 0.000000 0.339101 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
215 0.0 0.0 0.0 0.0 0.235817 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
571 0.0 0.0 0.0 0.0 0.000000 0.143788 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
839 0.0 0.0 0.0 0.0 0.285886 0.000000 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

5 rows × 24937 columns

Author
MWS    22
HPL    15
EAP    13
Name: Text, dtype: int64

Les 10 scores les plus élevés sont les suivants :

['We could not fear we did not.' '"And now I do not fear death.'
 'Be of heart and fear nothing.' 'I smiled, for what had I to fear?'
 'Indeed I had no fear on her account.'
 'I have not the slightest fear for the result.'
 'At length, in an abrupt manner she asked, "Where is he?" "O, fear not," she continued, "fear not that I should entertain hope Yet tell me, have you found him?'
 '"I fear you are right there," said the Prefect.'
 'I went down to open it with a light heart, for what had I now to fear?']

On remarque que les scores les plus élevés sont soient des extraits courts où le mot apparait une seule fois, soit des extraits plus longs où le mot fear apparaît plusieurs fois.

5 Approche contextuelle : les n-grams

Jusqu’à présent, dans l’approche bag of words, l’ordre des mots n’avait pas d’importance. On considère qu’un texte est une collection de mots tirés indépendamment, de manière plus ou moins fréquente en fonction de leur probabilité d’occurrence. Cependant, tirer un mot particulier n’affecte pas les chances de tirer certains mots ensuite, de manière conditionnelle.

Une manière d’introduire des liens entre les séries de tokens sont les n-grams. On s’intéresse non seulement aux mots et à leur fréquence, mais aussi aux mots qui suivent. Cette approche est essentielle pour désambiguiser les homonymes. Le calcul de n-grams 3 constitue la méthode la plus simple pour tenir compte du contexte.

Pour être en mesure de mener cette analyse, il est nécessaire de télécharger un corpus supplémentaire :

import nltk

nltk.download("genesis")
nltk.corpus.genesis.words("english-web.txt")
[nltk_data] Downloading package genesis to /github/home/nltk_data...
[nltk_data]   Package genesis is already up-to-date!
['In', 'the', 'beginning', 'God', 'created', 'the', ...]

NLTK offre des methodes pour tenir compte du contexte. Pour ce faire, nous calculons les n-grams, c’est-à-dire l’ensemble des co-occurrences successives de mots n-à-n. En général, on se contente de bi-grams, au mieux de tri-grams:

  • les modèles de classification, analyse du sentiment, comparaison de documents, etc. qui comparent des n-grams avec n trop grands sont rapidement confrontés au problème de données sparse, cela réduit la capacité prédictive des modèles ;
  • les performances décroissent très rapidement en fonction de n, et les coûts de stockage des données augmentent rapidement (environ n fois plus élevé que la base de données initiale).

On va, rapidement, regarder dans quel contexte apparaît le mot fear dans l’oeuvre d’Edgar Allan Poe (EAP). Pour cela, on transforme d’abord le corpus EAP en tokens NLTK :

eap_clean = train[train["Author"] == "EAP"]
eap_clean = " ".join(eap_clean["Text"])
tokens = eap_clean.split()
print(tokens[:10])
text = nltk.Text(tokens)
print(text)
['This', 'process,', 'however,', 'afforded', 'me', 'no', 'means', 'of', 'ascertaining', 'the']
<Text: This process, however, afforded me no means of...>

Vous aurez besoin des fonctions BigramCollocationFinder.from_words et BigramAssocMeasures.likelihood_ratio :

Avec la méthode concordance (question 1), la liste devrait ressembler à celle-ci :

Exemples d'occurences du terme 'fear' :
Displaying 13 of 13 matches:
d quick unequal spoken apparently in fear as well as in anger. What he said wa
hutters were close fastened, through fear of robbers, and so I knew that he co
to details. I even went so far as to fear that, as I occasioned much trouble, 
years of age, was heard to express a fear "that she should never see Marie aga
ich must be entirely remodelled, for fear of serious accident I mean the steel
 my arm, and I attended her home. 'I fear that I shall never see Marie again.'
clusion here is absurd. "I very much fear it is so," replied Monsieur Maillard
bt of ultimately seeing the Pole. "I fear you are right there," said the Prefe
er occurred before.' Indeed I had no fear on her account. For a moment there w
erhaps so," said I; "but, Legrand, I fear you are no artist. It is my firm int
 raps with a hammer. Be of heart and fear nothing. My daughter, Mademoiselle M
e splendor. I have not the slightest fear for the result. The face was so far 
arriers of iron that hemmed me in. I fear you have mesmerized" adding immediat

Même si on peut facilement voir le mot avant et après, cette liste est assez difficile à interpréter car elle recoupe beaucoup d’informations.

La collocation consiste à trouver les bi-grammes qui apparaissent le plus fréquemment ensemble. Parmi toutes les paires de deux mots observées, il s’agit de sélectionner, à partir d’un modèle statistique, les “meilleures”. On obtient donc avec cette méthode (question 2):

[('of', 'the'),
 ('in', 'the'),
 ('had', 'been'),
 ('to', 'be'),
 ('have', 'been'),
 ('I', 'had'),
 ('It', 'was'),
 ('it', 'is'),
 ('could', 'not'),
 ('from', 'the'),
 ('upon', 'the'),
 ('more', 'than'),
 ('it', 'was'),
 ('would', 'have'),
 ('with', 'a'),
 ('did', 'not'),
 ('I', 'am'),
 ('the', 'a'),
 ('at', 'once'),
 ('might', 'have')]

Si on modélise les meilleures collocations:

"Gad Fly"
'Hum Drum,'
'Rowdy Dow,'
Brevet Brigadier
Barrière du
ugh ugh
Ourang Outang
Chess Player
John A.
A. B.
hu hu
General John
'Oppodeldoc,' whoever
mille, mille,
Brigadier General

Cette liste a un peu plus de sens, on a des noms de personnages, de lieux mais aussi des termes fréquemment employés ensemble (Chess Player par exemple).

En ce qui concerne les collocations du mot fear :

[('fear', 'of'), ('fear', 'God'), ('I', 'fear'), ('the', 'fear'), ('The', 'fear'), ('fear', 'him'), ('you', 'fear')]

Si on mène la même analyse pour le terme love, on remarque que de manière logique, on retrouve bien des sujets généralement accolés au verbe :

[('love', 'me'), ('love', 'he'), ('will', 'love'), ('I', 'love'), ('love', ','), ('you', 'love'), ('the', 'love')]

6 Références

Informations additionnelles

environment files have been tested on.

Latest built version: 2024-04-27

Python version used:

'3.11.6 | packaged by conda-forge | (main, Oct  3 2023, 10:40:35) [GCC 12.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.12.2
aiohttp 3.9.3
aioitertools 0.11.0
aiosignal 1.3.1
alembic 1.13.1
aniso8601 9.0.1
annotated-types 0.6.0
appdirs 1.4.4
archspec 0.2.3
astroid 3.1.0
asttokens 2.4.1
attrs 23.2.0
Babel 2.14.0
bcrypt 4.1.2
beautifulsoup4 4.12.3
black 24.4.2
blinker 1.7.0
blis 0.7.11
bokeh 3.4.0
boltons 23.1.1
boto3 1.34.51
botocore 1.34.51
branca 0.7.1
Brotli 1.1.0
cachetools 5.3.3
cartiflette 0.0.2
Cartopy 0.23.0
catalogue 2.0.10
cattrs 23.2.3
certifi 2024.2.2
cffi 1.16.0
charset-normalizer 3.3.2
chromedriver-autoinstaller 0.6.4
click 8.1.7
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.16.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
commonmark 0.9.1
conda 24.3.0
conda-libmamba-solver 24.1.0
conda-package-handling 2.2.0
conda_package_streaming 0.9.0
confection 0.1.4
contextily 1.6.0
contourpy 1.2.1
cryptography 42.0.5
cycler 0.12.1
cymem 2.0.8
cytoolz 0.12.3
dask 2024.4.1
dask-expr 1.0.10
debugpy 1.8.1
decorator 5.1.1
dill 0.3.8
distributed 2024.4.1
distro 1.9.0
docker 7.0.0
duckdb 0.10.1
en-core-web-sm 3.7.1
entrypoints 0.4
et-xmlfile 1.1.0
exceptiongroup 1.2.0
executing 2.0.1
fastjsonschema 2.19.1
fiona 1.9.6
flake8 7.0.0
Flask 3.0.2
folium 0.16.0
fontawesomefree 6.5.1
fonttools 4.51.0
fr-core-news-sm 3.7.0
frozenlist 1.4.1
fsspec 2023.12.2
GDAL 3.8.4
gensim 4.3.2
geographiclib 2.0
geopandas 0.12.2
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.29.0
graphene 3.3
graphql-core 3.2.3
graphql-relay 3.2.0
graphviz 0.20.3
great-tables 0.5.0
greenlet 3.0.3
gunicorn 21.2.0
h11 0.14.0
htmltools 0.5.1
hvac 2.1.0
idna 3.6
imageio 2.34.1
importlib_metadata 7.1.0
importlib_resources 6.4.0
inflate64 1.0.0
ipykernel 6.29.3
ipython 8.22.2
ipywidgets 8.1.2
isort 5.13.2
itsdangerous 2.1.2
jedi 0.19.1
Jinja2 3.1.3
jmespath 1.0.1
joblib 1.3.2
jsonpatch 1.33
jsonpointer 2.4
jsonschema 4.21.1
jsonschema-specifications 2023.12.1
jupyter-cache 1.0.0
jupyter_client 8.6.1
jupyter_core 5.7.2
jupyterlab_widgets 3.0.10
kaleido 0.2.1
kiwisolver 1.4.5
kubernetes 29.0.0
langcodes 3.4.0
language_data 1.2.0
lazy_loader 0.4
libmambapy 1.5.7
llvmlite 0.42.0
locket 1.0.0
lxml 5.2.1
lz4 4.3.3
Mako 1.3.2
mamba 1.5.7
mapclassify 2.6.1
marisa-trie 1.1.0
Markdown 3.6
MarkupSafe 2.1.5
matplotlib 3.8.3
matplotlib-inline 0.1.6
mccabe 0.7.0
menuinst 2.0.2
mercantile 1.2.1
mizani 0.11.2
mlflow 2.11.3
mlflow-skinny 2.11.3
msgpack 1.0.7
multidict 6.0.5
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.10
mypy 1.9.0
mypy-extensions 1.0.0
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.3
nltk 3.8.1
numba 0.59.1
numpy 1.26.4
oauthlib 3.2.2
opencv-python-headless 4.9.0.80
openpyxl 3.1.2
outcome 1.3.0.post0
OWSLib 0.28.1
packaging 23.2
pandas 2.2.1
paramiko 3.4.0
parso 0.8.4
partd 1.4.1
pathspec 0.12.1
patsy 0.5.6
Pebble 5.0.7
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.3.0
pip 24.0
pkgutil_resolve_name 1.3.10
platformdirs 4.2.0
plotly 5.19.0
plotnine 0.13.5
pluggy 1.4.0
polars 0.20.18
preshed 3.0.9
prometheus_client 0.20.0
prometheus-flask-exporter 0.23.0
prompt-toolkit 3.0.42
protobuf 4.25.3
psutil 5.9.8
ptyprocess 0.7.0
pure-eval 0.2.2
py7zr 0.20.8
pyarrow 15.0.0
pyarrow-hotfix 0.6
pyasn1 0.5.1
pyasn1-modules 0.3.0
pybcj 1.0.2
pycodestyle 2.11.1
pycosat 0.6.6
pycparser 2.21
pycryptodomex 3.20.0
pydantic 2.7.1
pydantic_core 2.18.2
pyflakes 3.2.0
Pygments 2.17.2
PyJWT 2.8.0
pylint 3.1.0
PyNaCl 1.5.0
pynsee 0.1.7
pyOpenSSL 24.0.0
pyparsing 3.1.2
pyppmd 1.1.0
pyproj 3.6.1
pyshp 2.3.1
PySocks 1.7.1
python-dateutil 2.9.0
python-dotenv 1.0.1
python-magic 0.4.27
pytz 2024.1
pyu2f 0.1.5
pywaffle 1.1.0
PyYAML 6.0.1
pyzmq 25.1.2
pyzstd 0.15.10
QtPy 2.4.1
querystring-parser 1.2.4
rasterio 1.3.10
referencing 0.34.0
regex 2023.12.25
requests 2.31.0
requests-cache 1.2.0
requests-oauthlib 2.0.0
rpds-py 0.18.0
rsa 4.9
Rtree 1.2.0
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.10.1
scikit-image 0.23.2
scikit-learn 1.4.1.post1
scipy 1.13.0
seaborn 0.13.2
selenium 4.20.0
setuptools 69.2.0
shapely 2.0.3
six 1.16.0
smart-open 6.4.0
smmap 5.0.0
sniffio 1.3.1
snuggs 1.4.7
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.7.4
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.29
sqlparse 0.4.4
srsly 2.4.8
stack-data 0.6.2
statsmodels 0.14.1
tabulate 0.9.0
tblib 3.0.0
tenacity 8.2.3
texttable 1.7.0
thinc 8.2.3
threadpoolctl 3.4.0
tifffile 2024.4.24
tomli 2.0.1
tomlkit 0.12.4
toolz 0.12.1
topojson 1.8
tornado 6.4
tqdm 4.66.2
traitlets 5.14.2
trio 0.25.0
trio-websocket 0.11.1
truststore 0.8.0
typer 0.9.4
typing_extensions 4.11.0
tzdata 2024.1
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.18
wasabi 1.1.2
wcwidth 0.2.13
weasel 0.3.4
webcolors 1.13
webdriver-manager 4.0.1
websocket-client 1.7.0
Werkzeug 3.0.2
wheel 0.43.0
widgetsnbextension 4.0.10
wordcloud 1.9.3
wrapt 1.16.0
wsproto 1.2.0
xgboost 2.0.3
xlrd 2.0.1
xyzservices 2024.4.0
yarl 1.9.4
yellowbrick 1.5
zict 3.0.0
zipp 3.17.0
zstandard 0.22.0

View file history

SHA Date Author Description
06d003a 2024-04-23 10:09:22 Lino Galiana Continue la restructuration des sous-parties (#492)
005d89b 2023-12-20 17:23:04 Lino Galiana Finalise l’affichage des statistiques Git (#478)
3437373 2023-12-16 20:11:06 Lino Galiana Améliore l’exercice sur le LASSO (#473)
4cd44f3 2023-12-11 17:37:50 Antoine Palazzolo Relecture NLP (#474)
deaafb6 2023-12-11 13:44:34 Thomas Faria Relecture Thomas partie NLP (#472)
1f23de2 2023-12-01 17:25:36 Lino Galiana Stockage des images sur S3 (#466)
a1ab3d9 2023-11-24 10:57:02 Lino Galiana Reprise des chapitres NLP (#459)
a06a268 2023-11-23 18:23:28 Antoine Palazzolo 2ème relectures chapitres ML (#457)
09654c7 2023-11-14 15:16:44 Antoine Palazzolo Suggestions Git & Visualisation (#449)
889a71b 2023-11-10 11:40:51 Antoine Palazzolo Modification TP 3 (#443)
a771183 2023-10-09 11:27:45 Antoine Palazzolo Relecture TD2 par Antoine (#418)
154f09e 2023-09-26 14:59:11 Antoine Palazzolo Des typos corrigées par Antoine (#411)
a8f90c2 2023-08-28 09:26:12 Lino Galiana Update featured paths (#396)
8082302 2023-08-25 17:48:36 Lino Galiana Mise à jour des scripts de construction des notebooks (#395)
3bdf3b0 2023-08-25 11:23:02 Lino Galiana Simplification de la structure 🤓 (#393)
f2905a7 2023-08-11 17:24:57 Lino Galiana Introduction de la partie NLP (#388)
78ea2cb 2023-07-20 20:27:31 Lino Galiana Change titles levels (#381)
a9b384e 2023-07-18 18:07:16 Lino Galiana Sépare les notebooks (#373)
29ff3f5 2023-07-07 14:17:53 linogaliana description everywhere
f21a24d 2023-07-02 10:58:15 Lino Galiana Pipeline Quarto & Pages 🚀 (#365)
934149d 2023-02-13 11:45:23 Lino Galiana get_feature_names is deprecated in scikit 1.0.X versions (#351)
164fa68 2022-11-30 09:13:45 Lino Galiana Travail partie NLP (#328)
f10815b 2022-08-25 16:00:03 Lino Galiana Notebooks should now look more beautiful (#260)
494a85a 2022-08-05 14:49:56 Lino Galiana Images featured ✨ (#252)
d201e3c 2022-08-03 15:50:34 Lino Galiana Pimp la homepage ✨ (#249)
12965ba 2022-05-25 15:53:27 Lino Galiana :launch: Bascule vers quarto (#226)
9c71d6e 2022-03-08 10:34:26 Lino Galiana Plus d’éléments sur S3 (#218)
3299f1d 2022-01-08 16:50:11 Lino Galiana Clean NLP notebooks (#215)
09b60a1 2021-12-21 19:58:58 Lino Galiana Relecture suite du NLP (#205)
495599d 2021-12-19 18:33:05 Lino Galiana Des éléments supplémentaires dans la partie NLP (#202)
17092b2 2021-12-13 09:17:13 Lino Galiana Retouches partie NLP (#199)
3c87483 2021-12-13 08:46:52 Lino Galiana Notebooks NLP update (#198)
2a8809f 2021-10-27 12:05:34 Lino Galiana Simplification des hooks pour gagner en flexibilité et clarté (#166)
2e4d586 2021-09-02 12:03:39 Lino Galiana Simplify badges generation (#130)
49e2826 2021-05-13 18:11:20 Lino Galiana Corrige quelques images n’apparaissant pas (#108)
4cdb759 2021-05-12 10:37:23 Lino Galiana :sparkles: :star2: Nouveau thème hugo :snake: :fire: (#105)
7f9f97b 2021-04-30 21:44:04 Lino Galiana 🐳 + 🐍 New workflow (docker 🐳) and new dataset for modelization (2020 🇺🇸 elections) (#99)
d164635 2020-12-08 16:22:00 Lino Galiana :books: Première partie NLP (#87)
Back to top

References

Galiana, Lino, and Milena Suarez Castillo. 2022. “Fuzzy Matching on Big-Data an Illustration with Scanner Data and Crowd-Sourced Nutritional Data.”
Galiana, Lino, François Sémécurbe, Benjamin Sakarovitch, and Zbigniew Smoreda. 2020. “Residential Segregation, Daytime Segregation and Spatial Frictions: An Analysis from Mobile Phone Data.”

Footnotes

  1. L’approche bag of words est déjà, si on la pousse à ses limites, très intéressante. Elle peut notamment faciliter la mise en cohérence de différents corpus par la méthode des appariements flous (cf. Galiana and Castillo (2022). Le chapitre sur ElasticSearch présent dans cette partie du cours présente quelques éléments de ce travail sur les données de l’OpenFoodFacts.↩︎

  2. La littérature sur les modèles gravitaires, présentée dans Galiana et al. (2020), donne quelques arguments pour privilégier les modèles GLM à des modèles log-linéaires estimés par moindres carrés ordinaires.↩︎

  3. On parle de bigrams pour les co-occurences de mots deux-à-deux, trigrams pour les co-occurences trois-à-trois, etc.↩︎

Citation

BibTeX citation:
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python Pour La Data Science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {en}
}
For attribution, please cite this work as:
Galiana, Lino. 2023. Python Pour La Data Science. https://doi.org/10.5281/zenodo.8229676.