Top 25 Questions d'Entretien Data Science en 2026

Questions d'entretien en data science couvrant les statistiques, le machine learning, le feature engineering, le deep learning, SQL et la conception de systèmes — avec des exemples de code Python et des réponses détaillées pour 2026.

Questions d'entretien data science avec reseaux de neurones, graphiques statistiques et code Python sur fond sombre

Les entretiens en data science en 2026 vont bien au-delà des définitions théoriques. Les équipes de recrutement interrogent les candidats sur le raisonnement statistique, les compromis liés au feature engineering, l'évaluation de modèles au-delà de la simple précision, et la capacité à traduire des problèmes métier en pipelines analytiques. Ce guide couvre 25 questions qui reviennent régulièrement dans les entretiens de data scientist, des startups aux grandes entreprises technologiques.

Ce que les recruteurs évaluent réellement

Les entretiens en data science évaluent trois dimensions : les fondements statistiques (probabilités, tests d'hypothèses, distributions), les mécanismes du machine learning (biais-variance, régularisation, ensembles d'arbres) et le jugement appliqué (sélection de variables, choix de métriques, communication des résultats aux parties prenantes). Les candidats solides font le lien entre la théorie et l'impact concret en production.

Probabilités et statistiques fondamentales

Q1 : Une pièce est lancée 10 fois et tombe sur face 8 fois. La pièce est-elle truquée ?

La réponse intuitive serait « oui », mais l'approche rigoureuse consiste à appliquer un test binomial. Sous l'hypothèse nulle (pièce équilibrée, p=0,5), la probabilité d'obtenir 8 faces ou plus sur 10 lancers est d'environ 5,5 % — ce qui ne passe pas sous le seuil de signification standard de 5 %. La pièce ne peut donc pas être déclarée truquée à alpha = 0,05.

python
# binomial_test.py
from scipy import stats

# Two-sided binomial test: is the coin fair?
result = stats.binomtest(k=8, n=10, p=0.5, alternative='two-sided')
print(f"p-value: {result.pvalue:.4f}")  # 0.1094 (two-sided)
print(f"Reject H0 at alpha=0.05? {result.pvalue < 0.05}")  # False

Cette question permet de vérifier si le candidat se fie à son intuition ou applique un test d'hypothèse formel. Les recruteurs enchaînent souvent avec des questions sur les erreurs de type I et de type II, et sur la taille d'échantillon nécessaire pour détecter un biais de p=0,7 avec une puissance de 80 %.

Q2 : Expliquez la différence entre les approches bayésienne et fréquentiste de l'inférence.

L'inférence fréquentiste considère les paramètres comme fixes mais inconnus. Un intervalle de confiance à 95 % signifie : si l'expérience était répétée de nombreuses fois, 95 % des intervalles calculés contiendraient le vrai paramètre. L'inférence bayésienne traite les paramètres comme des variables aléatoires dotées de distributions a priori, et met à jour les croyances via le théorème de Bayes pour produire des distributions a posteriori. Un intervalle de crédibilité à 95 % signifie : étant donné les données observées et le prior, il y a 95 % de probabilité que le paramètre se trouve dans cet intervalle.

python
# bayesian_vs_frequentist.py
import numpy as np
from scipy import stats

# Frequentist: confidence interval for a mean
data = np.array([23.1, 25.4, 22.8, 24.9, 23.7, 25.1, 24.3])
ci = stats.t.interval(0.95, df=len(data)-1, loc=np.mean(data), scale=stats.sem(data))
print(f"95% CI (frequentist): [{ci[0]:.2f}, {ci[1]:.2f}]")

# Bayesian: posterior with conjugate prior (Normal-Normal)
prior_mean, prior_var = 24.0, 4.0  # prior belief
data_mean, data_var = np.mean(data), np.var(data, ddof=1) / len(data)
# Posterior parameters (conjugate update)
post_var = 1 / (1/prior_var + 1/data_var)
post_mean = post_var * (prior_mean/prior_var + data_mean/data_var)
post_ci = stats.norm.interval(0.95, loc=post_mean, scale=np.sqrt(post_var))
print(f"95% credible interval (Bayesian): [{post_ci[0]:.2f}, {post_ci[1]:.2f}]")

La différence pratique est importante en entretien : les méthodes bayésiennes intègrent les connaissances du domaine via les priors, ce qui est précieux lorsque les données sont peu nombreuses. Les méthodes fréquentistes font moins d'hypothèses mais nécessitent des échantillons plus larges pour une inférence fiable.

Q3 : Dans quels cas le théorème central limite échoue-t-il, et pourquoi est-ce important en data science ?

Le TCL garantit que les moyennes d'échantillon convergent vers une distribution normale à mesure que n augmente — mais seulement lorsque la population a une variance finie. Les distributions à queues lourdes (Cauchy, Pareto avec alpha inférieur ou égal à 2) violent cette hypothèse. En pratique, cela affecte la modélisation des rendements financiers, l'analyse du trafic réseau et tout domaine présentant des valeurs extrêmes. La médiane ou la moyenne tronquée devient alors un estimateur plus robuste.

Feature engineering et préparation des données

Q4 : Comment les valeurs manquantes affectent-elles l'entraînement d'un modèle, et quelles stratégies existent au-delà de la simple imputation ?

Les mécanismes de données manquantes déterminent la bonne stratégie. MCAR (Missing Completely At Random) permet la suppression des lignes sans biais. MAR (Missing At Random) bénéficie de l'imputation multiple ou d'approches basées sur des modèles. MNAR (Missing Not At Random) nécessite une modélisation spécifique au domaine du mécanisme de manque lui-même.

python
# missing_data_strategies.py
import pandas as pd
from sklearn.impute import KNNImputer, SimpleImputer
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

df = pd.DataFrame({
    'age': [25, 30, None, 45, None, 38],
    'income': [50000, None, 70000, 90000, 60000, None],
    'score': [85, 90, 78, None, 88, 92]
})

# Strategy 1: KNN imputation (preserves local structure)
knn_imp = KNNImputer(n_neighbors=2)
df_knn = pd.DataFrame(knn_imp.fit_transform(df), columns=df.columns)

# Strategy 2: Iterative imputation (MICE-like, models each feature)
iter_imp = IterativeImputer(max_iter=10, random_state=42)
df_iter = pd.DataFrame(iter_imp.fit_transform(df), columns=df.columns)

# Strategy 3: Add missingness indicator (preserves signal in the pattern)
df['income_missing'] = df['income'].isna().astype(int)
print(df_knn.round(1))

L'idée clé que les recruteurs recherchent : le schéma de manque lui-même peut être informatif. Ajouter des colonnes indicatrices binaires pour les variables présentant des valeurs manquantes améliore souvent les performances du modèle, particulièrement avec les arbres de gradient boosting.

Q5 : Expliquez le target encoding et dans quels cas il surpasse le one-hot encoding.

Le one-hot encoding crée une colonne binaire creuse par catégorie. Pour les variables à haute cardinalité (codes postaux, identifiants utilisateurs, SKU de produits), cela fait exploser la dimensionnalité. Le target encoding remplace chaque catégorie par la moyenne de la variable cible pour cette catégorie, produisant une seule colonne numérique dense.

python
# target_encoding.py
import pandas as pd
import numpy as np
from sklearn.model_selection import KFold

def target_encode_kfold(df, col, target, n_splits=5):
    """Target encoding with K-fold regularization to prevent leakage."""
    encoded = pd.Series(index=df.index, dtype=float)
    global_mean = df[target].mean()
    kf = KFold(n_splits=n_splits, shuffle=True, random_state=42)

    for train_idx, val_idx in kf.split(df):
        # Compute means only from training fold
        means = df.iloc[train_idx].groupby(col)[target].mean()
        encoded.iloc[val_idx] = df.iloc[val_idx][col].map(means)

    # Fill categories unseen in training fold with global mean
    encoded.fillna(global_mean, inplace=True)
    return encoded

df = pd.DataFrame({
    'city': ['Paris', 'Lyon', 'Paris', 'Marseille', 'Lyon', 'Paris',
             'Marseille', 'Lyon', 'Paris', 'Marseille'],
    'hired': [1, 0, 1, 0, 1, 1, 0, 0, 1, 1]
})
df['city_encoded'] = target_encode_kfold(df, 'city', 'hired')
print(df[['city', 'city_encoded', 'hired']])

L'approche par K-fold empêche la fuite de données en calculant les moyennes cibles uniquement sur les échantillons hors-fold. Sans cette régularisation, le target encoding surajuste sévèrement sur les petits jeux de données.

Prêt à réussir tes entretiens Data Science & ML ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Concepts fondamentaux du machine learning

Q6 : Qu'est-ce que le compromis biais-variance, et comment se manifeste-t-il dans les modèles à base d'arbres ?

Le biais mesure l'erreur systématique — à quel point les prédictions s'éloignent en moyenne des valeurs réelles. La variance mesure la sensibilité à l'ensemble d'entraînement — dans quelle mesure les prédictions changent d'un échantillon à l'autre. Un arbre de décision profond présente un faible biais mais une variance élevée : il mémorise les données d'entraînement. Une forêt aléatoire réduit la variance par agrégation bootstrap (bagging) tout en maintenant un faible biais. Les arbres de gradient boosting réduisent le biais de manière itérative en ajustant les résidus, mais risquent d'augmenter la variance sans régularisation appropriée (taux d'apprentissage, profondeur maximale, sous-échantillonnage).

Q7 : Pourquoi la précision (accuracy) échoue-t-elle comme métrique pour les jeux de données déséquilibrés ? Quelles alternatives existent ?

Sur un jeu de données avec 95 % de négatifs et 5 % de positifs, un modèle qui prédit toujours « négatif » atteint 95 % de précision tout en étant complètement inutile. Les courbes précision-rappel, le score F1 et l'aire sous la courbe précision-rappel (AUPRC) capturent mieux les performances sur la classe minoritaire. Pour les tâches de classement, l'AUC-ROC fonctionne bien car elle évalue la capacité de discrimination à tous les seuils.

python
# imbalanced_metrics.py
from sklearn.metrics import (
    classification_report, precision_recall_curve,
    average_precision_score, roc_auc_score
)
import numpy as np

# Simulated predictions on imbalanced data
np.random.seed(42)
y_true = np.array([0]*950 + [1]*50)  # 95/5 imbalance
y_scores = np.random.beta(2, 5, 1000)  # predicted probabilities
y_scores[y_true == 1] += 0.3  # positive class scores slightly higher
y_scores = np.clip(y_scores, 0, 1)
y_pred = (y_scores > 0.5).astype(int)

print(classification_report(y_true, y_pred, digits=3))
print(f"ROC AUC: {roc_auc_score(y_true, y_scores):.3f}")
print(f"Average Precision (AUPRC): {average_precision_score(y_true, y_scores):.3f}")

La question de suivi porte souvent sur : « Comment choisir entre précision et rappel ? » La réponse dépend du coût des faux positifs versus les faux négatifs. La détection de fraude privilégie le rappel (détecter la fraude compte plus que les fausses alarmes). Le filtrage des spams privilégie la précision (les faux positifs dérangent plus les utilisateurs que les spams manqués).

Q8 : Expliquez les régularisations L1 et L2 et dans quels cas privilégier chacune.

La régularisation L1 (Lasso) ajoute la somme des valeurs absolues des poids à la fonction de perte, poussant certains coefficients exactement à zéro. Cela produit des modèles parcimonieux et agit comme une sélection de variables intégrée. La régularisation L2 (Ridge) ajoute la somme des carrés des poids, réduisant tous les coefficients vers zéro sans en éliminer. Privilégier L1 lorsque de nombreuses variables sont non pertinentes et que la parcimonie est souhaitée. Privilégier L2 lorsque toutes les variables contribuent et que la multicolinéarité est présente. L'Elastic Net combine les deux et constitue souvent le choix par défaut lorsque le ratio optimal est inconnu.

Q9 : Comment les arbres de gradient boosting (XGBoost/LightGBM) gèrent-ils différemment les variables catégorielles ?

XGBoost nécessite traditionnellement un encodage one-hot ou ordinal avant l'entraînement. LightGBM gère nativement les variables catégorielles via un algorithme de recherche de coupures optimal qui regroupe les catégories par leurs statistiques de gradient, réduisant l'espace de recherche exponentiel à un temps linéaire. Cette gestion native surpasse souvent le one-hot encoding, en particulier pour les variables à haute cardinalité, et explique pourquoi LightGBM s'entraîne généralement plus rapidement sur les jeux de données tabulaires.

Évaluation et validation des modèles

Q10 : Qu'est-ce que la fuite de données (data leakage), et quelles en sont les trois sources les plus courantes ?

La fuite de données survient lorsque des informations extérieures à la distribution d'entraînement s'infiltrent dans le modèle, gonflant les métriques de validation mais dégradant les performances en production. Les trois sources les plus courantes :

  1. Fuite temporelle : utiliser des données futures pour prédire le passé (par exemple, utiliser la valeur vie d'un client pour prédire le churn du premier mois)
  2. Fuite de la cible : variables dérivées de la variable cible (par exemple, « nombre de remboursements » pour prédire « demandera un remboursement »)
  3. Fuite de prétraitement : ajustement des scalers, encodeurs ou imputeurs sur l'ensemble du jeu de données avant la division
python
# leakage_prevention.py
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import cross_val_score
import numpy as np

X = np.random.randn(1000, 10)
y = (X[:, 0] + X[:, 1] > 0).astype(int)

# WRONG: fit scaler on all data, then cross-validate
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)  # leakage: test fold info in scaling

# CORRECT: pipeline ensures preprocessing fits only on training folds
pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler()),
    ('model', GradientBoostingClassifier(n_estimators=100, random_state=42))
])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='roc_auc')
print(f"AUC (no leakage): {scores.mean():.3f} +/- {scores.std():.3f}")

Les Pipelines scikit-learn constituent la défense standard contre la fuite de prétraitement. Chaque étape de transformation dans le pipeline se réajuste indépendamment sur chaque fold d'entraînement.

Q11 : Quand la validation croisée pour séries temporelles doit-elle remplacer le K-fold standard ?

Le K-fold standard mélange aléatoirement les données, ce qui brise l'ordre temporel. Pour tout jeu de données dont les lignes ont une composante temporelle (cours boursiers, activité utilisateur, données de capteurs), cela crée une fuite du futur vers le passé. La validation croisée pour séries temporelles utilise des fenêtres expansibles ou glissantes : l'ensemble d'entraînement de chaque fold ne contient que des données antérieures à l'ensemble de validation. Scikit-learn fournit TimeSeriesSplit pour ce schéma.

Piège classique en entretien

Les candidats affirment souvent qu'ils « utilisent toujours la validation croisée K-fold ». Les recruteurs testent alors avec des scénarios de données temporelles ou groupées où le K-fold est incorrect. Il faut savoir quand utiliser TimeSeriesSplit, GroupKFold ou StratifiedKFold selon la structure des données.

Deep learning et réseaux de neurones

Q12 : Pourquoi les réseaux profonds utilisent-ils ReLU plutôt que sigmoïde, et quand ReLU échoue-t-il ?

La sigmoïde compresse les sorties dans (0, 1), mais son gradient s'évanouit pour les entrées extrêmes — proche de 0 ou de 1, le gradient tend vers zéro, bloquant la rétropropagation dans les réseaux profonds. ReLU (max(0, x)) possède un gradient constant de 1 pour les entrées positives, permettant un entraînement plus rapide. ReLU échoue lorsque les neurones reçoivent des entrées constamment négatives (problème des « neurones morts »), produisant des gradients nuls de manière permanente. Leaky ReLU et GELU (utilisé dans les Transformers) y remédient en autorisant de petits gradients pour les valeurs négatives.

Q13 : Expliquez le mécanisme d'attention et pourquoi les Transformers ont remplacé les RNN pour les tâches de séquence.

Les RNN traitent les séquences pas à pas, créant un goulot d'étranglement : les informations des premiers tokens doivent survivre à travers chaque état caché suivant. L'attention calcule des relations directes par paires entre toutes les positions simultanément, avec une complexité O(n²) mais une parallélisation totale. L'auto-attention dans les Transformers produit des matrices Query, Key et Value à partir de l'entrée, calculant les poids d'attention comme softmax(QK^T / sqrt(d_k)) * V.

python
# self_attention.py
import torch
import torch.nn.functional as F

def self_attention(x, d_k):
    """Scaled dot-product self-attention from scratch."""
    # x shape: (batch_size, seq_len, d_model)
    batch_size, seq_len, d_model = x.shape

    # Linear projections for Q, K, V
    W_q = torch.randn(d_model, d_k) * 0.1
    W_k = torch.randn(d_model, d_k) * 0.1
    W_v = torch.randn(d_model, d_k) * 0.1

    Q = x @ W_q  # (batch, seq_len, d_k)
    K = x @ W_k
    V = x @ W_v

    # Scaled dot-product attention
    scores = Q @ K.transpose(-2, -1) / (d_k ** 0.5)  # (batch, seq_len, seq_len)
    weights = F.softmax(scores, dim=-1)  # attention weights
    output = weights @ V  # (batch, seq_len, d_k)

    return output, weights

# Example: 1 batch, 4 tokens, 8-dim embeddings
x = torch.randn(1, 4, 8)
out, attn = self_attention(x, d_k=8)
print(f"Output shape: {out.shape}")    # (1, 4, 8)
print(f"Attention weights:\n{attn[0].detach().numpy().round(3)}")

L'avantage clé : l'attention permet au modèle de connecter directement deux positions quelconques quelle que soit la distance, résolvant le problème de dépendance à longue portée qui affectait les LSTM.

Q14 : Quelle est la différence entre le fine-tuning et le transfer learning, et quand chacun s'applique-t-il ?

Le transfer learning utilise les représentations apprises d'un modèle pré-entraîné comme point de départ. Le fine-tuning est une stratégie de transfer learning spécifique qui libère certaines ou toutes les couches pré-entraînées et poursuit l'entraînement sur la tâche cible. L'extraction de features (une autre stratégie) gèle toutes les couches pré-entraînées et entraîne uniquement une nouvelle tête de classification. Le fine-tuning fonctionne mieux avec des données cibles modérées (milliers d'exemples). L'extraction de features convient aux petits jeux de données où le fine-tuning complet surapprendrait.

SQL et manipulation des données

Q15 : Écrivez une requête pour trouver le deuxième salaire le plus élevé dans chaque département sans utiliser les fonctions de fenêtre.

sql
-- second_highest_salary.sql
-- Approach: correlated subquery counting distinct higher salaries
SELECT d.department_name, e.employee_name, e.salary
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE (
    SELECT COUNT(DISTINCT e2.salary)
    FROM employees e2
    WHERE e2.department_id = e.department_id
      AND e2.salary > e.salary
) = 1
ORDER BY d.department_name;

Les recruteurs utilisent cette question pour vérifier les fondamentaux SQL sans la commodité de RANK() ou DENSE_RANK(). La question de suivi consiste à résoudre le problème avec des fonctions de fenêtre, ce qui est plus élégant mais teste une compétence différente.

Q16 : Expliquez la différence entre WHERE et HAVING. À quel moment chacun est-il évalué ?

WHERE filtre les lignes avant l'agrégation. HAVING filtre les groupes après l'agrégation. Dans l'ordre d'exécution SQL, WHERE s'applique lors de la phase de lecture des lignes, GROUP BY crée les groupes, les fonctions d'agrégat calculent, puis HAVING filtre ces groupes. Une erreur courante : utiliser HAVING sans GROUP BY ou tenter de référencer des alias définis dans SELECT depuis WHERE.

Data science appliquée et conception de systèmes

Q17 : Comment concevriez-vous un test A/B pour un nouvel algorithme de recommandation ?

La conception nécessite cinq composantes : (1) une métrique primaire claire (taux de clics, taux de conversion ou revenu par utilisateur), (2) une analyse de puissance pour déterminer la taille d'échantillon, (3) une randomisation au niveau de l'utilisateur (et non de la session, pour éviter la contamination croisée), (4) des métriques de garde-fou qui ne doivent pas se dégrader (latence, taux de crash), et (5) un plan d'analyse pré-enregistré pour éviter le p-hacking.

Calcul de la taille d'échantillon

Pour un test z à deux proportions détectant un gain absolu de 2 % (de 10 % à 12 % de CTR) avec une puissance de 80 % et alpha=0,05, environ 3 800 utilisateurs par groupe sont nécessaires. Des effets attendus plus faibles requièrent des échantillons exponentiellement plus grands. Toujours réaliser une analyse de puissance avant le lancement.

Q18 : Un modèle performe bien en validation mais mal en production. Quelles sont les trois causes principales ?

  1. Dérive de distribution : les données d'entraînement ne représentent pas le trafic en production (démographies utilisateurs différentes, périodes ou géographies différentes)
  2. Divergence de features : les variables calculées différemment dans les pipelines d'entraînement (batch) et de service (temps réel) — analyse des timestamps, gestion des valeurs manquantes ou fenêtres d'agrégation divergent
  3. Fuite de label : le label d'entraînement a été dérivé de données indisponibles au moment de la prédiction en production

Le débogage commence par comparer les distributions de variables entre l'entraînement et la production via des tests statistiques (test KS, PSI — Population Stability Index) sur chaque variable indépendamment.

Q19 : Expliquez le théorème CAP et ses implications pour les feature stores en ML.

CAP stipule qu'un système distribué peut garantir au plus deux des trois propriétés : Cohérence (chaque lecture retourne la dernière écriture), Disponibilité (chaque requête reçoit une réponse) et Tolérance aux partitions (le système fonctionne malgré les pannes réseau). Les feature stores font directement face à ce compromis : les stores en ligne (Redis, DynamoDB) privilégient la disponibilité et la tolérance aux partitions, acceptant une cohérence éventuelle. Les stores hors ligne (BigQuery, Hive) privilégient la cohérence pour l'entraînement en batch. Une architecture dual-store répond aux deux besoins.

Q20 : Comment gérer la dérive conceptuelle (concept drift) dans un système ML en production ?

La dérive conceptuelle survient lorsque la relation statistique entre les variables et la cible change au fil du temps. Les méthodes de détection incluent la surveillance des changements de distribution des prédictions (PSI sur les sorties du modèle), le suivi des métriques de performance sur des données de production étiquetées, et les tests statistiques sur les distributions des variables entrantes. Stratégies d'atténuation : réentraînement planifié sur une fenêtre glissante, apprentissage en ligne pour la dérive progressive, ou déclenchement du réentraînement lorsque les métriques de dérive dépassent des seuils.

Prêt à réussir tes entretiens Data Science & ML ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Python et maîtrise de Pandas

Q21 : Quelle est la différence entre apply(), map() et transform() dans Pandas ?

map() opère élément par élément sur une Series uniquement. apply() fonctionne sur les Series et les DataFrames, passant chaque ligne ou colonne à une fonction. transform() exige que la sortie ait la même forme que l'entrée — elle ne peut pas agréger. L'implication pratique : transform() permet des calculs au niveau du groupe qui se diffusent vers l'index d'origine, ce que apply() peut faire mais moins efficacement.

python
# pandas_operations.py
import pandas as pd

df = pd.DataFrame({
    'team': ['A', 'A', 'B', 'B', 'A'],
    'score': [10, 20, 30, 40, 50]
})

# map: element-wise on Series
df['team_upper'] = df['team'].map({'A': 'Alpha', 'B': 'Beta'})

# apply: arbitrary function per row
df['score_label'] = df['score'].apply(lambda x: 'high' if x > 25 else 'low')

# transform: group-level, same shape output (broadcasts back)
df['team_mean'] = df.groupby('team')['score'].transform('mean')
df['score_normalized'] = df.groupby('team')['score'].transform(
    lambda x: (x - x.mean()) / x.std()
)
print(df)

Q22 : Expliquez le GIL de Python et son impact sur les workflows data science.

Le Global Interpreter Lock empêche plusieurs threads d'exécuter simultanément du bytecode Python. Les tâches liées au CPU (calcul numérique, entraînement de modèles) ne bénéficient pas du multithreading. C'est pourquoi NumPy, Pandas et scikit-learn utilisent des extensions C qui libèrent le GIL, et pourquoi le multiprocessing (et non le threading) est la stratégie de parallélisme standard pour le code Python pur. Pour les tâches liées aux I/O (appels API, requêtes de base de données), le threading fonctionne car le GIL est libéré pendant les attentes I/O.

Réduction de dimensionnalité et apprentissage non supervisé

Q23 : PCA vs t-SNE vs UMAP — quand chacun s'applique-t-il ?

PCA est une méthode linéaire qui maximise la variance dans les dimensions projetées. Elle préserve la structure globale et est déterministe, la rendant adaptée au prétraitement (réduction du nombre de variables avant la modélisation) et à la visualisation interprétable. t-SNE est non linéaire, optimisé pour la visualisation 2D/3D en préservant les voisinages locaux. Il distord les distances globales et ne convient pas au prétraitement. UMAP préserve mieux la structure locale et globale que t-SNE, s'exécute plus rapidement sur les grands jeux de données et produit des résultats plus cohérents d'une exécution à l'autre.

| Method | Linear | Preserves Global Structure | Speed (100K points) | Use Case | |--------|--------|---------------------------|---------------------|----------| | PCA | Yes | Yes | Seconds | Preprocessing, feature reduction | | t-SNE | No | No | Minutes | Cluster visualization (small data) | | UMAP | No | Partially | Seconds | Visualization + preprocessing |

Q24 : Dans quels cas K-means échoue-t-il, et quelles alternatives gèrent les clusters non sphériques ?

K-means suppose des clusters sphériques de taille égale et utilise la distance euclidienne. Il échoue sur les clusters allongés, annulaires ou à densité variable. DBSCAN identifie les clusters par densité, gérant des formes arbitraires et détectant automatiquement les valeurs aberrantes. Les modèles de mélanges gaussiens (GMM) modélisent chaque cluster comme une gaussienne multivariée, autorisant des formes elliptiques. Le clustering spectral utilise les vecteurs propres du Laplacien de graphe et gère des géométries complexes mais passe mal à l'échelle au-delà de 10 000 points.

Communication et impact métier

Q25 : Un responsable vous demande : « Quelles sont les variables les plus importantes dans le modèle ? » Comment répondez-vous ?

L'importance des variables possède plusieurs définitions valides, et la réponse dépend de l'audience. Pour les modèles à base d'arbres, trois mesures courantes existent : l'importance par coupure (fréquence d'utilisation d'une variable dans les coupures), l'importance par gain (réduction totale de la perte due aux coupures sur cette variable) et l'importance par permutation (dégradation des performances lorsqu'une variable est mélangée aléatoirement). Les valeurs SHAP offrent la réponse la plus rigoureuse : elles quantifient la contribution de chaque variable aux prédictions individuelles en utilisant des principes de la théorie des jeux.

python
# feature_importance_shap.py
import shap
import xgboost as xgb
from sklearn.datasets import make_classification

# Generate synthetic dataset
X, y = make_classification(n_samples=1000, n_features=10,
                           n_informative=5, random_state=42)

# Train XGBoost model
model = xgb.XGBClassifier(n_estimators=100, random_state=42, eval_metric='logloss')
model.fit(X, y)

# SHAP explanation
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)

# Global importance: mean absolute SHAP value per feature
import numpy as np
importance = np.abs(shap_values).mean(axis=0)
for i in np.argsort(importance)[::-1]:
    print(f"Feature {i}: {importance[i]:.4f}")

Pour les parties prenantes, il convient de traduire les valeurs SHAP en langage métier : « Les clients avec un revenu supérieur à 80 000 € sont 15 % plus susceptibles de convertir, toutes choses égales par ailleurs » plutôt que « La variable 3 a une valeur SHAP moyenne de 0,23. »

Conclusion

  • La rigueur en tests d'hypothèses compte : savoir quand appliquer un test binomial, comprendre les p-values et distinguer les approches bayésienne et fréquentiste
  • Le feature engineering détermine souvent les performances du modèle plus que le choix d'algorithme — maîtriser le target encoding, les stratégies de gestion des valeurs manquantes et la prévention des fuites de données
  • L'évaluation va au-delà de la précision : utiliser AUPRC pour les données déséquilibrées, TimeSeriesSplit pour les données temporelles et les pipelines pour éviter la fuite de prétraitement
  • Les fondamentaux du deep learning (attention, fonctions d'activation, transfer learning) apparaissent même dans les postes de data science qui utilisent principalement des méthodes tabulaires
  • Les questions de ML en production (détection de dérive, tests A/B, feature stores) différencient de plus en plus les candidats seniors des juniors
  • Les compétences de communication sont testées à travers l'explication de l'importance des variables — s'entraîner à traduire les valeurs SHAP en langage compréhensible par les parties prenantes

Passe à la pratique !

Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.

Tags

#data-science
#interview
#machine-learning
#python
#statistics

Partager

Articles similaires