Aller au contenu

80% sur Titanic Kaggle : un cas d’école pour structurer un projet data

·6 mins·
DataScience Kaggle

Aujourd’hui, je me penche sur le célèbre concours Kaggle du Titanic. Même s’il est devenu un grand classique, ce challenge reste une excellente façon de pratiquer sur des données claires, bien structurées, et facilement accessibles. Rien de révolutionnaire ici, mais c’est parfait pour se remettre dans le bain — ou tout simplement pour s’amuser un peu avec les bases.

1. Statistiques descriptives sur les données brutes
#

Le concours met à disposition deux jeux de données :

  • train (891 lignes, 11 variables)
  • test (418 lignes, 10 variables)

À première vue, ces datasets sont bien organisés, simples à utiliser, et assez intuitifs.

Voici un aperçu des variables proposées (le détail complet est disponible sur la page du concours Kaggle) :

Définitions des variables
Définitions des variables

Je commence par explorer les variables une par une avec des statistiques descriptives de base. Le but ici est de comprendre rapidement la nature des données, leur distribution, la présence d’outliers, de valeurs manquantes, etc.

On ne compte que 11 variables, bien remplies dans l’ensemble, avec peu de valeurs manquantes. Parfait pour commencer sans passer trop de temps à nettoyer.

2. Nettoyage des données & feature engineering
#

2.1. Création de nouvelles variables
#

“En data science, 80 % du temps est consacré à la préparation des données, et 20 % à râler parce qu’il faut préparer les données.”

Sur Kaggle, les datasets sont souvent déjà bien nettoyés, mais on peut pousser encore plus loin, et c’est d’ailleurs un des côtés intéressants : un bon modèle, ça commence par des variables bien pensées. L’objectif est alors de maximiser l’information utile sans rien gâcher.

VariableTypeDéfinition
SurvivalcatégoriqueC’est la variable cible \(y\) à prédire.
PclassordonnéeUtilisable en l’état
NamecatégoriqueSemble être structuré comme : name1, title, name2, name3 (nickname)
TitlecatégoriqueCréée à partir de Name : Mr, Mrs, Miss
HasNicknamecatégoriqueCréée à partir de Name, s’il a un surnom ou pas
SexcatégoriqueOK tel quel
AgecontinueImputation des valeurs manquantes avec la médiane par Title
IsChildcatégoriqueCréée à partir de Age : 1 si âge < 7 ; 0 sinon
AgeGroupcatégoriqueClasse par tranche de 10 ans
SibSpdiscrèteFrère et sœur
ParChdiscrèteLien de parenté
IsAlonecatégorique1 si pas de parent ni frère/sœur
IsFamilycatégorique1 si présence d’au moins un proche
FamilySizediscrèteSibSp + ParCh + 1
TicketcatégoriqueStructure du type : bureau de vente + numéro
TicketTextcatégoriquepremière partie si texte
TicketNumbercatégoriquedeuxième partie si numérique
HasFriendcatégoriquedétecte des proches via des numéros de ticket proches
FarecontinueImputation des valeurs manquantes par médiane selon Title
FareByPersoncontinueFare / FamilySize
CabincatégoriqueStructure : Deck, CabinNumber
Deckcatégoriquepremière lettre de Cabin (ou -1 si NA)
CabinNumbercatégoriquenuméro de cabine (ou -1 si NA)
EmbarkedcatégoriqueRemplissage des valeurs manquantes par la catégorie la plus fréquente

2.2. Suppression des variables devenues inutiles
#

Certaines variables d’origine ne sont plus utiles après transformation :

  • Name
  • Cabin
  • Ticket
  • TicketText
  • TicketNumber

2.3. Dataset intermédiaire
#

Après nettoyage et enrichissement, on obtient un jeu de données avec 17 variables explicatives catégorielles, prêtes à être utilisées pour la modélisation.

3. Analyse exploratoire des données (EDA)
#

3.1. Analyse univariée
#

On formule quelques hypothèses métier.

Quels profils de passagers ont eu plus de chances de survivre ? Quels facteurs semblent importants ? L’exploration permet d’y voir plus clair.

Je reprends donc mes nouvelles variables nettoyées, et j’en examine les statistiques descriptives.

Statistiques descriptives des variables
Statistiques descriptives des variables

Puis quelques distributions des variables indépendantes :

Distribution de Pclass, Sex et Embarked
Distribution de Pclass, Sex et Embarked

Distribution de IsChild, IsAlone et HasFriend
Distribution de IsChild, IsAlone et HasFriend

Distribution de Title et HasNickname
Distribution de Title et HasNickname

3.2. Analyse bivariée
#

Ensuite, j’analyse les relations entre chaque variable explicative et la variable cible \(y\) : Survived.

  • Premier élément marquant : un tarif de 512£ pour une seule personne attire mon attention.

FareByPerson en fonction de FamilySize
FareByPerson en fonction de FamilySize

Après vérification, il s’agit en fait d’une erreur sur les liens familiaux : c’était bien une famille, répartie sur trois cabines différentes, mais avec un seul ticket acheté.

Analyse croisée Survived par Pclass et Sex
Analyse croisée de Survived par Pclass et Sex

Les premiers effets nets apparaissent :

  • Les femmes en 1ʳᵉ classe ont des taux de survie bien supérieurs
  • Les hommes en 3ᵉ classe, sans surprise, sont les plus défavorisés.
À ajouter dans la prochaine mise à jour !
  • Tests d’indépendance (chi²)

3.3. Analyse multivariée
#

À ajouter dans la prochaine mise à jour !
  • Matrice de corrélation
  • PCA, FCA, MCA

4. Prétraitement des données
#

Avant de passer au machine learning, il faut finaliser le dataset. Je procède en deux temps :

  • Encodage des variables catégorielles : je crée des variables indicatrices (dummies) 0/1 pour toutes les variables catégorielles.
    Cela permet aux algorithmes de les traiter correctement, sans supposer d’ordre entre les catégories.
  • Normalisation des variables numériques : indispensable pour éviter que certaines variables (comme le tarif) ne dominent les autres.

Résultat : toutes les variables de mon jeu de données final sont numériques. On obtient une matrice d’entraînement \(X\) avec 41 variables prêtes à l’emploi.

5. Choix du modèle et validation croisée
#

Vient ensuite la phase de modélisation. Je teste plusieurs algorithmes classiques de classification pour comparer leurs performances.

Voici le tableau récapitulatif des performances par algorithme :

ClassifierScore
SVC0.826080
XGBClassifier0.821610
GradientBoostingClassifier0.812634
LogisticRegression0.810325
RandomForestClassifier0.809251
AdaBoostClassifier0.798077
BaggingClassifier0.792422
KNeighborsClassifier0.786804
DecisionTreeClassifier0.781199
GaussianNB0.732896

Je décide de ne retenir que les modèles avec un score supérieur à 80%, histoire de rester exigeant. La suite consistera à affiner, combiner, ou améliorer ces modèles — mais ça, c’est pour la prochaine partie.

6. Prédictions et performances
#

L’entraînement des différents modèles a produit des résultats assez homogènes, autour de 0,82 de score en validation croisée… sauf pour une méthode d’ensemble (stacking) qui a grimpé jusqu’à 0,91.

Mais attention, ce score ne reflète que la performance sur les données d’entraînement. En soumettant les prédictions sur Kaggle, la performance baisse : preuve que certains modèles surapprennent (overfitting).

Un score autour de 0,8 est considéré comme très bon sur cette compétition.

Voici les différences entre résultats de cross-validation et soumissions soumission sur Kaggle :

Cross-ValidationPrediction
RandomForestClassifier0.840.78
LogisticRegression0.810.77
GradientBoostingClassifier0.830.73
XGBClassifier0.840.75
SVC0.830.78
Stacking0.920.78

Ce décalage rappelle l’importance de généraliser et non juste de performer sur l’échantillon d’apprentissage.

Et il faut rester lucide : le classement Kaggle est parfois biaisé par des participants ayant un accès détourné aux données de test finales. Difficile donc d’aller beaucoup plus haut qu’un score de 0,80 sans tricher.


Références et inspirations
#

Pour progresser, j’ai consulté plusieurs sources utiles :

Études et tests assez sympas et originaux :

Certaines approches frisent l’absurde, d’autres sont brillantes — c’est aussi ce qui rend cette compétition amusante.

Le dataset complet (train + test + résultats) est disponible ici :

Thibault Clément - Intechnia
Auteur
Thibault Clément - Intechnia
Data scientist