Préparation des données pour construire un modèle

Afin d’avoir des données cohérentes avec les hypothèses de modélisation, il est absolument fondamental de prendre le temps de préparer les données à fournir à un modèle. La qualité de la prédiction dépend fortement de ce travail préalable qu’on appelle preprocessing. Beaucoup de méthodes sont disponibles dans scikit, ce qui rend ce travail moins fastidieux et plus fiable.

Modélisation
Exercice
Author

Lino Galiana

Published

2024-05-08

Ce chapitre utilise le jeu de données présenté dans l’introduction de cette partie : les données de vote aux élections présidentielles américaines de 2020 au niveau des comtés croisées à des variables socio-démographiques. Le code de consitution de la base de données est disponible sur Github. L’exercice 1 permet, à ceux qui le désirent, d’essayer de le reconstituer pas à pas.

Le guide utilisateur de Scikit est une référence précieuse, à consulter régulièrement. La partie sur le preprocessing est disponible ici.

L’objectif de ce chapitre est de présenter quelques éléments de préparation des données. Il s’agit d’une étape fondamentale, à ne pas négliger. Les modèles reposent sur certaines hypothèses, généralement relatives à la distribution théorique des variables qui y sont intégrées.

Il est nécessaire de faire correspondre la distribution empirique à ces hypothèses, ce qui implique un travail de restructuration des données. Celui-ci permettra d’avoir des résultats de modélisation plus pertinents. Nous verrons dans le chapitre sur les pipelines comment industrialiser ces étapes de preprocessing afin de se simplifier la vie pour appliquer un modèle sur un jeu de données différent de celui sur lequel il a été estimé.

Les packages suivants sont nécessaires pour importer et visualiser les données d’élection :

!pip install --upgrade xlrd #colab bug verson xlrd
!pip install geopandas

Dans ce chapitre, nous allons nous focaliser sur la préparation des données à faire en amont du travail de modélisation. Cette étape est indispensable pour s’assurer de la cohérence entre les données et les hypothèses de modélisation mais aussi pour produire des analyses valides scientifiquement.

La démarche générale que nous adopterons dans ce chapitre, et qui sera ensuite raffinée dans les prochains chapitres, est la suivante :

C’est l’approche classique du machine learning. On découpe l’ensemble des données disponibles en deux parties, échantillons d’apprentissage et de validation. Le premier sert à entraîner un modèle et la qualité des prédictions de celui-ci est évaluée sur le deuxième pour limiter le biais de surapprentissage. Le chapitre suivant approfondira cette question de l’évaluation des modèles. A ce stade de notre progression, on se concentrera dans ce chapitre sur la question des données. La librairie Scikit est non seulement particulièrement pratique parce qu’elle propose énormément d’algorithmes de machine learning mais aussi parce qu’elle facilite la préparation des données en amont, ce qui est l’objet de ce chapitre.

Néanmoins, avant de se concentrer sur la préparation des données, nous allons passer un peu de temps à explorer la structure des données à partir de laquelle nous désirons construire une modélisation. Ceci est indispensable afin de comprendre la nature de celles-ci et choisir une modélisation adéquate.

1 Construction de la base de données

Les sources de données étant diverses, le code qui construit la base finale est directement fourni. Le travail de construction d’une base unique est un peu fastidieux mais il s’agit d’un bon exercice, que vous pouvez tenter, pour réviser Pandas :

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/modelisation/get_data.py"
r = requests.get(url, allow_redirects=True)
open("getdata.py", "wb").write(r.content)

import getdata

votes = getdata.create_votes_dataframes()

Ce code introduit une base nommée votes dans l’environnement. Il s’agit d’une base rassemblant les différentes sources. Elle a l’aspect suivant :

votes.head(3)
STATEFP COUNTYFP COUNTYNS AFFGEOID GEOID NAME LSAD ALAND AWATER geometry ... share_2008_democrat share_2008_other share_2008_republican share_2012_democrat share_2012_other share_2012_republican share_2016_democrat share_2016_other share_2016_republican winner
0 29 227 00758566 0500000US29227 29227 Worth 06 690564983 493903 POLYGON ((-94.63203 40.57176, -94.53388 40.570... ... 0.363714 0.034072 0.602215 0.325382 0.041031 0.633588 0.186424 0.041109 0.772467 republican
1 31 061 00835852 0500000US31061 31061 Franklin 06 1491355860 487899 POLYGON ((-99.17940 40.35068, -98.72683 40.350... ... 0.284794 0.019974 0.695232 0.250000 0.026042 0.723958 0.149432 0.045427 0.805140 republican
2 36 013 00974105 0500000US36013 36013 Chautauqua 06 2746047476 1139407865 POLYGON ((-79.76195 42.26986, -79.62748 42.324... ... 0.495627 0.018104 0.486269 0.425017 0.115852 0.459131 0.352012 0.065439 0.582550 republican

3 rows × 383 columns

La carte choroplèthe suivante permet de visualiser rapidement les résultats (l’Alaska et Hawaï ont été exclus).

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns


# republican : red, democrat : blue
color_dict = {"republican": "#FF0000", "democrats": "#0000FF"}

fig, ax = plt.subplots(figsize=(12, 12))
grouped = votes.groupby("winner")
for key, group in grouped:
    group.plot(ax=ax, column="winner", label=key, color=color_dict[key])
plt.axis("off")

Les cartes choroplèthes peuvent donner une impression fallacieuse ce qui explique que ce type de carte a servi de justification pour contester les résultats du vote. En effet, un biais connu des représentations choroplèthes est qu’elles donnent une importance visuelle excessive aux grands espaces. Or, ceux-ci sont souvent des espaces peu denses et influencent donc moins la variable d’intérêt (en l’occurrence le taux de vote en faveur des républicains/démocrates). Une représentation à privilégier pour ce type de phénomènes est les ronds proportionnels (voir Insee (2018), “Le piège territorial en cartographie”).

Le GIF “Land does not vote, people do” qui avait eu un certain succès en 2020 propose un autre mode de visualisation. La carte originale a été construite avec JavaScript. Cependant, on dispose avec Python de plusieurs outils pour répliquer, à faible coût, cette carte grâce à l’une des surcouches à JavaScript vues dans la partie visualisation.

En l’occurrence, on peut utiliser Plotly pour tenir compte de la population et faire une carte en ronds proportionnels. Le code suivant permet de construire une carte adaptée :

import plotly
import plotly.graph_objects as go
import pandas as pd
import geopandas as gpd


centroids = votes.copy()
centroids.geometry = centroids.centroid
centroids["size"] = (
    centroids["CENSUS_2010_POP"] / 10000
)  # to get reasonable plotable number

color_dict = {"republican": "#FF0000", "democrats": "#0000FF"}
centroids["winner"] = np.where(
    centroids["votes_gop"] > centroids["votes_dem"], "republican", "democrats"
)


centroids["lon"] = centroids["geometry"].x
centroids["lat"] = centroids["geometry"].y
centroids = pd.DataFrame(
    centroids[["county_name", "lon", "lat", "winner", "CENSUS_2010_POP", "state_name"]]
)
groups = centroids.groupby("winner")

df = centroids.copy()

df["color"] = df["winner"].replace(color_dict)
df["size"] = df["CENSUS_2010_POP"] / 6000
df["text"] = (
    df["CENSUS_2010_POP"]
    .astype(int)
    .apply(lambda x: "<br>Population: {:,} people".format(x))
)
df["hover"] = (
    df["county_name"].astype(str)
    + df["state_name"].apply(lambda x: " ({}) ".format(x))
    + df["text"]
)

fig_plotly = go.Figure(
    data=go.Scattergeo(
        locationmode="USA-states",
        lon=df["lon"],
        lat=df["lat"],
        text=df["hover"],
        mode="markers",
        marker_color=df["color"],
        marker_size=df["size"],
        hoverinfo="text",
    )
)

fig_plotly.update_traces(
    marker={
        "opacity": 0.5,
        "line_color": "rgb(40,40,40)",
        "line_width": 0.5,
        "sizemode": "area",
    }
)

fig_plotly.update_layout(
    title_text='Reproduction of the "Acres don\'t vote, people do" map <br>(Click legend to toggle traces)',
    showlegend=True,
    geo={"scope": "usa", "landcolor": "rgb(217, 217, 217)"},
)
fig_plotly.show()

Les cercles proportionnels permettent ainsi à l’oeil de se concentrer sur les zones les plus denses et non sur les grands espaces. Cette fois, on voit bien que le vote démocrate est majoritaire, ce que cachait l’aplat de couleur.

2 Explorer la structure des données

La première étape nécessaire à suivre avant de se lancer dans la modélisation est de déterminer les variables à inclure dans le modèle.

Les fonctionnalités de Pandas sont, à ce niveau, suffisantes pour explorer des structures simples. Néanmoins, lorsqu’on est face à un jeu de données présentant de nombreuses variables explicatives (features en machine learning, covariates en économétrie), il est souvent judicieux d’avoir une première étape de sélection de variables, ce que nous verrons par la suite dans la partie dédiée.

Avant d’être en mesure de sélectionner le meilleur ensemble de variables explicatives, nous allons en prendre un nombre restreint et arbitraire. La première tâche est de représenter les relations entre les données, notamment la relation des variables explicatives à la variable dépendante (le score du parti républicain) ainsi que les relations entre les variables explicatives.

# 1. Créer le data.frame df2.
df2 = votes.set_index("GEOID").loc[
    :,
    [
        "winner",
        "votes_gop",
        "Unemployment_rate_2019",
        "Median_Household_Income_2019",
        "Percent of adults with less than a high school diploma, 2015-19",
        "Percent of adults with a bachelor's degree or higher, 2015-19",
    ],
]
# 2. Matrice de corrélation graphique
g1 = sns.heatmap(
    df2.drop("winner", axis=1).corr(), cmap="coolwarm", annot=True, fmt=".2f"
)

# Construction directement avec pandas également possible
g2 = (
    df2.drop("winner", axis=1)
    .corr()
    .style.background_gradient(cmap="coolwarm")
    .format("{:.2f}")
)

La matrice construite avec seaborn (question 2) aura l’aspect suivant :

<Axes: >

Alors que celle construite directement avec corr de Pandas ressemblera plutôt à ce tableau :

  votes_gop Unemployment_rate_2019 Median_Household_Income_2019 Percent of adults with less than a high school diploma, 2015-19 Percent of adults with a bachelor's degree or higher, 2015-19
votes_gop 1.00 -0.08 0.35 -0.11 0.37
Unemployment_rate_2019 -0.08 1.00 -0.43 0.36 -0.36
Median_Household_Income_2019 0.35 -0.43 1.00 -0.51 0.71
Percent of adults with less than a high school diploma, 2015-19 -0.11 0.36 -0.51 1.00 -0.59
Percent of adults with a bachelor's degree or higher, 2015-19 0.37 -0.36 0.71 -0.59 1.00

Le nuage de point obtenu à l’issue de la question 3 ressemblera à :

# 3. Matrice de nuages de points
ax = pd.plotting.scatter_matrix(df2, figsize=(15, 15))

array([[<Axes: xlabel='votes_gop', ylabel='votes_gop'>,
        <Axes: xlabel='Unemployment_rate_2019', ylabel='votes_gop'>,
        <Axes: xlabel='Median_Household_Income_2019', ylabel='votes_gop'>,
        <Axes: xlabel='Percent of adults with less than a high school diploma, 2015-19', ylabel='votes_gop'>,
        <Axes: xlabel="Percent of adults with a bachelor's degree or higher, 2015-19", ylabel='votes_gop'>],
       [<Axes: xlabel='votes_gop', ylabel='Unemployment_rate_2019'>,
        <Axes: xlabel='Unemployment_rate_2019', ylabel='Unemployment_rate_2019'>,
        <Axes: xlabel='Median_Household_Income_2019', ylabel='Unemployment_rate_2019'>,
        <Axes: xlabel='Percent of adults with less than a high school diploma, 2015-19', ylabel='Unemployment_rate_2019'>,
        <Axes: xlabel="Percent of adults with a bachelor's degree or higher, 2015-19", ylabel='Unemployment_rate_2019'>],
       [<Axes: xlabel='votes_gop', ylabel='Median_Household_Income_2019'>,
        <Axes: xlabel='Unemployment_rate_2019', ylabel='Median_Household_Income_2019'>,
        <Axes: xlabel='Median_Household_Income_2019', ylabel='Median_Household_Income_2019'>,
        <Axes: xlabel='Percent of adults with less than a high school diploma, 2015-19', ylabel='Median_Household_Income_2019'>,
        <Axes: xlabel="Percent of adults with a bachelor's degree or higher, 2015-19", ylabel='Median_Household_Income_2019'>],
       [<Axes: xlabel='votes_gop', ylabel='Percent of adults with less than a high school diploma, 2015-19'>,
        <Axes: xlabel='Unemployment_rate_2019', ylabel='Percent of adults with less than a high school diploma, 2015-19'>,
        <Axes: xlabel='Median_Household_Income_2019', ylabel='Percent of adults with less than a high school diploma, 2015-19'>,
        <Axes: xlabel='Percent of adults with less than a high school diploma, 2015-19', ylabel='Percent of adults with less than a high school diploma, 2015-19'>,
        <Axes: xlabel="Percent of adults with a bachelor's degree or higher, 2015-19", ylabel='Percent of adults with less than a high school diploma, 2015-19'>],
       [<Axes: xlabel='votes_gop', ylabel="Percent of adults with a bachelor's degree or higher, 2015-19">,
        <Axes: xlabel='Unemployment_rate_2019', ylabel="Percent of adults with a bachelor's degree or higher, 2015-19">,
        <Axes: xlabel='Median_Household_Income_2019', ylabel="Percent of adults with a bachelor's degree or higher, 2015-19">,
        <Axes: xlabel='Percent of adults with less than a high school diploma, 2015-19', ylabel="Percent of adults with a bachelor's degree or higher, 2015-19">,
        <Axes: xlabel="Percent of adults with a bachelor's degree or higher, 2015-19", ylabel="Percent of adults with a bachelor's degree or higher, 2015-19">]],
      dtype=object)

Le résultat de la question 4 devrait, quant à lui, ressembler au graphique suivant :

# 4. Matrice de corrélation avec plotly
import plotly
import plotly.express as px

htmlsnip2 = px.scatter_matrix(df2)
htmlsnip2.update_traces(diagonal_visible=False)
htmlsnip2.show()

3 Transformer les données

Les différences d’échelle ou de distribution entre les variables peuvent diverger des hypothèses sous-jacentes dans les modèles.

Par exemple, dans le cadre de la régression linéaire, les variables catégorielles ne sont pas traitées à la même enseigne que les variables ayant valeur dans \(\mathbb{R}\). Une variable discrète (prenant un nombre fini de valeurs) devra être transformée en suite de variables 0/1 par rapport à une modalité de référence pour être en adéquation avec les hypothèses de la régression linéaire. On appelle ce type de transformation one-hot encoding, sur laquelle nous reviendrons. Il s’agit d’une transformation, parmi d’autres, disponibles dans scikit pour mettre en adéquation un jeu de données et des hypothèses mathématiques.

L’ensemble de ces tâches s’appelle le preprocessing. L’un des intérêts d’utiliser Scikit est qu’on peut considérer qu’une tâche de preprocessing est, en fait, une tâche d’apprentissage. En effet, le preprocessing consiste à apprendre des paramètres d’une structure de données (par exemple estimer moyennes et variances pour les retrancher à chaque observation) et on peut très bien appliquer ces paramètres à des observations qui n’ont pas servi à construire ceux-ci. Ainsi, en gardant en tête l’approche générale avec Scikit,

nous allons voir deux processus très classiques de preprocessing :

  1. La standardisation transforme des données pour que la distribution empirique suive une loi \(\mathcal{N}(0,1)\).

  2. La normalisation transforme les données de manière à obtenir une norme (\(\mathcal{l}_1\) ou \(\mathcal{l}_2\)) unitaire. Autrement dit, avec la norme adéquate, la somme des éléments est égale à 1.

3.1 Standardisation

La standardisation consiste à transformer des données pour que la distribution empirique suive une loi \(\mathcal{N}(0,1)\). Pour être performants, la plupart des modèles de machine learning nécessitent souvent d’avoir des données dans cette distribution.

Moyenne de chaque variable sur 1000 premières observations avant :  [ 1.73616500e+04  3.84530000e+00  5.51891150e+04  1.29669150e+01
  2.15813433e+01 -2.73468885e-02]
Ecart-type de chaque variable sur 1000 premières observations avant :  [3.28113703e+04 1.28903822e+00 1.33256197e+04 6.45536365e+00
 9.41139584e+00 9.23129044e-01]
Moyenne de chaque variable sur 1000 premières observations après :  [-3.37507799e-17  2.66453526e-17  1.58095759e-16  1.42108547e-17
  1.24344979e-17 -1.59872116e-17]
Ecart-type de chaque variable sur 1000 premières observations après :  [1. 1. 1. 1. 1. 1.]

3.2 Normalisation

La normalisation est l’action de transformer les données de manière à obtenir une norme (\(\mathcal{l}_1\) ou \(\mathcal{l}_2\)) unitaire. Autrement dit, avec la norme adéquate, la somme des éléments est égale à 1. Par défaut, la norme est dans \(\mathcal{l}_2\). Cette transformation est particulièrement utilisée en classification de texte ou pour effectuer du clustering.

array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

3.3 Encodage des valeurs catégorielles

Les données catégorielles doivent être recodées sous forme de valeurs numériques pour être intégrés aux modèles de machine learning. Cela peut être fait de plusieurs manières :

  • LabelEncoder: transforme un vecteur ["a","b","c"] en vecteur numérique [0,1,2]. Cette approche a l’inconvénient d’introduire un ordre dans les modalités, ce qui n’est pas toujours souhaitable

  • OrdinalEncoder: une version généralisée du LabelEncoder qui a vocation à s’appliquer sur des matrices (\(X\)), alors que LabelEncoder s’applique plutôt à un vecteur (\(y\))

  • pandas.get_dummies effectue une opération de dummy expansion. Un vecteur de taille n avec K catégories sera transformé en matrice de taille \(n \times K\) pour lequel chaque colonne sera une variable dummy pour la modalité k. Il y a ici \(K\) modalités et il y a donc multicolinéarité. Avec une régression linéaire avec constante, il convient de retirer une modalité avant l’estimation.

  • OneHotEncoder est une version généralisée (et optimisée) de la dummy expansion. Il a plutôt vocation à s’appliquer sur les features (\(X\)) du modèle

3.4 Imputation

Les données peuvent souvent contenir des valeurs manquantes, autrement dit des cases de notre DataFrame contenant un NaN. Ces trous dans les données peuvent être à l’origine de bugs ou de mauvaises interprétations lorsque l’on passe à la modélisation. Pour y remédier, une première approche peut être de retirer toutes les observations présentant un NaN dans au moins l’une des colonnes. Cependant, si notre table contient beaucoup de NaN, ou bien que ces derniers sont répartis sur de nombreuses colonnes, c’est aussi prendre le risque de retirer un nombre important de lignes, et avec cela de l’information importante pour un modèle car les valeurs manquantes sont rarement réparties de manière aléatoire.

Même si dans plusieurs situations, cette solution reste tout à fait viable, il existe une autre approche plus robuste appelée imputation. Cette méthode consiste à remplacer les valeurs vides par une valeur donnée. Par exemple :

  • Imputation par la moyenne : remplacer tous les NaN dans une colonne par la valeur moyenne de la colonne ;
  • Imputation par la médiane sur le même principe, ou par la valeur de la colonne la plus fréquente pour les variables catégorielles ;
  • Imputation par régression : se servir d’autres variables pour essayer d’interpoler une valeur de remplacement adaptée.

Des méthodes plus complexes existent, mais dans de nombreux cas, les approches ci-dessus peuvent suffire pour donner des résultats beaucoup plus satisfaisants. Le package Scikit permet de faire de l’imputation de manière très simple (documentation ici).

3.5 Gestion des outliers

Les valeurs aberrantes (outliers en anglais) sont des observations qui se situent significativement à l’extérieur de la tendance générale des autres observations dans un ensemble de données. En d’autres termes, ce sont des points de données qui se démarquent de manière inhabituelle par rapport à la distribution globale des données. Cela peut être dû à des erreurs de remplissage, des personnes ayant mal répondu à un questionnaire, ou parfois simplement des valeurs extrêmes qui peuvent biaiser un modèle de façon trop importante.

A titre d’exemple, cela va être 3 individus mesurant plus de 4 mètres dans une population, ou bien des revenus de ménage dépassant les 10M d’euros par mois sur l’échelle d’un pays, etc.

Une bonne pratique peut donc être de systématiquement regarder la distribution des variables à disposition, pour se rendre compte si certaines valeurs s’éloignent de façon trop importante des autres. Ces valeurs vont parfois nous intéresser, si par exemple on se concentre uniquement sur les très hauts revenus (top 0.1%) en France. Cependant, ces données vont souvent nous gêner plus qu’autre chose, surtout si elles n’ont pas de sens dans le monde réel.

Si l’on estime que la présence de ces données extrêmes, ou outliers, dans notre base de données vont être problématiques plus qu’autre chose, alors il est tout à fait entendable et possible de simplement les retirer. La plupart du temps, on va se donner une proportion des données à retirer, par exemple 0.1%, 1% ou 5%, puis retirer dans les deux queues de la distribution les valeurs extrêmes correspondantes.

Plusieurs packages permettent de faire ce type d’opérations, qui sont parfois plus complexes si on s’intéresse aux outlier sur plusieurs variables. On pourra notamment citer la fonction IsolationForest() du package sklearn.ensemble.


Pour plus de détails sur ces deux derniers points, il est recommandé d’aller voir l’exemple Pour aller plus loin en bas de la page.

array([[23, 'Missouri'],
       [25, 'Nebraska'],
       [30, 'New York'],
       ...,
       [41, 'Texas'],
       [41, 'Texas'],
       [41, 'Texas']], dtype=object)
Alabama Arizona Arkansas California Colorado Connecticut Delaware District of Columbia Florida Georgia ... South Dakota Tennessee Texas Utah Vermont Virginia Washington West Virginia Wisconsin Wyoming
0 False False False False False False False False False False ... False False False False False False False False False False
1 False False False False False False False False False False ... False False False False False False False False False False
2 False False False False False False False False False False ... False False False False False False False False False False
3 False False False False False False False False False False ... False False False False False False False False False False
4 False False False False False False False False False False ... False True False False False False False False False False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3102 False False False False False False False False False False ... False False False False False False False False False False
3103 False False False False False False False False False False ... False False False False False False False False False False
3104 False False False False False False False False False False ... False False True False False False False False False False
3105 False False False False False False False False False False ... False False True False False False False False False False
3106 False False False False False False False False False False ... False False True False False False False False False False

3107 rows × 49 columns

array([23., 25., 30., ..., 41., 41., 41.])
<3107x1891 sparse matrix of type '<class 'numpy.float64'>'
    with 6214 stored elements in Compressed Sparse Row format>

4 Pour aller plus loin : un exemple pratique

Pour faire vos premiers pas en modélisation, notamment sur le preprocessing de données, vous pouvez également consulter le sujet 3 d’un hackathon organisé par l’Insee en 2023, Explorer les habitudes alimentaires de nos compatriotes, sur le SSP Cloud ou sur Github.

Le but du sujet est de travailler sur les données de consommations et habitudes alimentaires de l’étude INCA 3. Vous y travaillerez plusieurs thèmes : - Analyse exploratoire de données et visualisations - Clustering d’individus : du preprocessing jusqu’aux méthodes classiques d’apprentissage non supervisé (ACP, K-moyennes, Clustering Ascendant Hiérarchique) - Prédiction de l’IMC : Premiers pas vers les méthodes d’apprentissage supervisé et les preprocessings associés

5 Références

Insee. 2018. “Guide de Sémiologie Cartographique.”

Informations additionnelles

environment files have been tested on.

Latest built version: 2024-05-08

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.15.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
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.1
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.1
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.5.3
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)
3fba612 2023-12-17 18:16:42 Lino Galiana Remove some badges from python (#476)
417fb66 2023-12-04 18:49:21 Lino Galiana Corrections partie ML (#468)
1f23de2 2023-12-01 17:25:36 Lino Galiana Stockage des images sur S3 (#466)
a06a268 2023-11-23 18:23:28 Antoine Palazzolo 2ème relectures chapitres ML (#457)
b68369d 2023-11-18 18:21:13 Lino Galiana Reprise du chapitre sur la classification (#455)
fd3c955 2023-11-18 14:22:38 Lino Galiana Formattage des chapitres scikit (#453)
889a71b 2023-11-10 11:40:51 Antoine Palazzolo Modification TP 3 (#443)
9a4e226 2023-08-28 17:11:52 Lino Galiana Action to check URL still exist (#399)
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)
78ea2cb 2023-07-20 20:27:31 Lino Galiana Change titles levels (#381)
29ff3f5 2023-07-07 14:17:53 linogaliana description everywhere
f21a24d 2023-07-02 10:58:15 Lino Galiana Pipeline Quarto & Pages 🚀 (#365)
ebca985 2023-06-11 18:14:51 Lino Galiana Change handling precision (#361)
129b001 2022-12-26 20:36:01 Lino Galiana CSS for ipynb (#337)
f5f0f9c 2022-11-02 19:19:07 Lino Galiana Relecture début partie modélisation KA (#318)
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)
640b960 2022-06-10 15:42:04 Lino Galiana Finir de régler le problème plotly (#236)
5698e30 2022-06-03 18:28:37 Lino Galiana Finalise widget (#232)
7b9f27b 2022-06-03 17:05:15 Lino Galiana Essaie régler les problèmes widgets JS (#231)
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)
8f99cd3 2021-12-08 15:26:28 linogaliana hide otuput
9c5f718 2021-12-08 14:36:59 linogaliana format dico :sob:
41c8986 2021-12-08 14:25:18 linogaliana correction erreur
6474746 2021-12-08 14:08:06 linogaliana dict ici aussi
8e73912 2021-12-08 12:32:17 linogaliana coquille plotly :sob:
3704213 2021-12-08 11:57:51 linogaliana essaye avec un dict classique
85565d5 2021-12-08 08:15:29 linogaliana reformat
9ace7b9 2021-12-07 17:49:18 linogaliana évite la boucle crado
3514e09 2021-12-07 16:05:28 linogaliana sépare et document
63e67e6 2021-12-07 15:15:34 Lino Galiana Debug du plotly (temporaire) (#193)
65cecdd 2021-12-07 10:29:18 Lino Galiana Encore une erreur de nom de colonne (#192)
81b7023 2021-12-07 09:27:35 Lino Galiana Mise à jour liste des colonnes (#191)
c3bf4d4 2021-12-06 19:43:26 Lino Galiana Finalise debug partie ML (#190)
d91a5eb 2021-12-06 18:53:33 Lino Galiana La bonne branche c’est master
d86129c 2021-12-06 18:02:32 Lino Galiana verbose
fb14d40 2021-12-06 17:00:52 Lino Galiana Modifie l’import du script (#187)
37ecfa3 2021-12-06 14:48:05 Lino Galiana Essaye nom différent (#186)
2c8fd0d 2021-12-06 13:06:36 Lino Galiana Problème d’exécution du script import data ML (#185)
5d0a5e3 2021-12-04 07:41:43 Lino Galiana MAJ URL script recup data (#184)
5c10490 2021-12-03 17:44:08 Lino Galiana Relec (antuki?) partie modelisation (#183)
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)
347f50f 2020-11-12 15:08:18 Lino Galiana Suite de la partie machine learning (#78)
671f75a 2020-10-21 15:15:24 Lino Galiana Introduction au Machine Learning (#72)
Back to top

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.