Skip to content
Snippets Groups Projects
Commit bb29ddd3 authored by ROULOIS Alexandre's avatar ROULOIS Alexandre :bicyclist:
Browse files

Merge branch 'develop' into 'main'

Exercise on Titanic dataset

See merge request !8
parents 5932f581 eb2a2bfa
No related branches found
No related tags found
1 merge request!8Exercise on Titanic dataset
%% Cell type:markdown id:869ed322-c12e-47b1-b0e8-0c60721ec35f tags:
# Embarquement pour l’Amérique à bord du RMS *Titanic*
%% Cell type:markdown id:514a9244-338a-48da-9745-651f8070f7bf tags:
Le RMS *Titanic* est un paquebot qui fit naufrage le 15 avril 1912 avec à son bord quelques 2400 passagers dont Rose, Jack et au moins un contrebassiste. *Titanic* est aussi le nom d’un jeu de données qui fait partie des incontournables du *machine learning* et qui nous intéressera pour ce TD.
%% Cell type:markdown id:d030ff3d-4825-4056-bf3a-7dfed86c3564 tags:
## Contenu
%% Cell type:markdown id:afa7326c-2da2-4e12-9248-60ada1529611 tags:
Le fichier [*titanic.csv*](./files/titanic.csv) contient 891 observations décrites par 12 variables :
|Variable|Définition|
|:-:|-|
|*PassengerId*|Identifiant numérique du passager.|
|*Survived*|Facteur à deux niveaux : 0 pour indiquer que le passager n’a pas survécu ; 1 sinon.|
|*Pclass*|Facteur à trois niveaux pour caractériser la classe de transport : 1e, 2e ou 3e classe|
|*Name*|Nom du passager ou de la passagère.|
|*Sex*|Facteur à deux niveaux pour le sexe du passager ou de la passagère : *male* ou *female*.|
|*Age*|Âge, en nombre d’années. En dessous de 1 an, l’âge est exprimé en fraction décimale.|
|*SibSp*|Nombre de frères et sœurs (ou beaux-frères, belles-sœurs) et de maris ou femmes embarqué·es aussi sur le *Titanic*.|
|*Parch*|Nombre de parents et d’enfants embarqués sur le *Titanic*.|
|*Ticket*|Numéro de billet.|
|*Fare*|Tarif passager.|
|*Cabin*|Numéro de cabine.|
|*Embarked*|Facteur à trois niveaux pour coder le port d’embarquement : *C* = Cherbourg, *Q* = Queenstown, *S* = Southampton|
%% Cell type:markdown id:518e8f19-9bce-4b2f-8099-c98a9d324f44 tags:
## Importation du jeu de données
%% Cell type:markdown id:559dd9bf-132c-4590-9a5d-f2c65585180d tags:
Avant tout, commencez par importer la librairie *Pandas* :
%% Cell type:code id:f14db5b8-2fef-49d5-8cd6-0bd519e7b1f1 tags:
``` python
# your code here
import pandas as pd
```
%% Cell type:markdown id:49fa03f1-5208-49fc-9173-cce27db05eb0 tags:
À présent, grâce à la méthode `.read_csv()`, importez dans une variable `df` le fichier *titanic.csv* qui se trouve dans le sous-répertoire *files*, puis vérifiez avec `.head()` que l’opération s’est bien passée.
**Pour aller plus loin :** essayez d’identifier les variables catégorielles afin de typer correctement les données dès leur importation.
%% Cell type:code id:3f82d6b7-48c2-45a0-a5dc-ded217913f43 tags:
``` python
# your code here
dtype = {
"Pclass": "category",
"Sex": "category",
"Embarked": "category",
"Survived": "category"
}
df = pd.read_csv("./files/titanic.csv", dtype=dtype)
df.head()
```
%% Cell type:markdown id:021cdaa1-db4c-4508-bfde-ca184aaf250c tags:
Pour les besoins du TD, nous allons établir une liste des variables qui nous intéresseraient dans le cadre d’une tâche banale de classification en apprentissage supervisé. Il est d’usage de bien identifier les variables explicatives et la variable cible et de travailler sur une copie du fichier original qui restera toujours accessible dans `df` :
%% Cell type:code id:900e9fc6-fa8c-421b-b1e8-b4960e87eac3 tags:
``` python
target = "Survived"
features = ["Pclass", "Sex", "Age", "Fare", "Embarked"]
# a new data frame
data = pd.DataFrame( df[features + [target]] )
data.head()
```
%% Cell type:markdown id:2a19e0f0-d614-47a1-9cdc-198d28bcbf22 tags:
## Exploration des données
%% Cell type:markdown id:29153936-7955-4c4b-9d99-2fc6d4456c0a tags:
Avant de se lancer dans le moindre traitement, il est primordial de prendre du temps pour bien comprendre la structure des données. Et quel meilleur moyen sinon en calculant certaines mesures statistiques ou en les visualisant à l'aide de graphiques ?
Les manipulations ci-dessous ne sont pas exhaustives de ce que l’on souhaiterait en situation réelle, aussi n’hésitez pas à tester vos idées !
%% Cell type:markdown id:8a67b737-94b0-4251-9e9b-f68cdda523b4 tags:
### Visualisation
%% Cell type:markdown id:fe9a989e-9cb1-4f25-852c-952c1170b1ab tags:
Intéressons-nous en premier lieu à la variable `age` en regardant la répartition des effectifs en fonction de la modalité *Survived* :
%% Cell type:code id:b520fac1-c4a3-423b-ba49-ff759e73a1fe tags:
``` python
_ = data.hist(column="Age", by="Survived")
```
%% Cell type:markdown id:596ae6ee-609c-4a39-be5f-5a7ae5fafad9 tags:
Répétez l’opération pour connaître la répartition des hommes et des femmes pour chacune des mêmes modalités :
%% Cell type:code id:736a9da6-76ab-4fd1-800e-da773fd6b91f tags:
``` python
# your code here
_ = data.hist(column="Sex", by="Survived")
```
%% Cell type:markdown id:98912046-cb4e-497f-b83a-1d10d172e2f6 tags:
Un peu plus complexe, nous souhaitons obtenir le décompte des passager·ères qui ont survécu ou péri en fonction de leur port d’embarquement, afin de révéler peut-être une préférence nationale (les Irlandais en faveur des Irlandais etc…). Vous aurez besoin de dresser tout d’abord un tableau de contingence en comptabilisant les survivant·es et les péri·es en mer et en les différenciant selon la variable *Embarked* :
%% Cell type:code id:5dfc1d28-ba93-4f6a-ae45-420b2e6a01ad tags:
``` python
# your code here
a = pd.crosstab(index=data.Embarked, columns=data.Survived)
_ = a.plot.bar()
```
%% Cell type:markdown id:e1b61abc-dd54-4ef3-9fe4-197c53d7d074 tags:
### Mesures statistiques
%% Cell type:markdown id:89d923f3-6b28-48df-ae1a-dd577f322e4d tags:
La manière la plus rapide d’obtenir un aperçu des données est d’utiliser les méthodes `.describe()` et `.info()` :
%% Cell type:code id:84f14d5d-3c39-4100-8874-3971468833ef tags:
``` python
data.describe()
```
%% Cell type:code id:47a98948-8777-4d3e-b292-6fef314532fc tags:
``` python
data.info()
```
%% Cell type:markdown id:38a29a85-bf0c-4891-83a8-9324225d6a5f tags:
À l’aide de la méthode `.groupby()` sur le *data frame* `data`, affichez le prix moyen du billet en fonction du port d’embarquement et du sexe des passager·ères.
**Astuce :** le paramètre à transmettre s’appelle `by` et il accepte tout aussi bien une liste qu’une chaîne de caractères.
%% Cell type:code id:f6bce783-7763-4e00-bf81-b09976f9085a tags:
``` python
# your code here
fares = data.groupby(by=["Embarked", "Sex"]).Fare
fares.mean()
```
%% Cell type:markdown id:849df1f7-ac92-4e41-80b4-0f41e32c975f tags:
## Préparation des données
%% Cell type:markdown id:75043069-d32a-4f32-ba55-b032150260c1 tags:
Vous l’avez remarqué, l’étape de familiarisation avec le jeu de données est chronophage. Maintenant, nous allons nous atteler à la préapration du *dataset* en vue de son analyse future.
%% Cell type:markdown id:b6d6d692-9f62-400d-916b-f2acc4467671 tags:
### La chasse aux données manquantes
%% Cell type:markdown id:ffd012f7-d5aa-4bd8-ac37-b9c5f31537de tags:
Le résultat de l’instruction `data.info()` nous apprend que deux variables contiennent des données manquantes : *Age* et *Embarked*. Faites la somme pour chacune :
%% Cell type:code id:6208ba75-e2ad-45bc-89d5-51c1291578eb tags:
``` python
# your code here
nb_age_na = data.Age.isnull().sum()
nb_embarked_na = data.Embarked.isnull().sum()
print(
f"On ne connaît pas l’âge de { nb_age_na } passager·ères.",
f"Il manque { nb_embarked_na } indications du port d’embarquement.",
sep="\n"
)
```
%% Cell type:markdown id:d8ea47e4-ab3e-4de0-a52e-3742d8bb9fe1 tags:
Comme elles sont peu nombreuses, occupez-vous d’abord des données manquantes de la variable *Embarked*. Plutôt que de supprimer les observations concernées, attribuez-leur une valeur de votre convenance pour préciser explicitement que le port d’embarquement est inconnu.
**Remarque :** si vous avez transformé la variable *Embarked* en variable catégorielle, vous devrez au préalable rajouter une modalité avec `.cat.add_categories()`.
%% Cell type:code id:3abfa2a7-0160-476f-8857-49d6fc5dda7a tags:
``` python
# your code here
# new category "Unk" for "Unknown"
data.Embarked = data.Embarked.cat.add_categories(["Unk"])
# fill na
data.Embarked.fillna("Unk", inplace=True)
```
%% Cell type:markdown id:1d8b8e01-3598-43ec-9135-792678a49502 tags:
Pour la variable *Age*, choisissez la stratégie qui vous convient. Vous pourriez par exemple remplacer les valeurs manquantes par la moyenne des âges des passager·ères :
%% Cell type:code id:34778cd4-6f59-4523-b7ee-41e6c17b11d3 tags:
``` python
# your code here
# mean value
age_mean = data.Age.mean()
# fill na with mean
data.Age.fillna(age_mean, inplace=True)
```
%% Cell type:markdown id:18f81c62-c1c5-4778-956f-c283dac74eca tags:
### Le recodage de variables
%% Cell type:markdown id:7ae68d85-bf17-43e0-8aa3-ecd0411874de tags:
Recodez la variable *Sex* selon la convention suivante :
- *male* = 0 ;
- *female* = 1.
%% Cell type:code id:443af989-e856-4c01-915d-a1751cf8cab0 tags:
``` python
# your code here
translations = {
"male": 0,
"female": 1
}
data.replace(translations, inplace=True)
```
%% Cell type:markdown id:ecf043b1-2551-4635-98d1-eab4572af03b tags:
Une opération courante consiste à recoder la variable qui recueille l’âge des individus en variable catégorielle. Sachant que l’espérance de vie à la naissance en 1900 était d’à peu près 50 ans, constituez une nouvelle variable *age_cat* composée des modalités suivantes :
- En dessous de 20 ans ;
- de 20 à 50 ans ;
- \+ 50 ans.
%% Cell type:code id:39959a0a-c566-4c9a-b231-d984549c3989 tags:
``` python
# your code here
# (0-19] (19-50] (50-max]
bins = [0, 19, 50, data.Age.max()]
labels = ["-20 ans", "20-50 ans", "+ 50 ans"]
# segmentation
data["age_cat"] = pd.cut(data.Age, bins=bins, labels=labels)
```
%% Cell type:markdown id:5de716e3-dd74-4e2a-9a39-7a5ee6bfdf24 tags:
Une fois l’opération réalisée, il peut être intéressant de regarder la répartition des effectifs :
%% Cell type:code id:c220e114-38bb-4168-bcf5-9f3b81189fd5 tags:
``` python
_ = data.age_cat.value_counts(sort=False).plot.bar()
```
%% Cell type:markdown id:03f4a186-0d0d-434f-af47-0bc7587fbdf2 tags:
Ce qui nous permet d’estimer le taux de survie par classe d’âge :
%% Cell type:code id:d5f14968-41ab-4fff-89e4-59cad1fca508 tags:
``` python
s = pd.crosstab(index=data.Survived, columns=data.age_cat, margins=True)
# survival rate by age category
for cat in s:
print(f'{cat} : {(s[cat] / s[cat]["All"] * 100)["1"]:.2f} %')
```
%% Cell type:markdown id:869ed322-c12e-47b1-b0e8-0c60721ec35f tags:
# Embarquement pour l’Amérique à bord du RMS *Titanic*
%% Cell type:markdown id:514a9244-338a-48da-9745-651f8070f7bf tags:
Le RMS *Titanic* est un paquebot qui fit naufrage le 15 avril 1912 avec à son bord quelques 2400 passagers dont Rose, Jack et au moins un contrebassiste. *Titanic* est aussi le nom d’un jeu de données qui fait partie des incontournables du *machine learning* et qui nous intéressera pour ce TD.
%% Cell type:markdown id:d030ff3d-4825-4056-bf3a-7dfed86c3564 tags:
## Contenu
%% Cell type:markdown id:afa7326c-2da2-4e12-9248-60ada1529611 tags:
Le fichier [*titanic.csv*](./files/titanic.csv) contient 891 observations décrites par 12 variables :
|Variable|Définition|
|:-:|-|
|*PassengerId*|Identifiant numérique du passager.|
|*Survived*|Facteur à deux niveaux : 0 pour indiquer que le passager n’a pas survécu ; 1 sinon.|
|*Pclass*|Facteur à trois niveaux pour caractériser la classe de transport : 1e, 2e ou 3e classe|
|*Name*|Nom du passager ou de la passagère.|
|*Sex*|Facteur à deux niveaux pour le sexe du passager ou de la passagère : *male* ou *female*.|
|*Age*|Âge, en nombre d’années. En dessous de 1 an, l’âge est exprimé en fraction décimale.|
|*SibSp*|Nombre de frères et sœurs (ou beaux-frères, belles-sœurs) et de maris ou femmes embarqué·es aussi sur le *Titanic*.|
|*Parch*|Nombre de parents et d’enfants embarqués sur le *Titanic*.|
|*Ticket*|Numéro de billet.|
|*Fare*|Tarif passager.|
|*Cabin*|Numéro de cabine.|
|*Embarked*|Facteur à trois niveaux pour coder le port d’embarquement : *C* = Cherbourg, *Q* = Queenstown, *S* = Southampton|
%% Cell type:markdown id:518e8f19-9bce-4b2f-8099-c98a9d324f44 tags:
## Importation du jeu de données
%% Cell type:markdown id:559dd9bf-132c-4590-9a5d-f2c65585180d tags:
Avant tout, commencez par importer la librairie *Pandas* :
%% Cell type:code id:f14db5b8-2fef-49d5-8cd6-0bd519e7b1f1 tags:
``` python
# your code here
```
%% Cell type:markdown id:49fa03f1-5208-49fc-9173-cce27db05eb0 tags:
À présent, grâce à la méthode `.read_csv()`, importez dans une variable `df` le fichier *titanic.csv* qui se trouve dans le sous-répertoire *files*, puis vérifiez avec `.head()` que l’opération s’est bien passée.
**Pour aller plus loin :** essayez d’identifier les variables catégorielles afin de typer correctement les données dès leur importation.
%% Cell type:code id:3f82d6b7-48c2-45a0-a5dc-ded217913f43 tags:
``` python
# your code here
```
%% Cell type:markdown id:021cdaa1-db4c-4508-bfde-ca184aaf250c tags:
Pour les besoins du TD, nous allons établir une liste des variables qui nous intéresseraient dans le cadre d’une tâche banale de classification en apprentissage supervisé. Il est d’usage de bien identifier les variables explicatives et la variable cible et de travailler sur une copie du fichier original qui restera toujours accessible dans `df` :
%% Cell type:code id:900e9fc6-fa8c-421b-b1e8-b4960e87eac3 tags:
``` python
target = "Survived"
features = ["Pclass", "Sex", "Age", "Fare", "Embarked"]
# a new data frame
data = pd.DataFrame( df[features + [target]] )
data.head()
```
%% Cell type:markdown id:2a19e0f0-d614-47a1-9cdc-198d28bcbf22 tags:
## Exploration des données
%% Cell type:markdown id:29153936-7955-4c4b-9d99-2fc6d4456c0a tags:
Avant de se lancer dans le moindre traitement, il est primordial de prendre du temps pour bien comprendre la structure des données. Et quel meilleur moyen sinon en calculant certaines mesures statistiques ou en les visualisant à l'aide de graphiques ?
Les manipulations ci-dessous ne sont pas exhaustives de ce que l’on souhaiterait en situation réelle, aussi n’hésitez pas à tester vos idées !
%% Cell type:markdown id:8a67b737-94b0-4251-9e9b-f68cdda523b4 tags:
### Visualisation
%% Cell type:markdown id:fe9a989e-9cb1-4f25-852c-952c1170b1ab tags:
Intéressons-nous en premier lieu à la variable `age` en regardant la répartition des effectifs en fonction de la modalité *Survived* :
%% Cell type:code id:b520fac1-c4a3-423b-ba49-ff759e73a1fe tags:
``` python
_ = data.hist(column="Age", by="Survived")
```
%% Cell type:markdown id:596ae6ee-609c-4a39-be5f-5a7ae5fafad9 tags:
Répétez l’opération pour connaître la répartition des hommes et des femmes pour chacune des mêmes modalités :
%% Cell type:code id:736a9da6-76ab-4fd1-800e-da773fd6b91f tags:
``` python
# your code here
```
%% Cell type:markdown id:98912046-cb4e-497f-b83a-1d10d172e2f6 tags:
Un peu plus complexe, nous souhaitons obtenir le décompte des passager·ères qui ont survécu ou péri en fonction de leur port d’embarquement, afin de révéler peut-être une préférence nationale (les Irlandais en faveur des Irlandais etc…). Vous aurez besoin de dresser tout d’abord un tableau de contingence en comptabilisant les survivant·es et les péri·es en mer et en les différenciant selon la variable *Embarked* :
%% Cell type:code id:5dfc1d28-ba93-4f6a-ae45-420b2e6a01ad tags:
``` python
# your code here
```
%% Cell type:markdown id:e1b61abc-dd54-4ef3-9fe4-197c53d7d074 tags:
### Mesures statistiques
%% Cell type:markdown id:89d923f3-6b28-48df-ae1a-dd577f322e4d tags:
La manière la plus rapide d’obtenir un aperçu des données est d’utiliser les méthodes `.describe()` et `.info()` :
%% Cell type:code id:84f14d5d-3c39-4100-8874-3971468833ef tags:
``` python
data.describe()
```
%% Cell type:code id:47a98948-8777-4d3e-b292-6fef314532fc tags:
``` python
data.info()
```
%% Cell type:markdown id:38a29a85-bf0c-4891-83a8-9324225d6a5f tags:
À l’aide de la méthode `.groupby()` sur le *data frame* `data`, affichez le prix moyen du billet en fonction du port d’embarquement et du sexe des passager·ères.
**Astuce :** le paramètre à transmettre s’appelle `by` et il accepte tout aussi bien une liste qu’une chaîne de caractères.
%% Cell type:code id:f6bce783-7763-4e00-bf81-b09976f9085a tags:
``` python
# your code here
```
%% Cell type:markdown id:849df1f7-ac92-4e41-80b4-0f41e32c975f tags:
## Préparation des données
%% Cell type:markdown id:75043069-d32a-4f32-ba55-b032150260c1 tags:
Vous l’avez remarqué, l’étape de familiarisation avec le jeu de données est chronophage. Maintenant, nous allons nous atteler à la préapration du *dataset* en vue de son analyse future.
%% Cell type:markdown id:b6d6d692-9f62-400d-916b-f2acc4467671 tags:
### La chasse aux données manquantes
%% Cell type:markdown id:ffd012f7-d5aa-4bd8-ac37-b9c5f31537de tags:
Le résultat de l’instruction `data.info()` nous apprend que deux variables contiennent des données manquantes : *Age* et *Embarked*. Faites la somme pour chacune :
%% Cell type:code id:6208ba75-e2ad-45bc-89d5-51c1291578eb tags:
``` python
# your code here
```
%% Cell type:markdown id:d8ea47e4-ab3e-4de0-a52e-3742d8bb9fe1 tags:
Comme elles sont peu nombreuses, occupez-vous d’abord des données manquantes de la variable *Embarked*. Plutôt que de supprimer les observations concernées, attribuez-leur une valeur de votre convenance pour préciser explicitement que le port d’embarquement est inconnu.
**Remarque :** si vous avez transformé la variable *Embarked* en variable catégorielle, vous devrez au préalable rajouter une modalité avec `.cat.add_categories()`.
%% Cell type:code id:3abfa2a7-0160-476f-8857-49d6fc5dda7a tags:
``` python
# your code here
```
%% Cell type:markdown id:1d8b8e01-3598-43ec-9135-792678a49502 tags:
Pour la variable *Age*, choisissez la stratégie qui vous convient. Vous pourriez par exemple remplacer les valeurs manquantes par la moyenne des âges des passager·ères :
%% Cell type:code id:34778cd4-6f59-4523-b7ee-41e6c17b11d3 tags:
``` python
# your code here
```
%% Cell type:markdown id:18f81c62-c1c5-4778-956f-c283dac74eca tags:
### Le recodage de variables
%% Cell type:markdown id:7ae68d85-bf17-43e0-8aa3-ecd0411874de tags:
Recodez la variable *Sex* selon la convention suivante :
- *male* = 0 ;
- *female* = 1.
%% Cell type:code id:443af989-e856-4c01-915d-a1751cf8cab0 tags:
``` python
# your code here
```
%% Cell type:markdown id:ecf043b1-2551-4635-98d1-eab4572af03b tags:
Une opération courante consiste à recoder la variable qui recueille l’âge des individus en variable catégorielle. Sachant que l’espérance de vie à la naissance en 1900 était d’à peu près 50 ans, constituez une nouvelle variable *age_cat* composée des modalités suivantes :
- En dessous de 20 ans ;
- de 20 à 50 ans ;
- \+ 50 ans.
%% Cell type:code id:39959a0a-c566-4c9a-b231-d984549c3989 tags:
``` python
# your code here
```
%% Cell type:markdown id:5de716e3-dd74-4e2a-9a39-7a5ee6bfdf24 tags:
Une fois l’opération réalisée, il peut être intéressant de regarder la répartition des effectifs :
%% Cell type:code id:c220e114-38bb-4168-bcf5-9f3b81189fd5 tags:
``` python
_ = data.age_cat.value_counts(sort=False).plot.bar()
```
%% Cell type:markdown id:03f4a186-0d0d-434f-af47-0bc7587fbdf2 tags:
Ce qui nous permet d’estimer le taux de survie par classe d’âge :
%% Cell type:code id:d5f14968-41ab-4fff-89e4-59cad1fca508 tags:
``` python
s = pd.crosstab(index=data.Survived, columns=data.age_cat, margins=True)
# survival rate by age category
for cat in s:
print(f'{cat} : {(s[cat] / s[cat]["All"] * 100)["1"]:.2f} %')
```
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment