Introduction à la régression

La régression linéaire est la première modélisation statistique qu’on découvre dans un cursus quantitatif. Il s’agit en effet d’une méthode très intuitive et très riche. Le Machine Learning permet de l’appréhender d’une autre manière que l’économétrie. Avec scikit et statsmodels, on dispose de tous les outils pour satisfaire à la fois data scientists et économistes.

Modélisation
Auteur·rice

Lino Galiana

Date de publication

2025-01-15

Pour essayer les exemples présents dans ce tutoriel :
View on GitHub Onyxia Onyxia Open In Colab

Le précédent chapitre visait à proposer un premier modèle pour comprendre les comtés où le parti Républicain l’emporte. La variable d’intérêt étant bimodale (victoire ou défaite), on était dans le cadre d’un modèle de classification.

Maintenant, sur les mêmes données, on va proposer un modèle de régression pour expliquer le score du parti Républicain. La variable est donc continue. Nous ignorerons le fait que ses bornes se trouvent entre 0 et 100 et donc qu’il faudrait, pour être rigoureux, transformer l’échelle afin d’avoir des données dans cet intervalle.

Ce chapitre utilise toujours le même jeu de données, présenté dans l’introduction de cette partie : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible sur Github.

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

url = "https://raw.githubusercontent.com/linogaliana/python-datascientist/main/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 chapitre va utiliser plusieurs packages de modélisation, les principaux étant Scikit et Statsmodels. Voici une suggestion d’import pour tous ces packages.

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import sklearn.metrics
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

1 Principe général

Le principe général de la régression consiste à trouver une loi \(h_\theta(X)\) telle que

\[ h_\theta(X) = \mathbb{E}_\theta(Y|X) \]

Cette formalisation est extrêmement généraliste et ne se restreint d’ailleurs pas à la régression linéaire.

En économétrie, la régression offre une alternative aux méthodes de maximum de vraisemblance et aux méthodes des moments. La régression est un ensemble très vaste de méthodes, selon la famille de modèles (paramétriques, non paramétriques, etc.) et la structure de modèles.

1.1 La régression linéaire

C’est la manière la plus simple de représenter la loi \(h_\theta(X)\) comme combinaison linéaire de variables \(X\) et de paramètres \(\theta\). Dans ce cas,

\[ \mathbb{E}_\theta(Y|X) = X\beta \]

Cette relation est encore, sous cette formulation, théorique. Il convient de l’estimer à partir des données observées \(y\). La méthode des moindres carrés consiste à minimiser l’erreur quadratique entre la prédiction et les données observées (ce qui explique qu’on puisse voir la régression comme un problème de Machine Learning). En toute généralité, la méthode des moindres carrés consiste à trouver l’ensemble de paramètres \(\theta\) tel que

\[ \theta = \arg \min_{\theta \in \Theta} \mathbb{E}\bigg[ \left( y - h_\theta(X) \right)^2 \bigg] \]

Ce qui, dans le cadre de la régression linéaire, s’exprime de la manière suivante :

\[ \beta = \arg\min \mathbb{E}\bigg[ \left( y - X\beta \right)^2 \bigg] \]

Lorsqu’on amène le modèle théorique (\(\mathbb{E}_\theta(Y|X) = X\beta\)) aux données, on formalise le modèle de la manière suivante :

\[ Y = X\beta + \epsilon \]

Avec une certaine distribution du bruit \(\epsilon\) qui dépend des hypothèses faites. Par exemple, avec des \(\epsilon \sim \mathcal{N}(0,\sigma^2)\) i.i.d., l’estimateur \(\beta\) obtenu est équivalent à celui du Maximum de Vraisemblance dont la théorie asymptotique nous assure l’absence de biais, la variance minimale (borne de Cramer-Rao).

1.1.1 Application

Toujours sous le patronage des héritiers de Siegfried (1913), notre objectif, dans ce chapitre, est d’expliquer et prédire le score des Républicains à partir de quelques variables socioéconomiques. Contrairement au chapitre précédent, où on se focalisait sur un résultat binaire (victoire/défaite des Républicains), cette fois on va chercher à modéliser directement le score des Républicains.

Le prochain exercice vise à illustrer la manière d’effectuer une régression linéaire avec scikit. Dans ce domaine, statsmodels est nettement plus complet, ce que montrera l’exercice suivant. L’intérêt principal de faire des régressions avec scikit est de pouvoir comparer les résultats d’une régression linéaire avec d’autres modèles de régression dans une perspective de sélection du meilleur modèle prédictif.

Exercice 1a : Régression linéaire avec scikit
  1. A partir de quelques variables, par exemple, ‘Unemployment_rate_2019’, ‘Median_Household_Income_2021’, ‘Percent of adults with less than a high school diploma, 2018-22’, “Percent of adults with a bachelor’s degree or higher, 2018-22”, expliquer la variable per_gop à l’aide d’un échantillon d’entraînement X_train constitué au préalable.

⚠️ Utiliser la variable Median_Household_Income_2021 en log sinon son échelle risque d’écraser tout effet.

  1. Afficher les valeurs des coefficients, constante comprise

  2. Evaluer la pertinence du modèle avec le \(R^2\) et la qualité du fit avec le MSE.

  3. Représenter un nuage de points des valeurs observées et des erreurs de prédiction. Observez-vous un problème de spécification ?

À la question 4, on peut voir que la répartition des erreurs n’est clairement pas aléatoire en fonction de \(X\).

Le modèle souffre donc d’un problème de spécification, il faudra par la suite faire un travail sur les variables sélectionnées. Avant cela, on peut refaire cet exercice avec le package statsmodels.

Exercice 1b : Régression linéaire avec statsmodels

Cet exercice vise à illustrer la manière d’effectuer une régression linéaire avec statsmodels qui offre des fonctionnalités plus proches de celles de R, et moins orientées Machine Learning.

L’objectif est toujours d’expliquer le score des Républicains en fonction de quelques variables.

  1. A partir de quelques variables, par exemple, ‘Unemployment_rate_2019’, ‘Median_Household_Income_2021’, ‘Percent of adults with less than a high school diploma, 2018-22’, “Percent of adults with a bachelor’s degree or higher, 2018-22”, expliquer la variable per_gop. ⚠️ utiliser la variable Median_Household_Income_2021 en log sinon son échelle risque d’écraser tout effet.
  2. Afficher un tableau de régression.
  3. Evaluer la pertinence du modèle avec le R^2.
  4. Utiliser l’API formula pour régresser le score des républicains en fonction de la variable Unemployment_rate_2021, de Unemployment_rate_2019 au carré et du log de Median_Household_Income_2021.
R2:  0.4310933195576123
Tip

Pour sortir une belle table pour un rapport sous \(\LaTeX\), il est possible d’utiliser la méthode Summary.as_latex. Pour un rapport HTML, on utilisera Summary.as_html

Note

Les utilisateurs de R retrouveront des éléments très familiers avec statsmodels, notamment la possibilité d’utiliser une formule pour définir une régression. La philosophie de statsmodels est similaire à celle qui a influé sur la construction des packages stats et MASS de R: offrir une librairie généraliste, proposant une large gamme de modèles.

Néanmoins, statsmodels bénéficie de sa jeunesse par rapport aux packages R. Depuis les années 1990, les packages R visant à proposer des fonctionalités manquantes dans stats et MASS se sont multipliés alors que statsmodels, enfant des années 2010, n’a eu qu’à proposer un cadre général (les generalized estimating equations) pour englober ces modèles.

1.2 La régression logistique

Nous avons appliqué notre régression linéaire sur une variable d’outcome continue. Comment faire avec une distribution binaire ?
Dans ce cas, \(\mathbb{E}_{\theta} (Y|X) = \mathbb{P}_{\theta} (Y = 1|X)\).
La régression logistique peut être vue comme un modèle linéaire en probabilité :

\[ \text{logit}\bigg(\mathbb{E}_{\theta}(Y|X)\bigg) = \text{logit}\bigg(\mathbb{P}_{\theta}(Y = 1|X)\bigg) = X\beta \]

La fonction \(\text{logit}\) est \(]0,1[ \to \mathbb{R}: p \mapsto \log(\frac{p}{1-p})\).

Elle permet ainsi de transformer une probabilité dans \(\mathbb{R}\). Sa fonction réciproque est la sigmoïde (\(\frac{1}{1 + e^{-x}}\)), objet central du Deep Learning.

Il convient de noter que les probabilités ne sont pas observées, c’est l’outcome binaire (0/1) qui l’est. Cela amène à voir la régression logistique de deux manières différentes :

  • En économétrie, on s’intéresse au modèle latent qui détermine le choix de l’outcome. Par exemple, si on observe les choix de participer ou non au marché du travail, on va modéliser les facteurs déterminant ce choix ;
  • En Machine Learning, le modèle latent n’est nécessaire que pour classifier dans la bonne catégorie les observations.

L’estimation des paramètres \(\beta\) peut se faire par maximum de vraisemblance ou par régression, les deux solutions sont équivalentes sous certaines hypothèses.

Note

Par défaut, scikit applique une régularisation pour pénaliser les modèles peu parcimonieux (comportement différent de celui de statsmodels). Ce comportement par défaut est à garder à l’esprit si l’objectif n’est pas de faire de la prédiction.

Note

By default, scikit applies regularization to penalize non-parsimonious models (a behavior different from that of statsmodels). This default behavior should be kept in mind if the objective is not prediction.

Exercice 2a : Régression logistique avec scikit

Avec scikit, en utilisant échantillons d’apprentissage et d’estimation :

  1. Evaluer l’effet des variables déjà utilisées sur la probabilité des Républicains de gagner. Affichez la valeur des coefficients.
  2. Déduire une matrice de confusion et une mesure de qualité du modèle.
  3. Supprimer la régularisation grâce au paramètre penalty. Quel effet sur les paramètres estimés ?
Exercice 2b : Régression logistique avec statmodels

En utilisant échantillons d’apprentissage et d’estimation :

  1. Evaluer l’effet des variables déjà utilisées sur la probabilité des Républicains de gagner.
  2. Faire un test de ratio de vraisemblance concernant l’inclusion de la variable de (log)-revenu.

La p-value du test de maximum de ratio de vraisemblance étant proche de 1, cela signifie que la variable log revenu ajoute, presque à coup sûr, de l’information au modèle.

Tip

La statistique du test est : \[ LR = -2\log\bigg(\frac{\mathcal{L}_{\theta}}{\mathcal{L}_{\theta_0}}\bigg) = -2(\mathcal{l}_{\theta} - \mathcal{l}_{\theta_0}) \]

2 Pour aller plus loin

Ce chapitre n’évoque les enjeux de la régression que de manière très introductive. Pour compléter ceci, il est recommandé d’aller plus loin en fonction de vos centres d’intérêt et de vos besoins.

Dans le domaine du machine learning, les principales voies d’approfondissement sont les suivantes:

  • Les modèles de régression alternatifs comme les forêts aléatoires.
  • Les méthodes de boosting et bagging pour découvrir la manière dont plusieurs modèles peuvent être entraînés de manière conjointe et leur prédiction sélectionnée selon un principe démocratique pour converger vers une meilleure décision qu’un modèle simple.
  • Les enjeux liés à l’explicabilité des modèles, un champ de recherche très actif, pour mieux comprendre les critères de décision des modèles.

Dans le domaine de l’économétrie, les principales voies d’approfondissement sont les suivantes:

  • Les modèles linéaires généralisés pour découvrir la régression avec des hypothèses plus générales que celles que nous avons posées jusqu’à présent ;
  • Les tests d’hypothèses pour aller plus loin sur ces questions que notre test de ratio de vraisemblance.

Références

Informations additionnelles

environment files have been tested on.

Latest built version: 2025-01-15

Python version used:

'3.12.6 | packaged by conda-forge | (main, Sep 30 2024, 18:08:52) [GCC 13.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.15.1
aiohappyeyeballs 2.4.3
aiohttp 3.10.8
aioitertools 0.12.0
aiosignal 1.3.1
alembic 1.13.3
altair 5.4.1
aniso8601 9.0.1
annotated-types 0.7.0
anyio 4.8.0
appdirs 1.4.4
archspec 0.2.3
asttokens 2.4.1
attrs 24.2.0
babel 2.16.0
bcrypt 4.2.0
beautifulsoup4 4.12.3
black 24.8.0
blinker 1.8.2
blis 0.7.11
bokeh 3.5.2
boltons 24.0.0
boto3 1.35.23
botocore 1.35.23
branca 0.7.2
Brotli 1.1.0
cachetools 5.5.0
cartiflette 0.0.2
Cartopy 0.24.1
catalogue 2.0.10
cattrs 24.1.2
certifi 2024.8.30
cffi 1.17.1
charset-normalizer 3.3.2
click 8.1.7
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.20.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
commonmark 0.9.1
conda 24.9.1
conda-libmamba-solver 24.7.0
conda-package-handling 2.3.0
conda_package_streaming 0.10.0
confection 0.1.5
contextily 1.6.2
contourpy 1.3.0
cryptography 43.0.1
cycler 0.12.1
cymem 2.0.10
cytoolz 1.0.0
dask 2024.9.1
dask-expr 1.1.15
databricks-sdk 0.33.0
dataclasses-json 0.6.7
debugpy 1.8.6
decorator 5.1.1
Deprecated 1.2.14
diskcache 5.6.3
distributed 2024.9.1
distro 1.9.0
docker 7.1.0
duckdb 0.10.1
en-core-web-sm 3.7.1
entrypoints 0.4
et_xmlfile 2.0.0
exceptiongroup 1.2.2
executing 2.1.0
fastexcel 0.11.6
fastjsonschema 2.21.1
fiona 1.10.1
Flask 3.0.3
folium 0.17.0
fontawesomefree 6.6.0
fonttools 4.54.1
frozendict 2.4.4
frozenlist 1.4.1
fsspec 2023.12.2
geographiclib 2.0
geopandas 1.0.1
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.35.0
graphene 3.3
graphql-core 3.2.4
graphql-relay 3.2.0
graphviz 0.20.3
great-tables 0.12.0
greenlet 3.1.1
gunicorn 22.0.0
h11 0.14.0
h2 4.1.0
hpack 4.0.0
htmltools 0.6.0
httpcore 1.0.7
httpx 0.28.1
httpx-sse 0.4.0
hyperframe 6.0.1
idna 3.10
imageio 2.36.1
importlib_metadata 8.5.0
importlib_resources 6.4.5
inflate64 1.0.1
ipykernel 6.29.5
ipython 8.28.0
itsdangerous 2.2.0
jedi 0.19.1
Jinja2 3.1.4
jmespath 1.0.1
joblib 1.4.2
jsonpatch 1.33
jsonpointer 3.0.0
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
jupyter-cache 1.0.0
jupyter_client 8.6.3
jupyter_core 5.7.2
kaleido 0.2.1
kiwisolver 1.4.7
langchain 0.3.14
langchain-community 0.3.9
langchain-core 0.3.29
langchain-text-splitters 0.3.5
langcodes 3.5.0
langsmith 0.1.147
language_data 1.3.0
lazy_loader 0.4
libmambapy 1.5.9
locket 1.0.0
loguru 0.7.3
lxml 5.3.0
lz4 4.3.3
Mako 1.3.5
mamba 1.5.9
mapclassify 2.8.1
marisa-trie 1.2.1
Markdown 3.6
markdown-it-py 3.0.0
MarkupSafe 2.1.5
marshmallow 3.25.1
matplotlib 3.9.2
matplotlib-inline 0.1.7
mdurl 0.1.2
menuinst 2.1.2
mercantile 1.2.1
mizani 0.11.4
mlflow 2.16.2
mlflow-skinny 2.16.2
msgpack 1.1.0
multidict 6.1.0
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.11
mypy-extensions 1.0.0
narwhals 1.22.0
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.3
nltk 3.9.1
numpy 1.26.4
opencv-python-headless 4.10.0.84
openpyxl 3.1.5
opentelemetry-api 1.16.0
opentelemetry-sdk 1.16.0
opentelemetry-semantic-conventions 0.37b0
orjson 3.10.14
OWSLib 0.28.1
packaging 24.1
pandas 2.2.3
paramiko 3.5.0
parso 0.8.4
partd 1.4.2
pathspec 0.12.1
patsy 0.5.6
Pebble 5.1.0
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.4.0
pip 24.2
platformdirs 4.3.6
plotly 5.24.1
plotnine 0.13.6
pluggy 1.5.0
polars 1.8.2
preshed 3.0.9
prometheus_client 0.21.0
prometheus_flask_exporter 0.23.1
prompt_toolkit 3.0.48
protobuf 4.25.3
psutil 6.0.0
ptyprocess 0.7.0
pure_eval 0.2.3
py7zr 0.20.8
pyarrow 17.0.0
pyarrow-hotfix 0.6
pyasn1 0.6.1
pyasn1_modules 0.4.1
pybcj 1.0.3
pycosat 0.6.6
pycparser 2.22
pycryptodomex 3.21.0
pydantic 2.10.5
pydantic_core 2.27.2
pydantic-settings 2.7.1
Pygments 2.18.0
PyNaCl 1.5.0
pynsee 0.1.8
pyogrio 0.10.0
pyOpenSSL 24.2.1
pyparsing 3.1.4
pyppmd 1.1.1
pyproj 3.7.0
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.1
PyYAML 6.0.2
pyzmq 26.2.0
pyzstd 0.16.2
querystring_parser 1.2.4
rasterio 1.4.3
referencing 0.35.1
regex 2024.9.11
requests 2.32.3
requests-cache 1.2.1
requests-toolbelt 1.0.0
retrying 1.3.4
rich 13.9.4
rpds-py 0.22.3
rsa 4.9
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.10.2
scikit-image 0.24.0
scikit-learn 1.5.2
scipy 1.13.0
seaborn 0.13.2
setuptools 74.1.2
shapely 2.0.6
shellingham 1.5.4
six 1.16.0
smart-open 7.1.0
smmap 5.0.0
sniffio 1.3.1
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.7.5
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.35
sqlparse 0.5.1
srsly 2.5.0
stack-data 0.6.2
statsmodels 0.14.4
tabulate 0.9.0
tblib 3.0.0
tenacity 9.0.0
texttable 1.7.0
thinc 8.2.5
threadpoolctl 3.5.0
tifffile 2025.1.10
toolz 1.0.0
topojson 1.9
tornado 6.4.1
tqdm 4.66.5
traitlets 5.14.3
truststore 0.9.2
typer 0.15.1
typing_extensions 4.12.2
typing-inspect 0.9.0
tzdata 2024.2
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.20
wasabi 1.1.3
wcwidth 0.2.13
weasel 0.4.1
webdriver-manager 4.0.2
websocket-client 1.8.0
Werkzeug 3.0.4
wheel 0.44.0
wordcloud 1.9.3
wrapt 1.16.0
xgboost 2.1.1
xlrd 2.0.1
xyzservices 2024.9.0
yarl 1.13.1
yellowbrick 1.5
zict 3.0.0
zipp 3.20.2
zstandard 0.23.0

View file history

SHA Date Author Description
48dccf1 2025-01-14 21:45:34 lgaliana Fix bug in modeling section
d4f8959 2024-12-20 14:36:20 lgaliana format fstring R2
8c8ca4c 2024-12-20 10:45:00 lgaliana Traduction du chapitre clustering
a5ecaed 2024-12-20 09:36:42 Lino Galiana Traduction du chapitre modélisation (#582)
ff0820b 2024-11-27 15:10:39 lgaliana Mise en forme chapitre régression
06d003a 2024-04-23 10:09:22 Lino Galiana Continue la restructuration des sous-parties (#492)
8c316d0 2024-04-05 19:00:59 Lino Galiana Fix cartiflette deprecated snippets (#487)
005d89b 2023-12-20 17:23:04 Lino Galiana Finalise l’affichage des statistiques Git (#478)
7d12af8 2023-12-05 10:30:08 linogaliana Modularise la partie import pour l’avoir partout
417fb66 2023-12-04 18:49:21 Lino Galiana Corrections partie ML (#468)
a06a268 2023-11-23 18:23:28 Antoine Palazzolo 2ème relectures chapitres ML (#457)
889a71b 2023-11-10 11:40:51 Antoine Palazzolo Modification TP 3 (#443)
154f09e 2023-09-26 14:59:11 Antoine Palazzolo Des typos corrigées par Antoine (#411)
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)
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)
58c7128 2023-06-11 21:32:03 Lino Galiana change na subset (#362)
2ed4aa7 2022-11-07 15:57:31 Lino Galiana Reprise 2e partie ML + Règle problème mathjax (#319)
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)
c3bf4d4 2021-12-06 19:43:26 Lino Galiana Finalise debug partie ML (#190)
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)
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)
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)
59eadf5 2020-11-12 16:41:46 Lino Galiana Correction des typos partie ML (#81)
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)
Retour au sommet

Les références

Siegfried, André. 1913. Tableau politique de la France de l’ouest sous la troisième république: 102 cartes et croquis, 1 carte hors texte. A. Colin.

Citation

BibTeX
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python pour la data science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
Galiana, Lino. 2023. Python pour la data science. https://doi.org/10.5281/zenodo.8229676.