Python

Pratique de l’apprentissage automatique avec scikit-learn et TensorFlow

×

Recommandés

Cet article vous guide, pas à pas, de la préparation des données jusqu’au déploiement d’un modèle, en combinant scikit-learn (excellente boîte à outils pour données tabulaires) et TensorFlow/Keras (référence pour les réseaux de neurones). On y trouve : une méthodologie solide, des métriques adaptées, des pipelines reproductibles, de la mise au point, des interprétations, et des pistes de mise en production.


1) Quand utiliser scikit-learn, quand utiliser TensorFlow ?

  • scikit-learn : données tabulaires (CSV/SQL), tailles petites à moyennes, modèles linéaires/arbres/forêts/XGBoost* (non inclus nativement), sélection de variables, pipelines et validations croisées très simples à mettre en place.
  • TensorFlow/Keras : images, texte, audio, séries temporelles complexes, grands volumes de données, GPU, modèles profonds (CNN, RNN, Transformers), déploiement mobile/edge (TFLite), serving à grande échelle.

Le plus courant dans un projet : scikit-learn pour le prétraitement + Keras pour le modèle profond, ou bien tout-scikit-learn lorsque la donnée est tabulaire.


2) Préparer l’environnement

python -m pip install --upgrade pip
pip install numpy pandas scikit-learn tensorflow
# (optionnel) pour intégrer Keras au style scikit-learn :
pip install scikeras

3) Méthodologie incontournable

  1. Formuler le problème (classification binaire/multiclasse, régression, ranking).
  2. Séparer tôt les données : train/validation/test (ex. 70/15/15). Éviter toute fuite de données (data leakage).
  3. Établir une baseline (modèle simple, règles métiers).
  4. Pipeline de prétraitement (imputation, encodage, standardisation) avec ColumnTransformer/Pipeline.
  5. Sélection du modèle + validation croisée + recherche d’hyperparamètres.
  6. Interpréter & auditer (importance des variables, erreurs, biais).
  7. Emballer le pipeline, sauvegarder, tester en conditions proches de la prod.
  8. Surveiller en production (drift, qualité, coût).

4) scikit-learn : pipeline complet (tabulaire)

4.1 Charger un dataset d’exemple (classification)

import numpy as np, pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)

4.2 Prétraitement + modèle dans un Pipeline

  • Imputation valeurs manquantes,
  • Standardisation,
  • Modèle (logistique ou forêt aléatoire).
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

pipe = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler()),
    ("clf", LogisticRegression(max_iter=1000))
])

pipe.fit(X_train, y_train)

4.3 Évaluation multi-métriques

from sklearn.metrics import classification_report, roc_auc_score

y_pred = pipe.predict(X_test)
y_proba = pipe.predict_proba(X_test)[:, 1]

print(classification_report(y_test, y_pred))
print("ROC AUC:", roc_auc_score(y_test, y_proba))

Choix des métriques

  • Classification : précision/recall/F1, ROC AUC, PR AUC pour classes très déséquilibrées.
  • Régression : RMSE/MAE, R².
  • Business first : coût d’une erreur, seuils de décision adaptés (calibration possible).

4.4 Validation croisée et tuning

from sklearn.model_selection import StratifiedKFold, RandomizedSearchCV
from scipy.stats import loguniform

param_grid = {
    "clf__C": loguniform(1e-3, 1e2),    # régularisation pour la logistique
}
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

search = RandomizedSearchCV(
    estimator=pipe,
    param_distributions=param_grid,
    n_iter=20,
    scoring="roc_auc",
    cv=cv,
    n_jobs=-1,
    random_state=42
)
search.fit(X_train, y_train)
print("Meilleurs params:", search.best_params_)
print("AUC (CV):", search.best_score_)

best_model = search.best_estimator_

4.5 Interprétation rapide (permutation)

from sklearn.inspection import permutation_importance

r = permutation_importance(best_model, X_test, y_test, scoring="roc_auc", n_repeats=10, random_state=0)
importances = pd.Series(r.importances_mean, index=X.columns).sort_values(ascending=False)
print(importances.head(10))

Astuce : pour des arbres/forêts, regardez aussi feature_importances_. Pour des explications locales/globale plus poussées : SHAP/Partial Dependence/ICE.


5) TensorFlow/Keras : réseaux de neurones en pratique

5.1 Exemple image (Fashion-MNIST)

import tensorflow as tf
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()

# Normalisation et ajout de canal
X_train = X_train.astype("float32") / 255.0
X_test  = X_test.astype("float32") / 255.0
X_train = X_train[..., None]
X_test  = X_test[..., None]
num_classes = 10

5.2 tf.data pour des entrées efficaces

batch_size = 128
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train)).shuffle(10_000).batch(batch_size).prefetch(2)
test_ds  = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch(batch_size).prefetch(2)

5.3 Définir un modèle Keras

from tensorflow.keras import layers, models

def make_cnn():
    inputs = layers.Input(shape=(28, 28, 1))
    x = layers.Conv2D(32, 3, activation="relu")(inputs)
    x = layers.MaxPool2D()(x)
    x = layers.Conv2D(64, 3, activation="relu")(x)
    x = layers.MaxPool2D()(x)
    x = layers.Flatten()(x)
    x = layers.Dropout(0.3)(x)
    x = layers.Dense(128, activation="relu")(x)
    outputs = layers.Dense(num_classes, activation="softmax")(x)
    model = models.Model(inputs, outputs)
    model.compile(
        optimizer="adam",
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy"]
    )
    return model

model = make_cnn()

5.4 Entraînement avec callbacks utiles

from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint, TensorBoard
import time, os

run_dir = f"runs/fashion_{int(time.time())}"
os.makedirs(run_dir, exist_ok=True)

callbacks = [
    EarlyStopping(patience=5, restore_best_weights=True, monitor="val_accuracy"),
    ReduceLROnPlateau(patience=3, factor=0.5, monitor="val_loss"),
    ModelCheckpoint(os.path.join(run_dir, "best.keras"), save_best_only=True, monitor="val_accuracy"),
    TensorBoard(log_dir=run_dir)
]

history = model.fit(
    train_ds,
    epochs=30,
    validation_data=test_ds,
    callbacks=callbacks
)

test_metrics = model.evaluate(test_ds, verbose=0)
print(dict(zip(model.metrics_names, test_metrics)))

Bonnes pratiques Keras

  • Normalisation directement dans le modèle (ex. layers.Rescaling(1/255.)), pour éviter les écarts entre train et prod.
  • EarlyStopping + ReduceLROnPlateau = sur-apprentissage maîtrisé.
  • TensorBoard pour suivre loss/accuracy, histogrammes de poids, graphes.
  • Sauvegarde : format Keras .keras ou SavedModel.

5.5 Sauvegarde & rechargement

model.save("fashion_best.keras")
restored = tf.keras.models.load_model("fashion_best.keras")

6) Pont scikit-learn ↔ TensorFlow

6.1 Un pipeline scikit-learn avec un modèle Keras (via SciKeras)

from scikeras.wrappers import KerasClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import cross_val_score

def build_mlp(hidden=64, lr=1e-3):
    m = tf.keras.Sequential([
        layers.Input(shape=(X_train.shape[1],)),
        layers.Normalization(),  # ou StandardScaler dans le pipeline
        layers.Dense(hidden, activation="relu"),
        layers.Dropout(0.2),
        layers.Dense(num_classes, activation="softmax")
    ])
    m.compile(optimizer=tf.keras.optimizers.Adam(lr), loss="sparse_categorical_crossentropy", metrics=["accuracy"])
    return m

clf = KerasClassifier(model=build_mlp, epochs=20, batch_size=128, verbose=0)
pipe = make_pipeline(StandardScaler(with_mean=False), clf)  # selon vos features
# Exemple: sur des données tabulaires (ici, illustration générique)
# scores = cross_val_score(pipe, X_tab_train, y_tab_train, cv=5, scoring="accuracy")

Pourquoi SciKeras ?
Il expose un estimateur Keras compatible avec l’API scikit-learn (grid search, CV, pipelines), très pratique pour organiser vos expériences.


7) Gérer les classes déséquilibrées & le choix du seuil

  • Classes rares : utilisez class_weight (Keras) ou class_weight='balanced' (scikit-learn), ou des techniques de ré-échantillonnage (SMOTE via imbalanced-learn).
  • Seuil de décision : ne restez pas figé à 0,5 en proba; ajustez le seuil selon coût métier (matrice de coûts) et optimisez F1/recall/precision/PR AUC.
# Exemple d’ajustement de seuil (classification binaire)
from sklearn.metrics import precision_recall_curve

proba = best_model.predict_proba(X_test)[:,1]
prec, rec, thr = precision_recall_curve(y_test, proba)
# choisir le seuil qui maximise F1 ~ 2*(P*R)/(P+R) ou selon votre coût

8) Interprétabilité & audit

  • Permutation importance (global), Partial Dependence/ICE (effets marginaux), confusion matrix (erreurs typiques).
  • Pour les réseaux profonds : Grad-CAM (images), attention (NLP), saliency maps.
  • Audit des biais : performances par segments (sexe, âge, région…), respect de la réglementation locale (RGPD, CNIL : minimisation, finalité, droits d’accès).

9) Du notebook à la production

  • Sauvegarde :
    • scikit-learn : joblib.dump(pipeline, "model.joblib")
    • TensorFlow : model.save("model.keras") / SavedModel
  • Paquetiser : conservez le même pipeline de prétraitement (mêmes steps, mêmes versions d’outils).
  • API : servez via FastAPI/Flask ; pour TensorFlow, TF Serving ou TFLite (mobile).
  • Surveillance : dérive de données (drift), qualité des entrées, suivi des métriques (ex. AUC/F1, latence), alertes.

10) Check-list express

  • Split train/val/test avant toute transformation.
  • Pipelines pour l’imputation/encodage/scaling (reproductibilité).
  • Validation croisée + recherche d’hyperparamètres.
  • Métriques métiers (pas seulement l’accuracy).
  • Callbacks Keras (early stopping, checkpoints).
  • Interprétation (permutation, PDP, matrices d’erreur).
  • Sauvegarde du pipeline + modèle, tests d’intégration, monitoring.

11) Deux mini-recettes prêtes à copier

(A) Tabulaire binaire en 15 lignes (scikit-learn)

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.ensemble import RandomForestClassifier

num_cols = X_train.select_dtypes(include=["float64", "int64"]).columns
cat_cols = X_train.select_dtypes(include=["object", "category", "bool"]).columns

pre = ColumnTransformer([
    ("num", Pipeline([("imp", SimpleImputer(strategy="median")), ("sc", StandardScaler())]), num_cols),
    ("cat", Pipeline([("imp", SimpleImputer(strategy="most_frequent")), ("oh", OneHotEncoder(handle_unknown="ignore"))]), cat_cols)
])

rf = RandomForestClassifier(n_estimators=300, random_state=42, class_weight="balanced_subsample")
clf = Pipeline([("pre", pre), ("rf", rf)]).fit(X_train, y_train)
print("AUC:", roc_auc_score(y_test, clf.predict_proba(X_test)[:,1]))

(B) CNN image compact (TensorFlow)

inputs = tf.keras.Input((28,28,1))
x = layers.Rescaling(1/255.0)(inputs)
x = layers.Conv2D(32,3,activation="relu")(x); x = layers.MaxPool2D()(x)
x = layers.Conv2D(64,3,activation="relu")(x); x = layers.MaxPool2D()(x)
x = layers.Flatten()(x); x = layers.Dropout(0.3)(x)
outputs = layers.Dense(10, activation="softmax")(x)
cnn = tf.keras.Model(inputs, outputs)
cnn.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
cnn.fit(train_ds, validation_data=test_ds, epochs=15, callbacks=[EarlyStopping(patience=3, restore_best_weights=True)])

Cas pratique — Détection de profils NEET & recommandation de la meilleure formation (contexte France)

Objectif : aider un·e conseiller·ère (Mission locale, CFA, organisme de formation, service RH d’une collectivité) à identifier les jeunes NEET (ni en emploi, ni en études, ni en formation) et recommander une formation adaptée, en combinant données tabulaires, règles métier et apprentissage automatique.
Le système reste un outil d’aide à la décision (humain dans la boucle), conforme au RGPD et avec des garde-fous d’équité.


1) Problème & résultats attendus

  • Tâche 1 — Détection : classifier un profil en éligible à un accompagnement formation (binaire) pour prioriser l’effort d’orientation.
  • Tâche 2 — Recommandation : proposer 3 à 5 formations pertinentes, en tenant compte des compétences, intérêts, contraintes (mobilité, horaires, durée), niveau requis et débouchés locaux.

Clés de succès : respect du consentement, minimisation des données, transparence des critères, équité (pas de discrimination directe/indirecte), explications simples pour le public et les conseillers.


2) Données (schéma minimal, côté France)

2.1 Table jeunes (profils)

  • id_jeune (uid), age (entier), departement (INSEE), diplome_max (CAP/BEP/Bac/Bac+2/…),
  • experience_mois (dernier emploi), mobilite_km (≤5/10/20/illimitée), permis (bool), situation_logement (cat.),
  • compétences (liste normalisée : ex. « Excel », « relation client », « HTML/CSS »),
  • intérêts (liste : numérique, aide à la personne, logistique…),
  • disponibilite_h/semaine, contraintes (garde enfant, horaires), situation (NEET oui/non au moment T).

Éviter : santé, religion, opinions, données ultrasensibles — non nécessaires à la finalité.

2.2 Table formations

  • id_form, intitule, rome_codes (métiers visés), competences_cible (liste),
  • niveau_entree (pré-requis), duree_semaines, lieu_departement, modalite (présentiel/distanciel/hybride),
  • sessions (dates), taux_sortie_positif_local (historique placement/stage/emploi), cout (si pertinent), aides.

2.3 Table suivi

  • id_jeune, id_form, choisie (bool), terminee (bool), sortie_positif (bool), dates.

3) Pipeline global (vue d’ensemble)

  1. Ingestion & nettoyage (CSV/SQL) → encodage des catégories, imputation, standardisation.
  2. Détection (modèle simple & robuste : régression logistique/forêt/gradient boosting) → score d’éligibilité.
  3. Recommandation hybride = filtres métiers (contraintes) + appariement compétences/intérêts + priorisation par débouchés locaux.
  4. Équité & transparence : audits de biais, explications (features clés), alternatives proposées.
  5. Interface conseiller : profil, raisons, top formations, pourquoi (explications), plan d’action.
  6. Suivi : feedback (form. choisie, sorties positives) pour améliorer le modèle.

4) Détection des profils (binaire)

4.1 Prétraitement & modèle (scikit-learn)

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler, MultiLabelBinarizer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, roc_auc_score

# X: colonnes non sensibles, y: "situation_NEET" (0/1) *au moment de l'entrée*
num_cols = ["age", "experience_mois", "disponibilite_h"]
cat_cols = ["departement", "diplome_max", "mobilite_km", "permis", "situation_logement"]
# compétences/intérêts sous forme de listes -> binarisation multilabel
def binarize_multilabel(df, col):
    mlb = MultiLabelBinarizer()
    M = pd.DataFrame(mlb.fit_transform(df[col]), columns=[f"{col}_{c}" for c in mlb.classes_], index=df.index)
    return pd.concat([df.drop(columns=[col]), M], axis=1)

df = pd.read_csv("jeunes.csv")  # supposé
df = binarize_multilabel(df, "competences")
df = binarize_multilabel(df, "interets")

y = df["situation_NEET"].astype(int)
X = df.drop(columns=["situation_NEET"])

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=.2, random_state=42)

pre = ColumnTransformer([
    ("num", Pipeline([("imp", SimpleImputer(strategy="median")), ("sc", StandardScaler())]), num_cols),
    ("cat", Pipeline([("imp", SimpleImputer(strategy="most_frequent")),
                      ("oh", OneHotEncoder(handle_unknown="ignore"))]), cat_cols)
], remainder="passthrough")

clf = Pipeline([
    ("pre", pre),
    ("lr", LogisticRegression(max_iter=200, class_weight="balanced"))
]).fit(X_train, y_train)

proba = clf.predict_proba(X_test)[:,1]
print(classification_report(y_test, (proba>0.5).astype(int)))
print("AUC:", round(roc_auc_score(y_test, proba), 3))

Pourquoi la régression logistique ? Interprétable, stable, moins sujette au sur-apprentissage sur échantillons modestes. Vous pouvez tester RandomForest / XGBoost ensuite.

4.2 Gouvernance des seuils

  • Prioriser le rappel (Recall) si l’on veut ne pas rater des jeunes à accompagner.
  • Ajuster le seuil pour équilibrer « capacité d’accueil » vs « faux positifs ».
  • Décision humaine au final (le score n’est jamais une décision automatique sans revue).

5) Recommandation de formation (hybride)

5.1 Étape 1 — Filtres “métier”

  • Éligibilité : pré-requis vs diplome_max, âge si nécessaire, niveau d’entrée.
  • Contraintes : mobilite_km + distance (même département/limitrophes), modalité (distanciel si garde d’enfant), durée max.
  • Disponibilité : aligner horaires/saisonnalité.

5.2 Étape 2 — Appariement compétences & intérêts (content-based)

Score compétences (Jaccard / TF-IDF / Word2Vec…) + Score intérêts (overlap simple).

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# Vecteurs "compétences" des formations et des jeunes
forms = pd.read_csv("formations.csv")
forms["comp_str"] = forms["competences_cible"].apply(lambda L: " ".join(L))  # liste -> phrase

tfidf = TfidfVectorizer(min_df=2)
F = tfidf.fit_transform(forms["comp_str"])  # (n_form, vocab)

def score_jeune(competences_jeune):
    q = tfidf.transform([" ".join(competences_jeune)])
    return cosine_similarity(q, F).ravel()  # score par formation

5.3 Étape 3 — Pondération “débouchés locaux”

Utiliser taux_sortie_positif_local (historique) comme facteur de priorisation (mais pas unique, pour éviter l’auto-renforcement).

import numpy as np

def rank_formations(jeune, forms):
    mask = filtres_metier(jeune, forms)  # bool per formation
    s_comp = score_jeune(jeune["competences"])
    s_int  = jaccard(jeune["interets"], forms["interets_cible"])  # à coder simplement
    s_job  = forms["taux_sortie_positif_local"].to_numpy()

    # Score final (poids à calibrer avec les conseillers)
    score = 0.5*s_comp + 0.3*s_int + 0.2*normalize(s_job)
    score[~mask] = -1  # exclure ce qui ne passe pas les filtres
    top = np.argsort(-score)[:5]
    return forms.iloc[top][["id_form","intitule","lieu_departement","duree_semaines","modalite","taux_sortie_positif_local"]], score[top]

Pratique : afficher pourquoi chaque formation est proposée (compétences matching + contraintes respectées + débouchés) et une alternative (ex. même domaine, autre modalité).


6) Équité, RGPD & transparence (indispensable)

  • Base légale & consentement : finalité = orientation/formation, minimisation des données, durée de conservation limitée, droits d’accès/rectification.
  • Équité : ne pas utiliser d’attributs protégés comme variables de décision ; auditer les performances par segment (genre, tranche d’âge, territoire) → mesurer Equal Opportunity Difference, Demographic Parity et gap de rappel.
  • Explicabilité : fournir les facteurs déterminants (ex. compétences manquantes/présentes, contraintes).
  • Recours : documenter un processus de contestation et proposer des parcours alternatifs.
  • Humain dans la boucle : un·e conseiller·ère valide/adapte toujours la recommandation.

7) Interface conseillère/conseiller (exemple d’écran)

  • Profil : infos clés, compétences, intérêts, contraintes.
  • Score d’éligibilité + seuil (avec message simple : “prioritaire / standard”).
  • Top 5 formations : carte par formation avec score, pourquoi (matching compétences X%, respect contrainte Y, débouchés Z), dates prochaines sessions, contact.
  • Plan d’action : RDV, tests de positionnement, aides mobilité/numérique.
  • Feedback : choix (oui/non), abandon, sortie positive (stage/emploi).

8) Exemple concret (Nadia, 22 ans, Loire-Atlantique)

  • Profil : 22 ans, Bac pro commerce, 6 mois d’expérience en vente, permis B, mobilité 20 km, compétences : “relation client”, “caisse”, “bureautique”, intérêts : “numérique”, “vente en ligne”, dispo 30 h/semaine, contrainte : horaires de jour.
  • Détection : score 0,78 (> seuil 0,65) → prioritaire.
  • Top formations :
    1. Assistant·e webmarketing (hybride, 12 sem., 15 km) — matching compétences 0,66, intérêts 0,9, débouchés locaux 62 %.
    2. Conseiller·ère e-commerce (présentiel, 10 sem., 18 km) — matching 0,59, débouchés 58 %.
    3. Agent·e logistique + CACES (présentiel, 8 sem., 7 km) — alternative si saturation des sessions.

Explications affichées :

    • Compétences actuelles proches des pré-requis marketing digital, lacunes identifiées : “SEO de base”, “Canva”, “Excel avancé”.
    • Modalités compatibles (journée / hybride).
    • Marché local dynamique (petites agences & TPE e-commerce).

9) Évaluation & suivi

  • Détection : AUC, rappel, précision, balanced accuracy.
  • Reco : Hit@k (la formation choisie est-elle dans le top-k ?), NDCG@k, couverture (diversité), taux d’acceptation par conseillers, taux de sortie positive à 3–6 mois.
  • Équité : comparer rappel/précision par segment ; si écart > seuil, revoir features/poids et ajouter des contraintes d’équité (ex. pénalisation dans la fonction objectif).
  • Drift : surveiller dérive des distributions (nouveaux publics, nouvelles formations) et ré-entraîner.

10) Mise en œuvre (technique)

  • Stockage : Postgres/BigQuery + fichiers de référence (catalogue formations).
  • Modèles : sklearn (pipeline sauvegardé joblib), recommandation Python (TF-IDF + règles).
  • API : FastAPI (endpoint /score & /recommendations).
  • Batch : recalcul hebdo des scores et mise à jour quotidienne des formations/sessions.
  • Sécurité : cloisonnement des rôles, journalisation des accès, chiffrage au repos/en transit.
  • MCO : tests unitaires (filtres, matching), tests d’intégration, monitoring.

11) Morceaux de code utiles (extraits)

11.1 Normaliser des listes (compétences/intérêts)

def normalize_list(x):
    if isinstance(x, str):
        x = [t.strip().lower() for t in x.split(",") if t.strip()]
    return sorted(set(x))

jeunes["competences"] = jeunes["competences"].apply(normalize_list)
jeunes["interets"]    = jeunes["interets"].apply(normalize_list)

11.2 Jaccard simple (intérêts)

def jaccard(a, b):
    A, B = set(a), set(b)
    return len(A&B)/len(A|B) if A|B else 0.0

11.3 Filtres métier

def filtres_metier(jeune, forms):
    ok_niveau = forms["niveau_entree"] <= jeune["diplome_max_niveau"]
    ok_mobi   = (forms["lieu_departement"]==jeune["departement"]) | (jeune["mobilite_km"]>=20) | (forms["modalite"]!="présentiel")
    ok_duree  = forms["duree_semaines"]*35 <= jeune["disponibilite_h"]*4  # heuristique
    return ok_niveau & ok_mobi & ok_duree

12) Risques & parades

  • Biais historiques (ex. moins d’inscriptions féminines dans une filière) → ne pas auto-renforcer : appliquer des caps/diversité dans le top-k et auditer régulièrement.
  • Données incomplètes → imputation prudente, validation humaine, proposer au moins une alternative.
  • Décision automatisée → proscrite : toujours explications + choix humain.
  • Confidentialité → limiter les accès, tracer les consultations, purger périodiquement.

Ce cas pratique met en place un double système :

recommandation (quelle formation convient le mieux ?),
le tout explicable, équitable et piloté par les conseillers.
En démarrant par un pipeline scikit-learn simple et une reco content-based avec filtres métier, vous obtenez rapidement un impact opérationnel tout en gardant la possibilité d’évoluer (embeddings, deep learning, intégration temps réel).

détection (qui orienter en priorité ?),

Commencez simple (baseline claire), verrouillez votre pipeline, choisissez des métriques alignées avec le métier, puis poussez la complexité seulement si elle apporte (et reste maintenable). Avec scikit-learn et TensorFlow, vous couvrez 95 % des cas réels — du score rapide sur CSV au déploiement d’un CNN en prod.

Recommandés

CSV en Python — du téléchargement au...
Le CSV paraît simple, jusqu’au...
En savoir plus
Python : pandas.to_csv — Exporter propre, fiable...
DataFrame.to_csv devient un contrat d’échange :...
En savoir plus
Python : pandas.read_csv — Guide pratique enrichi
Pourquoi read_csv reste incontournableParce qu’il...
En savoir plus
Python & finance PME — un kit...
Pour une PME, la finance est...
En savoir plus
Python pour la finance — les fonctions de base
Python pour la finance — les fonctions...
Python est devenu l’outil “couteau suisse”...
En savoir plus
Python & Pickle : manipuler les fichiers...
Pickle est la bibliothèque standard de...
En savoir plus

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

error: Content is protected !!