Notebook de travail — Titanic: exploration, préparation et modèle simple
Ce notebook a pour objectif de charger le dataset Titanic (depuis une URL publique), d’effectuer une exploration et un traitement simples, puis d’entraîner un modèle de classification basique (régression logistique) et d’en présenter les métriques principales.
IMPORTANT — consignes de l’Admin avant exécution
Cellules Markdown : la première cellule (celle-ci) précise le contenu et ce que chaque section doit contenir. Les cellules Markdown suivantes doivent rester pédagogiques et explicites ; l’Admin a déjà ajouté des explications structurées pour chaque section.
Dépendances : NE PAS exécuter d’installation inline (%pip install) dans ce notebook. Indiquez ces paquets comme PREREQUIS à installer hors notebook (par ex. dans l’environnement du kernel) : pandas, numpy, scikit-learn, matplotlib, seaborn, joblib. Exemple (hors notebook) : pip install pandas numpy scikit-learn matplotlib seaborn joblib
Chemins de sortie : toutes les sorties persistantes (figures, modèles, tables) doivent être écrites dans des chemins relatifs sous le dossier outputs/, p. ex. outputs/models/, outputs/figures/. Aucun chemin absolu ni chemin temporaire du kernel ne doit apparaître dans les sorties.
Traitement des warnings prévisibles : le notebook doit éviter les avertissements connus à la source lorsque c’est possible (par ex. éviter les affectations chainées pandas et utiliser .copy()). Pour les warnings restant (FutureWarning, ConvergenceWarning de sklearn), utilisez un filtrage ciblé via la bibliothèque warnings au début du notebook afin de garder la sortie lisible.
Plan du notebook (sections et rôle des cellules)
Prérequis (Markdown) : liste des dépendances à installer hors notebook et rappel sur outputs/.
Préparation de l’environnement (code) : imports, configuration de warnings et création des dossiers outputs/ si nécessaire.
Initialisation (code) : téléchargement (via pandas.read_csv) du jeu de données Titanic depuis une URL fiable, affichage sommaire et sauvegarde d’une copie dans outputs/data/titanic.csv.
Traitement (code) : nettoyage minimal (gestion des valeurs manquantes, transformation des variables catégorielles), création d’un jeu X / y et séparation train/test. Éviter les SettingWithCopyWarning en utilisant .copy().
Analyse (code + plots) : quelques visualisations simples (histogramme d’âge, taux de survie par sexe/classe) et sauvegarde des figures dans outputs/figures/.
Modélisation et évaluation (code) : entraînement d’un pipeline simple (imputation, encodage minimal, StandardScaler, LogisticRegression), rapport des métriques (accuracy, precision, recall, f1) sur le jeu de test et sauvegarde du modèle sous outputs/models/.
Conclusion (Markdown + code) : synthèse des résultats et chemins des fichiers sauvegardés.
Remarque administrative : le Coder devra remplir toutes les cellules de code laissées comme placeholders (“# Cellule N”). L’Admin exige des sorties explicites et des chemins relatifs. Après implémentation, le Reviewer pourra valider. Si Papermill ou le Reviewer signale une erreur, corriger la cellule indiquée puis relancer l’implémentation.
Fin de la cellule d’instruction de l’Admin.
# Cellule 0# Vérification légère de l'environnement et rappel des prérequis (à installer hors notebook).import sysprint(f"Python version: {sys.version.split()[0]}")print("Prérequis (installer hors notebook) : pandas, numpy, scikit-learn, matplotlib, seaborn, joblib")print("Les sorties persistantes seront écrites sous le dossier relatif 'outputs/'")
Python version: 3.13.14
Prérequis (installer hors notebook) : pandas, numpy, scikit-learn, matplotlib, seaborn, joblib
Les sorties persistantes seront écrites sous le dossier relatif 'outputs/'
1. Préparation de l’environnement
Cette cellule contient les imports, la configuration du filtrage des warnings et la création des dossiers outputs/ nécessaires pour sauvegarder les résultats.
Filtrage warnings : masquer FutureWarning et ConvergenceWarning (sklearn) et ignorer SettingWithCopyWarning en veillant toutefois à éviter les pratiques qui la provoquent.
Création des dossiers : outputs/, outputs/data/, outputs/figures/, outputs/models/.
La cellule de code suivante doit implémenter tout cela.
# Cellule 1import osimport warnings# Filtrage ciblé des warnings pour produire des sorties propresfrom warnings import filterwarningsfilterwarnings('ignore', category=FutureWarning)# sklearn ConvergenceWarning est parfois utile mais on le réduit icifrom sklearn.exceptions import ConvergenceWarningfilterwarnings('ignore', category=ConvergenceWarning)import pandas as pd# Ignorer SettingWithCopyWarning (nous évitons toutefois les pratiques qui le génèrent)filterwarnings('ignore', category=pd.errors.SettingWithCopyWarning)# On évite SettingWithCopyWarning en copiant les DataFrame quand nécessaireimport numpy as npimport matplotlibimport matplotlib.pyplot as pltimport seaborn as snsimport joblib# Dossiers de sortie relatifsOUTPUT_DIRS = ["outputs", "outputs/data", "outputs/figures", "outputs/models"]for d in OUTPUT_DIRS: os.makedirs(d, exist_ok=True)# Configuration visuellesns.set(style='whitegrid')plt.rcParams['figure.dpi'] =100print("Imports effectués et dossiers outputs/ créés :", ", ".join(OUTPUT_DIRS))
Téléchargement et chargement du dataset Titanic via pandas.read_csv depuis une URL publique fiable (par ex. l’URL du dataset Titanic sur le dépôt de Kaggle n’est pas directement utilisable ; on utilisera un miroir public tel que l’URL fournie par ‘raw.githubusercontent.com’ si disponible).
Actions attendues dans la cellule de code : - Charger les données dans un DataFrame pandas df. - Afficher les 5 premières lignes et un résumé (.info()) succinct. - Sauvegarder une copie brute dans outputs/data/titanic.csv
Si le téléchargement échoue (connexions restreintes), documenter brièvement le problème via un message clair et lever une exception contrôlée.
# Cellule 2import io# URL publique pour le dataset Titanic (raw GitHub mirror)TITANIC_URL = ("https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv")try: df = pd.read_csv(TITANIC_URL)exceptExceptionas e:raiseRuntimeError("Échec du téléchargement du dataset Titanic depuis internet. ""Vérifiez la connectivité ou fournissez le fichier localement." ) from e# Affichage sommaireprint("Dimensions du DataFrame:", df.shape)print("Colonnes:", df.columns.tolist())print("Aperçu (5 premières lignes):")print(df.head().to_string(index=False))print("\nRésumé succinct (.info):")buf = io.StringIO()df.info(buf=buf)info = buf.getvalue()print(info)# Sauvegarde d'une copie bruteraw_path = os.path.join("outputs", "data", "titanic.csv")df.to_csv(raw_path, index=False)print(f"Copie brute sauvegardée: {raw_path}")
Dimensions du DataFrame: (891, 12)
Colonnes: ['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked']
Aperçu (5 premières lignes):
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38.0 1 0 PC 17599 71.2833 C85 C
3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
Résumé succinct (.info):
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
Copie brute sauvegardée: outputs\data\titanic.csv
3. Traitement
Ici, nous effectuons les manipulations et traitements nécessaires pour atteindre les résultats escomptés.
# Cellule 3from sklearn.model_selection import train_test_splitfrom sklearn.impute import SimpleImputerfrom sklearn.preprocessing import OneHotEncoder, StandardScaler# Travail sur une copie pour éviter SettingWithCopyWarningdf_clean = df.copy()# Sélection de features simplesFEATURES = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]TARGET ="Survived"# Traitement des valeurs manquantes# Embarked a quelques valeurs manquantes -> remplir par la modalité la plus fréquenteif df_clean['Embarked'].isna().sum() >0: most_freq = df_clean['Embarked'].mode(dropna=True)[0] df_clean['Embarked'] = df_clean['Embarked'].fillna(most_freq)# Age et Fare -> laisser NaN pour imputer plus tard# Garder seulement les colonnes d'intérêtdf_model = df_clean[[TARGET] + FEATURES].copy()# Séparation train/testX = df_model[FEATURES].copy()y = df_model[TARGET].copy()X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.25, random_state=42, stratify=y)print("Taille train:", X_train.shape, "Taille test:", X_test.shape)# Sauvegarde des jeux bruts traités (optionnel)X_train.to_csv(os.path.join('outputs','data','X_train.csv'), index=False)y_train.to_csv(os.path.join('outputs','data','y_train.csv'), index=False)X_test.to_csv(os.path.join('outputs','data','X_test.csv'), index=False)y_test.to_csv(os.path.join('outputs','data','y_test.csv'), index=False)print("Jeux train/test sauvegardés sous outputs/data/")
Nous effectuons ici les vérifications, agrégats et visualisations nécessaires pour valider les résultats obtenus.
# Cellule 4import matplotlib.pyplot as pltimport seaborn as sns# Analyse simple et sauvegarde des figures dans outputs/figures/fig1_path = os.path.join('outputs','figures','age_histogram.png')plt.figure(figsize=(6,4))plt.hist(df['Age'].dropna(), bins=30, color='C0', edgecolor='k')plt.xlabel('Age')plt.ylabel('Count')plt.title('Histogramme des âges (Titanic)')plt.tight_layout()plt.savefig(fig1_path)plt.close()print('Figure sauvegardée:', fig1_path)# Taux de survie par sexefig2_path = os.path.join('outputs','figures','survival_by_sex.png')surv_by_sex = df.groupby('Sex')['Survived'].mean().reset_index()plt.figure(figsize=(5,4))sns.barplot(data=surv_by_sex, x='Sex', y='Survived', palette='muted')plt.ylabel('Taux de survie')plt.title('Taux de survie par sexe')plt.ylim(0,1)plt.tight_layout()plt.savefig(fig2_path)plt.close()print('Figure sauvegardée:', fig2_path)# Taux de survie par classefig3_path = os.path.join('outputs','figures','survival_by_pclass.png')surv_by_class = df.groupby('Pclass')['Survived'].mean().reset_index()plt.figure(figsize=(6,4))sns.barplot(data=surv_by_class, x='Pclass', y='Survived', palette='pastel')plt.ylabel('Taux de survie')plt.title('Taux de survie par Pclass')plt.ylim(0,1)plt.tight_layout()plt.savefig(fig3_path)plt.close()print('Figure sauvegardée:', fig3_path)print('Toutes les figures sont dans le dossier outputs/figures/')
Figure sauvegardée: outputs\figures\age_histogram.png
Figure sauvegardée: outputs\figures\survival_by_sex.png
Figure sauvegardée: outputs\figures\survival_by_pclass.png
Toutes les figures sont dans le dossier outputs/figures/
5. Conclusion
Concluons ici l’exécution et la validation de la tâche. Récapitulons les résultats obtenus. La cellule suivante peut servir de synthèse.
# Cellule 5from sklearn.pipeline import Pipelinefrom sklearn.compose import ColumnTransformerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report# Préparer transformateursnumeric_features = ["Age", "SibSp", "Parch", "Fare"]numeric_transformer = Pipeline(steps=[ ("imputer", SimpleImputer(strategy='median')), ("scaler", StandardScaler())])categorical_features = ["Pclass", "Sex", "Embarked"]# Pour Pclass on peut laisser tel quel (numérique ordinal) mais on encode tout en one-hot pour simplicitécategorical_transformer = Pipeline(steps=[ ("imputer", SimpleImputer(strategy='most_frequent')), ("onehot", OneHotEncoder(handle_unknown='ignore'))])preprocessor = ColumnTransformer( transformers=[ ("num", numeric_transformer, numeric_features), ("cat", categorical_transformer, categorical_features) ])clf = Pipeline(steps=[ ("preprocessor", preprocessor), ("clf", LogisticRegression(max_iter=1000, random_state=42))])# Entraînementclf.fit(X_train, y_train)# Évaluationy_pred = clf.predict(X_test)acc = accuracy_score(y_test, y_pred)prec = precision_score(y_test, y_pred)rec = recall_score(y_test, y_pred)f1 = f1_score(y_test, y_pred)print("Métriques sur le jeu de test:")print(f"Accuracy: {acc:.4f}")print(f"Precision: {prec:.4f}")print(f"Recall: {rec:.4f}")print(f"F1-score: {f1:.4f}")# Rapport détailléprint('\nRapport de classification:\n')print(classification_report(y_test, y_pred, digits=4))# Sauvegarde du modèlemodel_path = os.path.join('outputs','models','titanic_logreg.joblib')joblib.dump(clf, model_path)print('Modèle sauvegardé:', model_path)# Sauvegarde des métriques dans un petit fichier textemetrics_path = os.path.join('outputs','models','metrics.txt')withopen(metrics_path, 'w') as f: f.write(f"accuracy={acc:.6f}\nprecision={prec:.6f}\nrecall={rec:.6f}\nf1={f1:.6f}\n")print('Métriques sauvegardées:', metrics_path)print('\nTerminé. Fichiers produits:')print('-', os.path.join('outputs','data','titanic.csv'))print('-', os.path.join('outputs','figures','age_histogram.png'))print('-', os.path.join('outputs','models','titanic_logreg.joblib'))
Métriques sur le jeu de test:
Accuracy: 0.7758
Precision: 0.7250
Recall: 0.6744
F1-score: 0.6988
Rapport de classification:
precision recall f1-score support
0 0.8042 0.8394 0.8214 137
1 0.7250 0.6744 0.6988 86
accuracy 0.7758 223
macro avg 0.7646 0.7569 0.7601 223
weighted avg 0.7737 0.7758 0.7741 223
Modèle sauvegardé: outputs\models\titanic_logreg.joblib
Métriques sauvegardées: outputs\models\metrics.txt
Terminé. Fichiers produits:
- outputs\data\titanic.csv
- outputs\figures\age_histogram.png
- outputs\models\titanic_logreg.joblib
Lecture ancrée. Le modèle de régression logistique entraîné sur le dataset Titanic atteint des performances honorables avec une précision (accuracy) de 77.58% sur le jeu de test. Les autres métriques sont également instructives : une précision (precision) de 72.50% indique que lorsque le modèle prédit la survie, il a raison dans 72.5% des cas, tandis qu’un recall de 67.44% signifie qu’il identifie correctement 67.44% de tous les passagers ayant effectivement survécu. Le F1-score de 69.88%, qui harmonise précision et recall, confirme que le modèle capture correctement les patterns de survie dans ce dataset historique.