diff --git a/content/NLP/02_exoclean.qmd b/content/NLP/02_exoclean.qmd index 050f1dd9c..179c23771 100644 --- a/content/NLP/02_exoclean.qmd +++ b/content/NLP/02_exoclean.qmd @@ -507,7 +507,7 @@ par la loi de Zipf, cf. exercice suivant). -### Aparté: la loi de Zipf +### Aparté : la loi de Zipf ::: {.cell .markdown} ```{=html} diff --git a/content/annexes/corrections.qmd b/content/annexes/corrections.qmd index 2e2e17252..bca2ec139 100644 --- a/content/annexes/corrections.qmd +++ b/content/annexes/corrections.qmd @@ -50,7 +50,7 @@ print_badges("content/manipulation/02b_pandas_TP.qmd", correction=True) ``` ::: -* [Exercices `Geopandas`](../manipulation/03_geopandas_TP.qmd): +* [Exercices `Geopandas`](../manipulation/03_geopandas_TP.qmd) : ::: {.cell .markdown} ```{python} diff --git a/content/getting-started/01_installation.qmd b/content/getting-started/01_installation.qmd index 439564948..6260550ff 100644 --- a/content/getting-started/01_installation.qmd +++ b/content/getting-started/01_installation.qmd @@ -39,7 +39,7 @@ chapitre présente les badges suivants qui permettent d'ouvrir la page *web* en question dans l'environnement de prédilection. Par exemple, pour ouvrir le chapitre relatif à `numpy` dans l'un des environnements temporaires proposés, -les badges suivants sont proposés: +les badges suivants sont proposés : ::: {.cell .markdown} ```{python} @@ -216,8 +216,8 @@ jusqu'au déploiement de visualisations automatiques[^1]) mais n'est pas très pratique pour le griffonnage. -[^1] A cet égard, il est recommandé de consulter le cours de dernière année -de l'ENSAE déjà cité: https://ensae-reproductibilite.github.io/website/ +[^1]: A cet égard, il est recommandé de consulter le cours de dernière année +de l'ENSAE déjà cité : https://ensae-reproductibilite.github.io/website/ [Kaggle](https://www.kaggle.com/notebooks) diff --git a/content/getting-started/04_python_practice.qmd b/content/getting-started/04_python_practice.qmd index 9602047f9..c7b7381ec 100644 --- a/content/getting-started/04_python_practice.qmd +++ b/content/getting-started/04_python_practice.qmd @@ -62,7 +62,7 @@ l'environnement est le `NAMESPACE`. [sphinx](https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html) et non de l'éditer manuellement. (cf. [plus tard](#docfonctions)). Les éléments qui s'en rapprochent dans un package `R` sont les vignettes. -* Les tests génériques des fonctions. Ce n'est pas obligatoire mais c'est recommandé: ça évite de découvrir deux jours +* Les tests génériques des fonctions. Ce n'est pas obligatoire mais c'est recommandé : ça évite de découvrir deux jours avant un rendu de projet que la fonction ne produit pas le résultat espéré. * Le `README.md` permet de créer une présentation du package qui s'affiche automatiquement sur github/gitlab et le fichier `LICENSE` vise à protéger la propriété intellectuelle. Un certain nombre de licences diff --git a/content/getting-started/05_rappels_types.qmd b/content/getting-started/05_rappels_types.qmd index 0304e2db8..fabaafad7 100644 --- a/content/getting-started/05_rappels_types.qmd +++ b/content/getting-started/05_rappels_types.qmd @@ -400,7 +400,7 @@ nous allons voir comment nous en servir. Pour comprendre comment modifier un objet, il convient de distinguer deux concepts, développés plus amplement -dans le chapitre dédié: les __attributs__ et les __méthodes__ : +dans le chapitre dédié : les __attributs__ et les __méthodes__ : - Les _attributs_ décrivent la structure interne d'un objet. Par exemple, la taille d'un objet, sa langue, etc. diff --git a/content/git/exogit.qmd b/content/git/exogit.qmd index edbff1342..541a95e9e 100644 --- a/content/git/exogit.qmd +++ b/content/git/exogit.qmd @@ -271,7 +271,7 @@ sans s'en rendre compte. En amont de l'exercice 2, pour les utilisateurs du `SSPCloud`, il est recommandé d'ouvrir un service `Jupyter` -en suivant les consignes suivantes: +en suivant les consignes suivantes : * Dans la page `Mes services`, cliquer sur le bouton `Nouveau service` ; * Choisir `Jupyter-Python` ; diff --git a/content/manipulation/01_numpy.qmd b/content/manipulation/01_numpy.qmd index e0e8e19f1..2e40737b0 100644 --- a/content/manipulation/01_numpy.qmd +++ b/content/manipulation/01_numpy.qmd @@ -152,7 +152,7 @@ Il existe aussi des méthodes pratiques pour créer des array: * séquences logiques : `np.arange` (suite) ou `np.linspace` (interpolation linéaire entre deux bornes) * séquences ordonnées : _array_ rempli de zéros, de 1 ou d'un nombre désiré : `np.zeros`, `np.ones` ou `np.full` * séquences aléatoires : fonctions de génération de nombres aléatoires : `np.rand.uniform`, `np.rand.normal`, etc. -* tableau sous forme de matrice identité: `np.eye` +* tableau sous forme de matrice identité : `np.eye` Ceci donne ainsi, pour les séquences logiques: diff --git a/content/manipulation/02a_pandas_tutorial.qmd b/content/manipulation/02a_pandas_tutorial.qmd index da390008d..234def4c5 100644 --- a/content/manipulation/02a_pandas_tutorial.qmd +++ b/content/manipulation/02a_pandas_tutorial.qmd @@ -668,7 +668,7 @@ ou `df['Autres transports']`. C'est une manière préférable de procéder. Pour accéder à une ou plusieurs valeurs d'un `DataFrame`, il existe deux manières conseillées de procéder, selon la -forme des indices de lignes ou colonnes utilisés: +forme des indices de lignes ou colonnes utilisées : * `df.loc` : utilise les labels * `df.iloc` : utilise les indices @@ -950,7 +950,7 @@ donnée en fin de cours. Tant qu'on n'appelle pas une action sur un `DataFrame` par groupe, du type `head` ou `display`, `pandas` n'effectue aucune opération. On parle de *lazy evaluation*. Par exemple, le résultat de `df.groupby('dep')` est -une transformation qui n'est pas encore évaluée: +une transformation qui n'est pas encore évaluée : ```{python} df.groupby('dep') diff --git a/content/manipulation/02b_pandas_TP.qmd b/content/manipulation/02b_pandas_TP.qmd index 026d8762a..6252d144c 100644 --- a/content/manipulation/02b_pandas_TP.qmd +++ b/content/manipulation/02b_pandas_TP.qmd @@ -370,7 +370,7 @@ utiliser le _package_ communautaire `pynsee` :

Note

``` -Le _package_ `pynsee` comporte deux principaux points d'entrée: +Le _package_ `pynsee` comporte deux principaux points d'entrée : - Les API de l'Insee, ce qui sera illustré dans le chapitre consacré. - Quelques jeux de données directement issus du site web de diff --git a/content/manipulation/04a_webscraping_TP.qmd b/content/manipulation/04a_webscraping_TP.qmd index c5623841a..6ef3141f8 100644 --- a/content/manipulation/04a_webscraping_TP.qmd +++ b/content/manipulation/04a_webscraping_TP.qmd @@ -180,7 +180,7 @@ Citons, par exemple, les balises `

`, `

`, `

`, `

`, `` ou `< Le symbole ``< >`` est une balise : il sert à indiquer le début d'une partie. Le symbole `` indique la fin de cette partie. La plupart des balises vont par paires, avec une *balise ouvrante* et une *balise fermante* (par exemple `

` et `

`). Par exemple, les principales balises -définissant la structure d'un tableau sont les suivantes: +définissant la structure d'un tableau sont les suivantes : | Balise | Description | |-------------|------------------------------------| @@ -196,7 +196,7 @@ définissant la structure d'un tableau sont les suivantes: **Application : un tableau en HTML** -Le code `HTML` du tableau suivant: +Le code `HTML` du tableau suivant : ```{html} @@ -485,7 +485,7 @@ print(rows[0]) ``` -La seconde ligne va correspondre à la ligne du premier club présent dans le tableau: +La seconde ligne va correspondre à la ligne du premier club présent dans le tableau : ```{python} #| echo: true @@ -555,7 +555,7 @@ data_participants.head() ``` -5️⃣ Récupérer les en-têtes du tableau: +5️⃣ Récupérer les en-têtes du tableau : ```{python} #| echo: true @@ -1337,7 +1337,7 @@ search_button.click() `Selenium` permet de capturer l'image qu'on verrait dans le navigateur avec `get_screenshot_as_png`. Cela peut être utile pour vérifier qu'on -a fait la bonne action: +a fait la bonne action : ```{python} #| output: false diff --git a/content/manipulation/04b_regex_TP.qmd b/content/manipulation/04b_regex_TP.qmd index d9a8bb770..a93738365 100644 --- a/content/manipulation/04b_regex_TP.qmd +++ b/content/manipulation/04b_regex_TP.qmd @@ -117,7 +117,7 @@ print(re.search(pattern, "J'ai un chapeau rond.")) ``` Cependant, dans le dernier cas, nous ne trouvons pas -le _pattern_ recherché: +le _pattern_ recherché : ```{python} print(re.search(pattern, "La soupe est chaude.")) @@ -137,7 +137,7 @@ ou les ancres (`^`, `$`...) Dans l'exemple précédent, nous retrouvions deux quantifieurs accolés `.+`. Le premier (`.`) signifie n'importe quel caractère[^1]. Le deuxième (`+`) signifie _"répète le pattern précédent"_. Dans notre cas, la combinaison `.+` permet ainsi de répéter n'importe quel caractère avant de trouver un _n_. -Le nombre de fois est indeterminé: cela peut ne pas être pas nécessaire d'intercaler des caractères avant le _n_ +Le nombre de fois est indeterminé : cela peut ne pas être pas nécessaire d'intercaler des caractères avant le _n_ ou cela peut être nécessaire d'en intercepter plusieurs : ```{python} @@ -792,7 +792,7 @@ data_books.loc[~(data_books['Date of Publication'] == data_books['year']), ['Dat ``` Quant aux nouveaux `NaN`, -il s'agit de lignes qui ne contenaient pas de chaînes de caractères qui ressemblaient à des années: +il s'agit de lignes qui ne contenaient pas de chaînes de caractères qui ressemblaient à des années : ```{python} #| echo: false diff --git a/content/manipulation/04c_API_TP.qmd b/content/manipulation/04c_API_TP.qmd index d9654f289..532121aff 100644 --- a/content/manipulation/04c_API_TP.qmd +++ b/content/manipulation/04c_API_TP.qmd @@ -283,7 +283,7 @@ def interactive_map_dpe(dpe): # I can add marker one by one on the map for i in range(0,len(dpe)): folium.Marker([dpe.iloc[i]['latitude'], dpe.iloc[i]['longitude']], - popup=f"Année de construction: {dpe.iloc[i]['annee_construction']},
DPE: {dpe.iloc[i]['classe_consommation_energie']}", + popup=f"Année de construction : {dpe.iloc[i]['annee_construction']},
DPE : {dpe.iloc[i]['classe_consommation_energie']}", icon=folium.Icon(color="black", icon="home", icon_color = dpe.iloc[i]['color'])).add_to(m) m.fit_bounds([sw, ne]) diff --git a/content/modelisation/0_preprocessing.qmd b/content/modelisation/0_preprocessing.qmd index 9993e9434..6a56708c3 100644 --- a/content/modelisation/0_preprocessing.qmd +++ b/content/modelisation/0_preprocessing.qmd @@ -60,7 +60,7 @@ 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. +à 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 @@ -79,7 +79,7 @@ Cet aspect unifié est l'une des raisons du succès précoce de celle-ci. `R` n' bénéficié que plus récemment d'une librairie unifiée, à savoir [`tidymodels`](https://www.tidymodels.org/). -Une autre raison du succès de `scikit` est son approche opérationnelle: la mise +Une autre raison du succès de `scikit` est son approche opérationnelle : la mise en production de modèles développés via les _pipelines_ `scikit` est peu coûteuse. Un [chapitre spécial de ce cours](/pipeline-scikit) est dédié aux _pipelines_. Avec Romain Avouac, nous proposons un [cours plus avancé](https://ensae-reproductibilite.github.io/website/) @@ -99,7 +99,7 @@ développé dans le cadre de l'initiative [`Inria Academy`](https://www.inria.fr ::: Les _packages_ suivants sont nécessaires pour importer et visualiser -les données d'élection: +les données d'élection : ```{python} #| eval: false @@ -116,7 +116,7 @@ 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: +est la suivante : ![](scikit_predict.png) @@ -197,7 +197,7 @@ 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: +suivant : ```{python} #| echo: true @@ -252,7 +252,7 @@ l'une des surcouches à `JavaScript` vues dans la partie [visualisation](#visual 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: +Le code suivant permet de construire une carte adaptée : ```{python} #| output: false @@ -350,7 +350,7 @@ ainsi que les relations entre les variables explicatives. `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. Représenter grâce à un graphique la matrice de corrélation. Vous pouvez utiliser le _package_ `seaborn` et sa fonction `seaborn`. +2. Représenter grâce à un graphique la matrice de corrélation. Vous pouvez utiliser le _package_ `seaborn` et sa fonction `heatmap`. 3. Représenter une matrice de nuages de points des variables de la base `df2` avec `pd.plotting.scatter_matrix` 4. (optionnel) Refaire ces figures avec `Plotly` qui offre également la possibilité de faire une matrice de corrélation. @@ -406,7 +406,7 @@ Le résultat de la question 4 devrait, quant à lui, ressembler au graphique suivant : ```{python} -# 4. Matrice de corélation avec plotly +# 4. Matrice de corrélation avec plotly import plotly import plotly.express as px htmlsnip2 = px.scatter_matrix(df2) @@ -423,11 +423,11 @@ 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ées en suite de +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 lequel nous reviendrons. Il s'agit d'une 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. @@ -438,7 +438,7 @@ 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` +ceux-ci. Ainsi, en gardant en tête l'approche générale avec `Scikit`, ![](scikit_predict.png) @@ -592,7 +592,51 @@ 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 +### 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](https://stefvanbuuren.name/fimd/sec-MCAR.html). + +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](https://scikit-learn.org/stable/modules/impute.html)). + +### 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. ::: {.cell .markdown} ```{=html} @@ -652,6 +696,14 @@ onehot_enc = preprocessing.OneHotEncoder().fit(df) onehot_enc.transform(df) ``` +## 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](https://www.sspcloud.fr/formation?search=funath&path=%5B%22Funathon%202023%22%5D) ou sur [Github](https://github.com/InseeFrLab/funathon2023_sujet3/). + +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 ## Références diff --git a/content/modelisation/1_modelevaluation.qmd b/content/modelisation/1_modelevaluation.qmd index 6da393f35..3fab4c9fb 100644 --- a/content/modelisation/1_modelevaluation.qmd +++ b/content/modelisation/1_modelevaluation.qmd @@ -24,7 +24,7 @@ description: | peut se faire, grâce à scikit, de manière relativement standardisée. Cette démarche scientifique est essentielle pour assurer la confiance dans la qualité d'un modèle, ce qu'a illustré récemment - un [cycle de séminaire de Princeton](https://reproducible.cs.princeton.edu/) + un [cycle de séminaire de Princeton](https://reproducible.cs.princeton.edu/). image: https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Overfitting.svg/300px-Overfitting.svg.png --- @@ -52,7 +52,7 @@ que nous appliquerons dans les prochains chapitres. ## Découper l'échantillon Le chapitre précédent présentait le _pipeline_ simple ci-dessous -pour introduire à la notion d'entraînement d'un modèle: +pour introduire à la notion d'entraînement d'un modèle : ![](scikit_predict.png) @@ -69,7 +69,7 @@ pénalisation et choisir celui qui permet la meilleure prédiction. La notion de __validation croisée__ permettra de généraliser cette approche. Ces paramètres qui affectent la prédiction seront pas la suite appelés des **hyperparamètres**. Comme nous allons le voir, nous allons aboutir à un -raffinement de l'approche pour obtenir un *pipeline* ayant plutôt cet aspect: +raffinement de l'approche pour obtenir un *pipeline* ayant plutôt cet aspect : ![](scikit_predict2.png) @@ -92,7 +92,7 @@ $$ Il y a ainsi un compromis à faire entre biais et variance. Un modèle peu parcimonieux, c'est-à-dire proposant un grand nombre de paramètres, va, en général, avoir un faible biais mais une grande variance. En effet, le modèle va tendre à se souvenir d'une combinaison de paramètres à partir d'un grand nombre d'exemples sans être capable d'apprendre la règle qui permette de structurer les données. -[^1]! Cette formule permet de bien comprendre la théorie statistique asymptotique, notamment le théorème de Cramer-Rao. Dans la classe des estimateurs sans biais, c'est-à-dire dont le premier terme est nul, trouver l'estimateur à variance minimale revient à trouver l'estimateur qui minimise $\mathbb{E}\bigg[(y - h_\theta(X))^2 \bigg]$. C'est la définition même de la régression, ce qui, quand on fait des hypothèses supplémentaires sur le modèle statistique, explique le théorème de Cramer-Rao. +[^1]: Cette formule permet de bien comprendre la théorie statistique asymptotique, notamment le théorème de Cramer-Rao. Dans la classe des estimateurs sans biais, c'est-à-dire dont le premier terme est nul, trouver l'estimateur à variance minimale revient à trouver l'estimateur qui minimise $\mathbb{E}\bigg[(y - h_\theta(X))^2 \bigg]$. C'est la définition même de la régression, ce qui, quand on fait des hypothèses supplémentaires sur le modèle statistique, explique le théorème de Cramer-Rao. Par exemple, la ligne verte ci-dessous est trop dépendante des données et risque de produire une erreur plus importante que la ligne noire (qui moyennise plus) sur de nouvelles données. @@ -167,7 +167,7 @@ La __validation croisée__ est une méthode permettant de choisir la valeur du p qui optimise la qualité de la prédiction en agrégeant des scores de performance sur des découpages différents de l'échantillon d'apprentissage. -La validation croisée permet d'évaluer les performances de modèles différents (SVM, random forest, etc.) ou, couplé à une stratégie de *grid search* de trouver les valeurs des hyperparamètres qui aboutissent à la meilleure prédiction. +La validation croisée permet d'évaluer les performances de modèles différents (SVM, random forest, etc.) ou, couplé à une stratégie de *grid search*, de trouver les valeurs des hyperparamètres qui aboutissent à la meilleure prédiction. ::: {.cell .markdown} ```{=html} @@ -214,7 +214,7 @@ A partir des 4 coins de cette matrice, il existe plusieurs mesure de performance | Critère | Mesure | Calcul | |-------------|--------------|------------------| -| *Accuracy* | Taux de classification correcte | Diagonale du tableau: $\frac{TP+TN}{TP+FP+FN+FP}$ | +| *Accuracy* | Taux de classification correcte | Diagonale du tableau : $\frac{TP+TN}{TP+FP+FN+FP}$ | | *Precision* | Taux de vrais positifs |Ligne des prédictions positives : $\frac{TP}{TP+FP}$ | | *Recall* (rappel) | Capacité à identifier les labels positifs | Colonne des prédictions positives : $\frac{TP}{TP+FN}$ | | *F1 Score* | Mesure synthétique (moyenne harmonique) de la précision et du rappel | $2 \frac{precision \times recall}{precision + recall}$ | @@ -232,7 +232,7 @@ $$ $$ Plus on augmente $c$, plus on est sélectif sur le critère d'appartenance à la classe. -Le rappel, i.e. le taux de faux négatifs, diminue. Mais on augmente le nombre de positifs manqués. Pour chaque valeur de $c$ correspond une matrice de confusion et donc des mesures de performances. +La précision, i.e. le taux de vrais positifs parmi les prédictions positives, augmente. Mais on augmente le nombre de positifs manqués (autrement dit on diminue le rappel). Pour chaque valeur de $c$ correspond une matrice de confusion et donc des mesures de performances. La **courbe ROC** est un outil classique pour représenter en un graphique l’ensemble de ces informations en faisant varier $c$ de 0 à 1: @@ -254,5 +254,5 @@ En Machine Learning, les indicateurs de performance en régression sont les suiv L'économètre se focalise moins sur la qualité de la prédiction et utilisera d'autres critères pour évaluer la qualité d'un modèle (certains, comme le BIC, sont -à regarder aussi dans une optique *Machine Learning*): $R^2$, $BIC$, +à regarder aussi dans une optique *Machine Learning*) : $R^2$, $BIC$, $AIC$, *log-likelihood*, etc. diff --git a/content/modelisation/2_SVM.qmd b/content/modelisation/2_SVM.qmd index f753adecd..bddb12750 100644 --- a/content/modelisation/2_SVM.qmd +++ b/content/modelisation/2_SVM.qmd @@ -43,9 +43,6 @@ print_badges("content/modelisation/2_SVM.qmd") ``` ::: -Pour pouvoir importer les données, -nous allons importer les données suivantes: - ```{python} #| eval: false !pip install --upgrade xlrd @@ -54,7 +51,7 @@ nous allons importer les données suivantes: Nous allons partir du même jeu de données que précédemment, c'est-à-dire les résultats des élections US 2020 présentés dans l'[introduction -de cette partie](index.qmd): les données de vote aux élections présidentielles américaines +de cette partie](index.qmd) : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible [sur `Github`](https://github.com/linogaliana/python-datascientist/blob/master/content/modelisation/get_data.py). @@ -78,6 +75,7 @@ votes = getdata.create_votes_dataframes() Pour ce TP, nous aurons besoin des packages suivants : ```{python} +#| echo: true import pandas as pd import matplotlib.pyplot as plt ``` @@ -197,7 +195,7 @@ from sklearn.model_selection import cross_val_score 2. En utilisant la fonction prête à l'emploi nommée `train_test_split` de la librairie `sklearn.model_selection`, créer des échantillons de test (20 % des observations) et d'estimation (80 %) avec comme *features*: `'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"` et comme *label* la variable `y`. -*Note: Il se peut que vous ayez le warning suivant:* +*Note: Il se peut que vous ayez le warning suivant :* > A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel() @@ -390,7 +388,7 @@ disp.plot() plt.savefig("confusion_matrix3.png") ``` -Et la matrice de confusion associée: +Et la matrice de confusion associée : ![](confusion_matrix3.png) diff --git a/content/modelisation/3_regression.qmd b/content/modelisation/3_regression.qmd index b136c0e5d..82066cc05 100644 --- a/content/modelisation/3_regression.qmd +++ b/content/modelisation/3_regression.qmd @@ -45,7 +45,7 @@ print_badges("content/modelisation/3_regression.qmd") Nous allons partir du même jeu de données que précédemment, c'est-à-dire les résultats des élections US 2020 présentés dans l'[introduction -de cette partie](index.qmd): les données de vote aux élections présidentielles américaines +de cette partie](index.qmd) : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible [sur Github](https://github.com/linogaliana/python-datascientist/blob/master/content/modelisation/get_data.py). @@ -82,7 +82,7 @@ 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](index.qmd): les données de vote aux élections présidentielles américaines +de cette partie](index.qmd) : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible [sur Github](https://github.com/linogaliana/python-datascientist/blob/master/content/modelisation/get_data.py). @@ -416,7 +416,7 @@ englober ces modèles. Ce modèle s'applique à 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é: +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 diff --git a/content/modelisation/4_featureselection.qmd b/content/modelisation/4_featureselection.qmd index 2d67180e1..e2ddbcca9 100644 --- a/content/modelisation/4_featureselection.qmd +++ b/content/modelisation/4_featureselection.qmd @@ -54,7 +54,7 @@ print_badges("content/modelisation/4_featureselection.qmd") Pour illustrer le travail de données nécessaire pour faire de la sélection de variables, nous allons partir du même jeu de données que précédemment, c'est-à-dire les résultats des élections US 2020 présentés dans l'[introduction -de cette partie](index.qmd): les données de vote aux élections présidentielles américaines +de cette partie](index.qmd) : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible [sur Github](https://github.com/linogaliana/python-datascientist/blob/master/content/modelisation/get_data.py). @@ -85,7 +85,7 @@ computationnel que représenterait la construction d'un modèle avec un grand nombre de variables, le choix d'un nombre restreint de variables (modèle parcimonieux) limite le risque de sur-apprentissage. -Comment, dès-lors, choisir le bon nombre de variables et la meilleure +Comment, dès lors, choisir le bon nombre de variables et la meilleure combinaison de ces variables ? Il existe de multiples méthodes, parmi lesquelles : * se fonder sur des critères statistiques de performance qui pénalisent les diff --git a/content/modelisation/5_clustering.qmd b/content/modelisation/5_clustering.qmd index e2d5bd011..8ab3ac075 100644 --- a/content/modelisation/5_clustering.qmd +++ b/content/modelisation/5_clustering.qmd @@ -49,7 +49,7 @@ print_badges("content/modelisation/5_clustering.qmd") Nous allons continuer avec le même jeu de données que précédemment, c'est-à-dire les résultats des élections US 2020 présentés dans l'[introduction -de cette partie](index.qmd): les données de vote aux élections présidentielles américaines +de cette partie](index.qmd) : les données de vote aux élections présidentielles américaines croisées à des variables sociodémographiques. Le code est disponible [sur Github](https://github.com/linogaliana/python-datascientist/blob/master/content/modelisation/get_data.py). @@ -315,7 +315,7 @@ le vrai type d'une observation puisqu'on est en apprentissage non supervisé). Sans connaissance a priori du nombre de clusters, on peut recourir à deux familles de méthodes : -* **La méthode du coude** (*elbow method*): On prend le point d'inflexion de la courbe +* **La méthode du coude** (*elbow method*) : On prend le point d'inflexion de la courbe de performance du modèle. Cela représente le moment où ajouter un cluster (complexité croissante du modèle) n'apporte que des gains modérés dans la modélisation des données. diff --git a/content/modelisation/6_pipeline.qmd b/content/modelisation/6_pipeline.qmd index 28b14fe35..0363f90a8 100644 --- a/content/modelisation/6_pipeline.qmd +++ b/content/modelisation/6_pipeline.qmd @@ -246,7 +246,7 @@ import duckdb duckdb.sql(f'CREATE OR REPLACE VIEW dvf AS SELECT * FROM read_parquet("dvf.parquet")') ``` -Les données prennent la forme suivante: +Les données prennent la forme suivante : ```{python} #| echo: true @@ -519,7 +519,7 @@ mutations2 = mutations2.groupby('dep').sample(frac = 0.1, random_state = 123) Avec la fonction adéquate de `Scikit`, faire un découpage de `mutations2` en _train_ et _test sets_ -en suivant les consignes suivantes: +en suivant les consignes suivantes : - 20% des données dans l'échantillon de _test_ ; - L'échantillonnage est stratifié par départements ; @@ -813,7 +813,7 @@ g.ax.axline(xy1=(0, 0), slope=1, color="red", dashes=(5, 2)) ## Restriction du champ du modèle Mettre en oeuvre un bon modèle de prix au niveau France entière -est complexe. Nous allons donc nous restreindre au champ suivant: +est complexe. Nous allons donc nous restreindre au champ suivant : les appartements dans Paris. ```{python} @@ -1061,7 +1061,7 @@ print("Le RMSE sur le jeu de test est {:,}".format( )) ``` -Et si on regarde la qualité en prédiction: +Et si on regarde la qualité en prédiction : ```{python} #| include: false diff --git a/content/modelisation/index.qmd b/content/modelisation/index.qmd index 2053b983e..d1c3aef03 100644 --- a/content/modelisation/index.qmd +++ b/content/modelisation/index.qmd @@ -272,14 +272,14 @@ de performance sont généralement des moyennes plus ou moins sophistiquées d' la prédiction et la valeur observée. [^5]: Nous allons nous focaliser sur le cas binaire, le plus simple. Dans ce type de problèmes, -la variable $y$ a deux modalités: gagnant-perdant, 0-1, oui-non... Néanmoins il existe de +la variable $y$ a deux modalités : gagnant-perdant, 0-1, oui-non... Néanmoins il existe de nombreux cas d'usage où la variable dispose de plus de modalités, par exemples des scores de satisfaction entre 0 et 5 ou A et D. La mise en oeuvre de modèles est plus complexe mais l'idée générale est souvent de se ramener à un ensemble de modèles dichotomiques pour pouvoir appliquer des métriques simples et stables. -En résumé, l'aide-mémoire suivante, issue de l'aide de `Scikit-Learn`, peut déjà donner de premiers enseignements sur les différentes familles de modèles: +En résumé, l'aide-mémoire suivante, issue de l'aide de `Scikit-Learn`, peut déjà donner de premiers enseignements sur les différentes familles de modèles : ::: {#fig-algos-scikit layout-ncol=2} ![](https://scikit-learn.org/stable/_static/ml_map.png) diff --git a/content/modern-ds/continuous_integration.qmd b/content/modern-ds/continuous_integration.qmd index e54bf2f5c..a6cef7aff 100644 --- a/content/modern-ds/continuous_integration.qmd +++ b/content/modern-ds/continuous_integration.qmd @@ -174,7 +174,7 @@ Avouac (https://ensae-reproductibilite.github.io/website/). Quand on utilise un dépôt `Github` ou `Gitlab` , des services automatiques -d'intégration continue peuvent être utilisés: +d'intégration continue peuvent être utilisés : * `Gitlab CI`: solution pleinement intégrée à un dépôt `Gitlab`. Très généraliste et permettant des *pipelines* très complexes @@ -281,7 +281,7 @@ Il convient ainsi de lister les dépendances nécessaires dans un fichier ou un fichier `environment.yml` (si on préfère utiliser un environnement conda). Bien que le principe sous-jacent soit légèrement différent, -ces fichiers ont la même fonction: +ces fichiers ont la même fonction : permettre la création d'un environnement _ex-nihilo_ avec un certain nombre de dépendances pré-installées[^4]. diff --git a/content/modern-ds/dallE.qmd b/content/modern-ds/dallE.qmd index cbbcc2d10..9824e860e 100644 --- a/content/modern-ds/dallE.qmd +++ b/content/modern-ds/dallE.qmd @@ -271,7 +271,7 @@ openai.Image.create( ``` L'_output_ est un JSON avec les URL des images générées. -Voici les deux images générées: +Voici les deux images générées : ![](dallE.png) @@ -315,7 +315,7 @@ Sur `Colab`, `conda` n'est pas disponible par défaut. Pour pouvoir installer un package en utilisant `conda` sur `Colab`, on utilise donc l'astuce -suivante: +suivante : ```python !pip install -q condacolab @@ -469,7 +469,7 @@ prompt = "Chuck Norris fighting against Zeus on Mount Olympus in an epic Mortal ``` L'initialisation du modèle se fait de la manière -suivante: +suivante : ```{python} #| eval: false diff --git a/content/modern-ds/elastic_approfondissement.qmd b/content/modern-ds/elastic_approfondissement.qmd index 92c248912..01a647358 100644 --- a/content/modern-ds/elastic_approfondissement.qmd +++ b/content/modern-ds/elastic_approfondissement.qmd @@ -426,7 +426,7 @@ def gen_dict_from_pandas(index_name, df): Enfin, on peut industrialiser l'indexation de notre `DataFrame` en faisant tourner de -manière successive cette fonction: +manière successive cette fonction : ```{python} #| eval: false diff --git a/content/modern-ds/elastic_intro.qmd b/content/modern-ds/elastic_intro.qmd index f39fe7377..c43ebf29d 100644 --- a/content/modern-ds/elastic_intro.qmd +++ b/content/modern-ds/elastic_intro.qmd @@ -490,7 +490,7 @@ ciqual.head(2) ``` Après avoir mis en majuscule, on se retrouve avec le jeu de données -suivant: +suivant : ```{python} #| echo: false diff --git a/content/modern-ds/s3.qmd b/content/modern-ds/s3.qmd index 9ebc1ec3f..69c690b16 100644 --- a/content/modern-ds/s3.qmd +++ b/content/modern-ds/s3.qmd @@ -178,7 +178,7 @@ lorsqu'une donnée est disponible sous format de fichier(s), elle peut l'être d - Soit la donnée est stockée dans un seul fichier qui mélange contours géographiques et valeurs attributaires (la valeur associée à cette observation géographique, par exemple le taux d'abstention). Ce principe est celui du `geojson`. -- Soit la donnée est stockée dans plusieurs fichiers qui sont spécialisés: un fichier va stocker les contours géographiques, +- Soit la donnée est stockée dans plusieurs fichiers qui sont spécialisés : un fichier va stocker les contours géographiques, l'autre les données attributaires et d'autres fichiers des informations annexes (comme le système de projection). Ce principe est celui du `shapefile`. C'est alors le logiciel qui requête les données (`Python` par exemple) qui saura où aller chercher l'information @@ -251,7 +251,7 @@ mode dans l'écosystème récent de la _data science_ que les fichiers. # Le format `parquet` -Le format `CSV` a rencontré un grand succès par sa simplicité: il +Le format `CSV` a rencontré un grand succès par sa simplicité : il est lisible par un humain (un bloc-note suffit pour l'ouvrir et apercevoir les premières lignes), sa nature plate lui permet de bien correspondre au concept de données tabulées sans hiérarchie