{ "cells": [ { "cell_type": "markdown", "id": "2936bcdd", "metadata": {}, "source": [ "## MLFLOW & Modélisation" ] }, { "cell_type": "markdown", "id": "d07f903e", "metadata": {}, "source": [ "### Import des modules" ] }, { "cell_type": "code", "execution_count": 1, "id": "675bc3c9", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import joblib\n", "import warnings\n", "warnings.filterwarnings(\"ignore\")\n", "import mlflow\n", "import mlflow.sklearn \n", "from sklearn.pipeline import Pipeline\n", "from sklearn.compose import ColumnTransformer\n", "from sklearn.preprocessing import StandardScaler, OneHotEncoder, TargetEncoder\n", "from sklearn.model_selection import train_test_split, StratifiedKFold, cross_val_score, GridSearchCV, RandomizedSearchCV\n", "from sklearn.dummy import DummyClassifier\n", "from sklearn.svm import SVC\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.ensemble import RandomForestClassifier\n", "from xgboost import XGBClassifier\n", "from sklearn.metrics import (accuracy_score, roc_auc_score, f1_score, precision_score, recall_score, roc_curve, precision_recall_curve, classification_report, confusion_matrix)\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "74fa8866", "metadata": {}, "outputs": [], "source": [ "app_test_clean = joblib.load(\"data/app_test_clean_v2.joblib\")" ] }, { "cell_type": "code", "execution_count": null, "id": "4bb1da50", "metadata": {}, "outputs": [], "source": [ "# Importation des données \n", "app_train_clean = joblib.load(\"data/app_train_clean_v2.joblib\")\n", "app_test_clean = joblib.load(\"data/app_test_clean_v2.joblib\")" ] }, { "cell_type": "code", "execution_count": null, "id": "64195ccb", "metadata": {}, "outputs": [], "source": [ "# Fonction permettant de vérifier la différence de colonnes entre 2 tables\n", "def check_columns(df_ref, df_test, name_ref=\"train\", name_test=\"test\"):\n", " cols_ref = set(df_ref.columns)\n", " cols_test = set(df_test.columns)\n", "\n", " missing = cols_ref - cols_test\n", " extra = cols_test - cols_ref\n", "\n", " print(f\"--- Vérification colonnes : {name_test} vs {name_ref} ---\")\n", " print(f\"Colonnes attendues : {len(cols_ref)}\")\n", " print(f\"Colonnes trouvées : {len(cols_test)}\")\n", "\n", " if missing:\n", " print(\"\\n❌ Colonnes manquantes dans\", name_test, \":\")\n", " for c in sorted(missing):\n", " print(\" -\", c)\n", " else:\n", " print(\"\\n✔️ Aucune colonne manquante\")\n", "\n", " if extra:\n", " print(\"\\n⚠️ Colonnes supplémentaires dans\", name_test, \":\")\n", " for c in sorted(extra):\n", " print(\" -\", c)\n", " else:\n", " print(\"\\n✔️ Aucune colonne supplémentaire\")\n", "\n", " print(\"\\n--------------------------------------------\\n\")\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "b07074ac", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- Vérification colonnes : test vs train ---\n", "Colonnes attendues : 328\n", "Colonnes trouvées : 327\n", "\n", "❌ Colonnes manquantes dans test :\n", " - TARGET\n", "\n", "✔️ Aucune colonne supplémentaire\n", "\n", "--------------------------------------------\n", "\n" ] } ], "source": [ "# Check des colonnes entre train et test\n", "check_columns(app_train_clean, app_test_clean, name_ref=\"train\", name_test=\"test\")" ] }, { "cell_type": "markdown", "id": "4a9db321", "metadata": {}, "source": [ "Mon objectif principal est de pouvoir tracer l'impact du preprocessing, des modèles et des hyperparamètres sur les métriques et le scoring.\n", "\n", "De ce fait il faudrait une structure du MLFlow permettant de:\n", "- comparer facilement les préprocessings entre eux\n", "- comparer facilement les modèles entre eux\n", "- comparer facilement les hyperparamètres entre eux\n", "- garder une hiérarchie lisible dans MLflow UI\n", "- ne pas exploser le nombre de runs" ] }, { "cell_type": "markdown", "id": "0ed123dc", "metadata": {}, "source": [ "### Fonctions du preprocessing\n", "\n", "3 fonctions de preprocessing permettant de gérer les variables manquantes:\n", "- Garder les NaN tel quel en les flaguant (je ne sais pas si en flaguant les numériques par '-1' çà n'a pas un impact sur les données?)\n", "- Imputation classique(**médiane** pour les numériques, **mode** pour les catégorielles)\n", "- Suppression des variables dont le ratio NaN est >= 70%\n", "\n", "1 fonction pour tester l'impact de la gestion des outliers sur les scores et résultats en plus des nettoyages précédents" ] }, { "cell_type": "code", "execution_count": 6, "id": "ba8ba74d", "metadata": {}, "outputs": [], "source": [ "# Flag \"Missing\"\n", "def preprocess_missing_flag(df):\n", " df = df.copy()\n", " df_num = df.select_dtypes(include=[\"int64\", \"float64\"])\n", " df_cat = df.select_dtypes(include=[\"object\", \"category\", \"bool\"])\n", "\n", " df_num = df_num.fillna(-1)\n", " df_cat = df_cat.fillna(\"MISSING\")\n", "\n", " return pd.concat([df_num, df_cat], axis=1)\n", "\n", "\n", "# Imputation classique\n", "from sklearn.impute import SimpleImputer\n", "\n", "def preprocess_imputation(df):\n", " df = df.copy()\n", " df_num = df.select_dtypes(include=[\"int64\", \"float64\"])\n", " df_cat = df.select_dtypes(include=[\"object\", \"category\", \"bool\"])\n", "\n", " df_num = pd.DataFrame(SimpleImputer(strategy=\"median\").fit_transform(df_num),\n", " columns=df_num.columns)\n", " df_cat = pd.DataFrame(SimpleImputer(strategy=\"most_frequent\").fit_transform(df_cat),\n", " columns=df_cat.columns)\n", "\n", " return pd.concat([df_num, df_cat], axis=1)\n", "\n", "\n", "# Suppression colonnes >= 70% NaN\n", "def preprocess_drop70(df, threshold=0.7):\n", " df = df.copy()\n", " missing_ratio = df.isna().mean()\n", " cols_to_drop = missing_ratio[missing_ratio >= threshold].index.tolist()\n", "\n", " print(\"Colonnes supprimées (>=70% NaN) :\", cols_to_drop)\n", "\n", " df = df.drop(columns=cols_to_drop)\n", "\n", " # puis imputation classique\n", " return preprocess_imputation(df)\n", "\n", "\n", "# Gestion des outliers\n", "def clip_outliers(df, lower_q=0.01, upper_q=0.99):\n", " df_out = df.copy()\n", " num_cols = df_out.select_dtypes(include=['int64', 'float64']).columns\n", " \n", " for col in num_cols:\n", " lower = df_out[col].quantile(lower_q)\n", " upper = df_out[col].quantile(upper_q)\n", " df_out[col] = df_out[col].clip(lower, upper)\n", " \n", " return df_out\n", "\n", "\n", "def preprocess_outliers_missing_flag(X):\n", " X2 = clip_outliers(X)\n", " return preprocess_missing_flag(X2)\n", "\n", "def preprocess_outliers_imputation(X):\n", " X2 = clip_outliers(X)\n", " return preprocess_imputation(X2)\n", "\n", "def preprocess_outliers_drop70(X):\n", " X2 = clip_outliers(X)\n", " return preprocess_drop70(X2)\n" ] }, { "cell_type": "markdown", "id": "a26b47a6", "metadata": {}, "source": [ "### Transformation des colonnes selon leur type: ColumnTransformer\n", "\n", "Après la séparation des données en X & y:\n", "- je crèe des listes de colonnes selon leur type (**numériques, catégorielle, booléennes**)\n", "- ensuite j'applique la stratégie de transformation selon le type de la variable\n", " - les variables catégorielles ont 2 stratégies distinctes dû au nombre élevé de catégories pour certaines variables(\n", " **OneHotEncoder** si un *maximum de 10 catégories*\n", " **TargetEncoder** si *plus de 10 catégories*)" ] }, { "cell_type": "code", "execution_count": 7, "id": "75bd1792", "metadata": {}, "outputs": [], "source": [ "# Séparation du jeu de données\n", "X = app_train_clean.drop(columns=[\"TARGET\"])\n", "y = app_train_clean[\"TARGET\"].astype(int)" ] }, { "cell_type": "code", "execution_count": null, "id": "d7856726", "metadata": {}, "outputs": [], "source": [ "# Fonction qui construit le process de transformation des colonnes\n", "def tranformation_process(X_prep):\n", " num_cols = X_prep.select_dtypes(include=[\"int64\", \"float64\"]).columns.tolist()\n", " cat_cols = X_prep.select_dtypes(include=[\"object\", \"category\"]).columns.tolist()\n", " bool_cols = X_prep.select_dtypes(include=[\"bool\"]).columns.tolist()\n", "\n", " nb_faible_cols = [c for c in cat_cols if X_prep[c].nunique() <= 10]\n", " nb_eleve_cols = [c for c in cat_cols if X_prep[c].nunique() > 10]\n", "\n", " preprocessor = ColumnTransformer(\n", " transformers=[\n", " (\"num\", StandardScaler(), num_cols),\n", " (\"card_faible\", OneHotEncoder(handle_unknown=\"ignore\"), nb_faible_cols),\n", " (\"card_eleve\", TargetEncoder(), nb_eleve_cols),\n", " (\"bool\", \"passthrough\", bool_cols)\n", " ]\n", " )\n", " return preprocessor\n" ] }, { "cell_type": "markdown", "id": "29569db1", "metadata": {}, "source": [ "### Score métier et optimisation\n", "\n", "L'objectif métier de la modélisation est de créer un **scoring métier - score qui permet de minimiser le coût d'erreur de prédiction des FN & FP**\n", "- FN = faux négatif = mauvais client prédit bon <> coût très élevé (perte financière)\n", "- FP = faux positif = bon client prédit mauvais <> coût plus faible (manque à gagner)\n", "\n", "Pour se faire, il faudra trouver le *seuil optimal* permettant de minimiser ce coût, car le seuil par défaut étant de 0.5 ne permet pas de capter toutes les erreurs. \n", "Ainsi, j'ai créé une fonction qui:\n", "- teste plusieurs seuils; et pour chaque seuil:\n", " - elle convertit les probabilités en classes\n", " - calcule FN, FP\n", " - calcule le coût métier\n", " - garde le seuil qui minimise ledit coût" ] }, { "cell_type": "code", "execution_count": 9, "id": "2bca6b48", "metadata": {}, "outputs": [], "source": [ "# Coût des classes\n", "cout_FN = 10.0\n", "cout_FP = 1.0\n", "\n", "# Fonction du calcul du coût métier\n", "def cout_metier(y_true, y_pred):\n", " cm = confusion_matrix(y_true, y_pred)\n", " TN, FP, FN, TP = cm.ravel() # transformer la matrice en un tableau 1D\n", " cout_total = FN * cout_FN + FP * cout_FP\n", " return cout_total, cm\n", "\n", "# Fonction d'optimisation du seuil\n", "def best_seuil(y_true, y_proba):\n", " seuils = np.linspace(0.01, 0.99, 99) # 99 seuils allant de 0.01 à 0.99 avec un espace de 0.01 (0.01, 0.02, 0.03, ..., 0.99)\n", " best_s = 0.5\n", " best_cost = np.inf\n", " best_cm = None\n", "\n", " for s in seuils:\n", " y_pred = (y_proba >= s).astype(int)\n", " cost, cm = cout_metier(y_true, y_pred)\n", " if cost < best_cost:\n", " best_cost = cost\n", " best_s = s\n", " best_cm = cm\n", "\n", " return best_s, best_cost, best_cm\n" ] }, { "cell_type": "markdown", "id": "43415548", "metadata": {}, "source": [ "### Déclaration des modèles à comparer - Optimisation des hyperparamètres" ] }, { "cell_type": "code", "execution_count": 10, "id": "39166bc8", "metadata": {}, "outputs": [], "source": [ "# Grilles d'hyperparamètres pour optimisation\n", "\n", "# LR\n", "param_LR = {\n", " \"model__C\": [0.01, 0.1, 1, 10], \n", " \"model__max_iter\": [200, 500]}\n", "\n", "# Random Forest\n", "param_RF = {\n", " # \"model__n_estimators\": [200, 400, 600],\n", " # \"model__max_depth\": [5, 10, 15, None],\n", " # \"model__min_samples_split\": [2, 5, 10],\n", " # \"model__min_samples_leaf\": [1, 2, 4]\n", " \"model__max_depth\": [3, 5],\n", " \"model__n_estimators\": [100, 150, 200],\n", " \"model__min_samples_leaf\": [1, 2, 4],\n", " \"model__max_features\": [\"sqrt\", \"log2\"]}\n", "\n", "# XGBoost\n", "param_XGB = {\n", " # \"model__n_estimators\": [400, 600, 700],\n", " # \"model__learning_rate\": [0.1, 0.2, 0.3],\n", " # \"model__max_depth\": [3, 5, 7],\n", " # \"model__subsample\": [0.8, 1.0],\n", " # \"model__colsample_bytree\": [0.8, 1.0],\n", " # \"model__min_child_weight\": [1, 3, 5],\n", " # \"model__gamma\": [0, 1, 5],\n", " # \"model__reg_lambda\": [1, 5, 10]\n", " \"model__learning_rate\": [0.05, 0.1], \n", " \"model__max_depth\": [3, 5], \n", " \"model__subsample\": [0.8, 1.0], \n", " \"model__colsample_bytree\": [0.8, 1.0]}" ] }, { "cell_type": "code", "execution_count": 11, "id": "cf336c4c", "metadata": {}, "outputs": [], "source": [ "# Rapport entre négatifs et positifs - pour calculer le ratio des classes négatives et positives afin de l'utiliser dans l'hyperparamètre\n", "scale_pos_weight = y.value_counts()[0] / y.value_counts()[1]\n", "\n", "# Modèles à comparer + hyperparamètres\n", "modeles = {\n", " \"Dummy\": (DummyClassifier(strategy = \"stratified\"), {}),\n", " \"LogisticRegression\": (LogisticRegression(max_iter = 2000, class_weight = \"balanced\", C = 0.1), param_LR),\n", "\n", " \"RandomForest\": (RandomForestClassifier(n_estimators=200, class_weight=\"balanced\", random_state = 42,max_depth = 3, min_samples_split = 2, min_samples_leaf = 2),\n", " param_RF),\n", "\n", " \"XGBoost\": (XGBClassifier(eval_metric=\"logloss\", n_estimators = 100, learning_rate = 0.01, max_depth = 3, subsample = 0.4, colsample_bytree = 0.4, min_child_weight = 3, gamma = 2, \n", " reg_lambda = 3, scale_pos_weight = scale_pos_weight, random_state = 42),\n", " param_XGB)}\n" ] }, { "cell_type": "code", "execution_count": null, "id": "a8a96bcc", "metadata": {}, "outputs": [], "source": [ "\n", "def optimisation_hyperparametres(model_name, model, param_grid, preprocessor, X_train, y_train):\n", "\n", " # 1. Réduire n_estimators uniquement pour l’optimisation\n", " if hasattr(model, \"n_estimators\"):\n", " # Valeurs recommandées pour accélérer\n", " if model_name.lower().startswith(\"randomforest\"):\n", " model.set_params(n_estimators=150)\n", " elif model_name.lower().startswith(\"xgb\"):\n", " model.set_params(n_estimators=200)\n", "\n", " # 2. Pipeline\n", " pipe = Pipeline([\n", " (\"preprocess\", preprocessor),\n", " (\"model\", model)\n", " ])\n", "\n", " # 3. RandomizedSearchCV plus léger\n", " search = RandomizedSearchCV(\n", " estimator=pipe,\n", " param_distributions=param_grid,\n", " n_iter=5, \n", " scoring=\"roc_auc\",\n", " cv=3, \n", " n_jobs=-1,\n", " random_state=42,\n", " verbose=1\n", " )\n", "\n", " search.fit(X_train, y_train)\n", "\n", " return search.best_estimator_, search.best_params_, search.best_score_\n", "\n", "\n" ] }, { "cell_type": "markdown", "id": "3a68a441", "metadata": {}, "source": [ "#### Fonction d'évaluation des modèles - Pipeline MLOps\n", "\n", "Fonction qui pour chaque modèle:\n", "- le combine avec le préprocesseur intégré (pipeline preprocessing), \n", "- l’entraîne, \n", "- calcule toutes les métriques utiles, \n", "- optimise le seuil métier, \n", "- génère les artefacts (ROC + matrice de confusion),\n", "- enregistre tout dans MLflow.\n", "\n", "Ceci est effectué en mettant en place un tracking permettant d'enregistrer, pour chaque modèle, les résultats obtenus dans le but de les comparer selon le besoin:\n", "- démarrer un **run MLFlow** en créant un sous-run par modèle *(with mlflow.start_run(run_name=model_name, nested=True))* afin d'enregistrer tout ce qui lui est demandé\n", " - enregistrer les hyperparamètres\n", " - entrainer le pipeline <> application du preprocessing dans le pipeline\n", " - calculer les prédictions (0, 1) & probabilités (entre 0 & 1)\n", " - calculer les métriques nécessaires, puis les enregister dans le MLFlow <> j'ai choisi de mesurer la qualité globale, la capacité à détecter les mauvais clients (*Recall*), l'équilibre précision/rappel (*F1*), et \n", " surtout la performance globale (*AUC - la contrainte est de s'assurer qu'il soit inférieur à 0.82, indicateur de surapprentissage*)\n", " - effectuer une validation croisée indépendamment du split train/test\n", " - calculer, pour 99 seuils distinct, le coût métier, puis choisir le seuil qui minimise le coût. Le modèle qui permettra d'obtenir le coût total le moins élevé sera celui choisi\n", " - puis tracer la matrice de confusion et la courbe ROC.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "644f673f", "metadata": {}, "outputs": [], "source": [ "# Fonction permettant de calculer les métriques et artefacts(matrice de confusion, ROC), coût métier, seuil optimal\n", "def evaluation_modele(model_name, model, X_train, X_test, y_train, y_test, preprocessor):\n", " \n", " pipe = Pipeline([\n", " (\"preprocess\", preprocessor),\n", " (\"model\", model)])\n", "\n", " # Log hyperparamètres\n", " for param_name, param_value in model.get_params().items():\n", " mlflow.log_param(param_name, param_value)\n", "\n", " # Fit\n", " pipe.fit(X_train, y_train)\n", "\n", " # Prédictions\n", " y_pred_train = pipe.predict(X_train)\n", " y_pred_test = pipe.predict(X_test)\n", "\n", " y_proba_train = pipe.predict_proba(X_train)[:, 1]\n", " y_proba_test = pipe.predict_proba(X_test)[:, 1]\n", "\n", " # compteur de step pour éviter les collisions MLflow \n", " step = 0\n", "\n", " # Métriques train/test\n", " metrics = {\n", " \"accuracy_train\": accuracy_score(y_train, y_pred_train),\n", " \"accuracy_test\": accuracy_score(y_test, y_pred_test),\n", " \"precision_train\": precision_score(y_train, y_pred_train),\n", " \"precision_test\": precision_score(y_test, y_pred_test),\n", " \"recall_train\": recall_score(y_train, y_pred_train),\n", " \"recall_test\": recall_score(y_test, y_pred_test),\n", " \"f1_train\": f1_score(y_train, y_pred_train),\n", " \"f1_test\": f1_score(y_test, y_pred_test),\n", " \"auc_train\": roc_auc_score(y_train, y_proba_train),\n", " \"auc_test\": roc_auc_score(y_test, y_proba_test)}\n", "\n", " for m, v in metrics.items():\n", " mlflow.log_metric(m, v, step=step)\n", "\n", " # Validation croisée\n", " cv = StratifiedKFold(n_splits = 5, shuffle = True, random_state = 42)\n", " auc_cv = cross_val_score(pipe, X_train, y_train, cv = cv, scoring = \"roc_auc\", n_jobs = -1 ).mean() \n", " mlflow.log_metric(\"auc_cv\", auc_cv, step=step)\n", " step += 1\n", " \n", "\n", " # Score métier\n", " best_s, best_cost, best_cm = best_seuil(y_test, y_proba_test)\n", " mlflow.log_metric(\"business_cost\", best_cost, step=step); step += 1\n", " mlflow.log_metric(\"best_threshold\", best_s, step=step); step += 1\n", "\n", " # Prédictions au seuil optimal\n", " y_pred_opt = (y_proba_test >= best_s).astype(int)\n", "\n", " # Recall des mauvais payeurs au seuil optimal\n", " recall_bad_payers = recall_score(y_test, y_pred_opt, pos_label=1)\n", " mlflow.log_metric(\"recall_bad_payers\", recall_bad_payers, step=step)\n", " step += 1\n", "\n", "\n", " # Matrice de confusion\n", " fig_cm, ax = plt.subplots(figsize=(4,4))\n", " sns.heatmap(best_cm, annot=True, fmt=\"d\", cmap=\"Blues\", ax=ax)\n", " plt.tight_layout()\n", " cm_path = f\"artefacts/cm_{model_name}.png\"\n", " fig_cm.savefig(cm_path)\n", " mlflow.log_artifact(cm_path)\n", " plt.close(fig_cm)\n", "\n", "\n", " # Courbe ROC\n", " fpr, tpr, _ = roc_curve(y_test, y_proba_test)\n", " fig_roc, ax = plt.subplots(figsize=(5,4))\n", " ax.plot(fpr, tpr, label=f\"AUC={metrics['auc_test']:.3f}\")\n", " ax.plot([0,1],[0,1],\"k--\")\n", " plt.tight_layout()\n", " roc_path = f\"artefacts/roc_{model_name}.png\"\n", " fig_roc.savefig(roc_path)\n", " mlflow.log_artifact(roc_path)\n", " plt.close(fig_roc)\n", "\n", " # Log du modèle\n", " mlflow.sklearn.log_model(pipe, model_name)\n", "\n", " return metrics, auc_cv, best_s, best_cost\n" ] }, { "cell_type": "markdown", "id": "42294c06", "metadata": {}, "source": [ "#### Exécution du MLFlow" ] }, { "cell_type": "code", "execution_count": null, "id": "cddc1074", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026/03/07 23:38:53 INFO mlflow.tracking.fluent: Experiment with name 'missing_flag_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/07 23:45:08 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/07 23:49:56 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/07 23:57:52 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 00:01:53 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 00:02:04 INFO mlflow.tracking.fluent: Experiment with name 'missing_flag_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 00:08:14 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 00:08:22 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'missing_flag_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'missing_flag_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 00:21:35 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 00:21:45 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'missing_flag_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'missing_flag_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 00:45:41 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 00:45:50 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'missing_flag_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'missing_flag_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:02:43 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 01:02:53 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'missing_flag_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'missing_flag_XGBoost_optimized_v5_2-07-03'.\n", "2026/03/08 01:03:02 INFO mlflow.tracking.fluent: Experiment with name 'imputation_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:09:50 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:13:27 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:19:58 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:26:31 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 01:26:40 INFO mlflow.tracking.fluent: Experiment with name 'imputation_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:33:55 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 01:34:04 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'imputation_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'imputation_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 01:45:04 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 01:45:14 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'imputation_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'imputation_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:09:18 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 02:09:28 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'imputation_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'imputation_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:25:54 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 02:26:03 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'imputation_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'imputation_XGBoost_optimized_v5_2-07-03'.\n", "2026/03/08 02:26:13 INFO mlflow.tracking.fluent: Experiment with name 'drop70_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Colonnes supprimées (>=70% NaN) : ['CC_SK_DPD_DEF_max', 'CC_CNT_DRAWINGS_OTHER_CURRENT_mean', 'CC_CNT_DRAWINGS_ATM_CURRENT_sum', 'CC_AMT_DRAWINGS_CURRENT_min', 'CC_CNT_DRAWINGS_ATM_CURRENT_mean', 'PREV_RATE_INTEREST_PRIVILEGED_max', 'CC_AMT_DRAWINGS_CURRENT_mean', 'CC_NAME_CONTRACT_STATUS_Signed', 'CC_AMT_DRAWINGS_ATM_CURRENT_sum', 'BUREAU_AMT_ANNUITY_min', 'CC_UTILIZATION_mean', 'CC_AMT_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_Refused', 'CC_MONTHS_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_NUNIQUE', 'CC_UTILIZATION_max', 'CC_NAME_CONTRACT_STATUS_Sent proposal', 'CC_AMT_PAYMENT_TOTAL_CURRENT_max', 'CC_AMT_PAYMENT_CURRENT_min', 'CC_NAME_CONTRACT_STATUS_Approved', 'CC_CNT_DRAWINGS_ATM_CURRENT_min', 'CC_SK_DPD_max', 'CC_PAYMENT_RATIO_min', 'CC_CNT_DRAWINGS_OTHER_CURRENT_min', 'CC_AMT_INST_MIN_REGULARITY_min', 'BUREAU_AMT_ANNUITY_mean', 'CC_AMT_DRAWINGS_CURRENT_max', 'BUREAU_MONTHS_BALANCE_max', 'CC_MONTHS_BALANCE_max', 'CC_CNT_DRAWINGS_CURRENT_min', 'CC_AMT_DRAWINGS_ATM_CURRENT_mean', 'CC_AMT_CREDIT_LIMIT_ACTUAL_max', 'CC_AMT_CREDIT_LIMIT_ACTUAL_sum', 'CC_CNT_DRAWINGS_CURRENT_max', 'CC_AMT_DRAWINGS_POS_CURRENT_min', 'PREV_RATE_INTEREST_PRIMARY_max', 'CC_NAME_CONTRACT_STATUS_Completed', 'CC_UTILIZATION_min', 'CC_PAYMENT_RATIO_max']\n", "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:32:19 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:35:47 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:41:59 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:47:54 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 02:48:03 INFO mlflow.tracking.fluent: Experiment with name 'drop70_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Colonnes supprimées (>=70% NaN) : ['CC_SK_DPD_DEF_max', 'CC_CNT_DRAWINGS_OTHER_CURRENT_mean', 'CC_CNT_DRAWINGS_ATM_CURRENT_sum', 'CC_AMT_DRAWINGS_CURRENT_min', 'CC_CNT_DRAWINGS_ATM_CURRENT_mean', 'PREV_RATE_INTEREST_PRIVILEGED_max', 'CC_AMT_DRAWINGS_CURRENT_mean', 'CC_NAME_CONTRACT_STATUS_Signed', 'CC_AMT_DRAWINGS_ATM_CURRENT_sum', 'BUREAU_AMT_ANNUITY_min', 'CC_UTILIZATION_mean', 'CC_AMT_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_Refused', 'CC_MONTHS_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_NUNIQUE', 'CC_UTILIZATION_max', 'CC_NAME_CONTRACT_STATUS_Sent proposal', 'CC_AMT_PAYMENT_TOTAL_CURRENT_max', 'CC_AMT_PAYMENT_CURRENT_min', 'CC_NAME_CONTRACT_STATUS_Approved', 'CC_CNT_DRAWINGS_ATM_CURRENT_min', 'CC_SK_DPD_max', 'CC_PAYMENT_RATIO_min', 'CC_CNT_DRAWINGS_OTHER_CURRENT_min', 'CC_AMT_INST_MIN_REGULARITY_min', 'BUREAU_AMT_ANNUITY_mean', 'CC_AMT_DRAWINGS_CURRENT_max', 'BUREAU_MONTHS_BALANCE_max', 'CC_MONTHS_BALANCE_max', 'CC_CNT_DRAWINGS_CURRENT_min', 'CC_AMT_DRAWINGS_ATM_CURRENT_mean', 'CC_AMT_CREDIT_LIMIT_ACTUAL_max', 'CC_AMT_CREDIT_LIMIT_ACTUAL_sum', 'CC_CNT_DRAWINGS_CURRENT_max', 'CC_AMT_DRAWINGS_POS_CURRENT_min', 'PREV_RATE_INTEREST_PRIMARY_max', 'CC_NAME_CONTRACT_STATUS_Completed', 'CC_UTILIZATION_min', 'CC_PAYMENT_RATIO_max']\n", "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 02:54:32 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 02:54:41 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'drop70_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'drop70_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 03:04:55 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 03:05:04 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'drop70_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'drop70_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 03:29:02 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 03:29:14 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'drop70_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'drop70_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 03:44:32 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 03:44:43 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'drop70_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'drop70_XGBoost_optimized_v5_2-07-03'.\n", "2026/03/08 03:44:55 INFO mlflow.tracking.fluent: Experiment with name 'outliers_missing_flag_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 03:51:06 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 03:56:07 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 04:02:15 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 04:08:17 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 04:08:26 INFO mlflow.tracking.fluent: Experiment with name 'outliers_missing_flag_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 04:14:41 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 04:14:50 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_missing_flag_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_missing_flag_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 04:28:15 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 04:28:24 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_missing_flag_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_missing_flag_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 04:52:02 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 04:52:12 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_missing_flag_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_missing_flag_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:08:39 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 05:08:48 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_missing_flag_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_missing_flag_XGBoost_optimized_v5_2-07-03'.\n", "2026/03/08 05:08:58 INFO mlflow.tracking.fluent: Experiment with name 'outliers_imputation_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:15:59 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:19:41 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:25:57 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:32:21 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 05:32:30 INFO mlflow.tracking.fluent: Experiment with name 'outliers_imputation_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:39:47 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 05:39:55 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_imputation_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_imputation_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 05:50:54 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 05:51:04 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_imputation_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_imputation_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:14:40 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 06:14:51 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_imputation_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_imputation_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:30:49 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 06:30:58 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_imputation_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_imputation_XGBoost_optimized_v5_2-07-03'.\n", "2026/03/08 06:31:08 INFO mlflow.tracking.fluent: Experiment with name 'outliers_drop70_base_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Colonnes supprimées (>=70% NaN) : ['CC_SK_DPD_DEF_max', 'CC_CNT_DRAWINGS_OTHER_CURRENT_mean', 'CC_CNT_DRAWINGS_ATM_CURRENT_sum', 'CC_AMT_DRAWINGS_CURRENT_min', 'CC_CNT_DRAWINGS_ATM_CURRENT_mean', 'PREV_RATE_INTEREST_PRIVILEGED_max', 'CC_AMT_DRAWINGS_CURRENT_mean', 'CC_NAME_CONTRACT_STATUS_Signed', 'CC_AMT_DRAWINGS_ATM_CURRENT_sum', 'BUREAU_AMT_ANNUITY_min', 'CC_UTILIZATION_mean', 'CC_AMT_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_Refused', 'CC_MONTHS_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_NUNIQUE', 'CC_UTILIZATION_max', 'CC_NAME_CONTRACT_STATUS_Sent proposal', 'CC_AMT_PAYMENT_TOTAL_CURRENT_max', 'CC_AMT_PAYMENT_CURRENT_min', 'CC_NAME_CONTRACT_STATUS_Approved', 'CC_CNT_DRAWINGS_ATM_CURRENT_min', 'CC_SK_DPD_max', 'CC_PAYMENT_RATIO_min', 'CC_CNT_DRAWINGS_OTHER_CURRENT_min', 'CC_AMT_INST_MIN_REGULARITY_min', 'BUREAU_AMT_ANNUITY_mean', 'CC_AMT_DRAWINGS_CURRENT_max', 'BUREAU_MONTHS_BALANCE_max', 'CC_MONTHS_BALANCE_max', 'CC_CNT_DRAWINGS_CURRENT_min', 'CC_AMT_DRAWINGS_ATM_CURRENT_mean', 'CC_AMT_CREDIT_LIMIT_ACTUAL_max', 'CC_AMT_CREDIT_LIMIT_ACTUAL_sum', 'CC_CNT_DRAWINGS_CURRENT_max', 'CC_AMT_DRAWINGS_POS_CURRENT_min', 'PREV_RATE_INTEREST_PRIMARY_max', 'CC_NAME_CONTRACT_STATUS_Completed', 'CC_UTILIZATION_min', 'CC_PAYMENT_RATIO_max']\n", "Modèle sans optimisation: Dummy\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:37:18 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: LogisticRegression\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:40:39 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: RandomForest\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:46:42 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Modèle sans optimisation: XGBoost\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:52:30 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 06:52:39 INFO mlflow.tracking.fluent: Experiment with name 'outliers_drop70_optimisé_v5_2-07-03' does not exist. Creating a new experiment.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Colonnes supprimées (>=70% NaN) : ['CC_SK_DPD_DEF_max', 'CC_CNT_DRAWINGS_OTHER_CURRENT_mean', 'CC_CNT_DRAWINGS_ATM_CURRENT_sum', 'CC_AMT_DRAWINGS_CURRENT_min', 'CC_CNT_DRAWINGS_ATM_CURRENT_mean', 'PREV_RATE_INTEREST_PRIVILEGED_max', 'CC_AMT_DRAWINGS_CURRENT_mean', 'CC_NAME_CONTRACT_STATUS_Signed', 'CC_AMT_DRAWINGS_ATM_CURRENT_sum', 'BUREAU_AMT_ANNUITY_min', 'CC_UTILIZATION_mean', 'CC_AMT_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_Refused', 'CC_MONTHS_BALANCE_mean', 'CC_NAME_CONTRACT_STATUS_NUNIQUE', 'CC_UTILIZATION_max', 'CC_NAME_CONTRACT_STATUS_Sent proposal', 'CC_AMT_PAYMENT_TOTAL_CURRENT_max', 'CC_AMT_PAYMENT_CURRENT_min', 'CC_NAME_CONTRACT_STATUS_Approved', 'CC_CNT_DRAWINGS_ATM_CURRENT_min', 'CC_SK_DPD_max', 'CC_PAYMENT_RATIO_min', 'CC_CNT_DRAWINGS_OTHER_CURRENT_min', 'CC_AMT_INST_MIN_REGULARITY_min', 'BUREAU_AMT_ANNUITY_mean', 'CC_AMT_DRAWINGS_CURRENT_max', 'BUREAU_MONTHS_BALANCE_max', 'CC_MONTHS_BALANCE_max', 'CC_CNT_DRAWINGS_CURRENT_min', 'CC_AMT_DRAWINGS_ATM_CURRENT_mean', 'CC_AMT_CREDIT_LIMIT_ACTUAL_max', 'CC_AMT_CREDIT_LIMIT_ACTUAL_sum', 'CC_CNT_DRAWINGS_CURRENT_max', 'CC_AMT_DRAWINGS_POS_CURRENT_min', 'PREV_RATE_INTEREST_PRIMARY_max', 'CC_NAME_CONTRACT_STATUS_Completed', 'CC_UTILIZATION_min', 'CC_PAYMENT_RATIO_max']\n", "Optimisation du modèle : Dummy\n", "Fitting 3 folds for each of 1 candidates, totalling 3 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 06:59:11 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 06:59:19 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_drop70_Dummy_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_drop70_Dummy_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : LogisticRegression\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 07:09:42 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 07:09:51 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_drop70_LogisticRegression_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_drop70_LogisticRegression_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : RandomForest\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 07:32:29 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 07:32:38 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_drop70_RandomForest_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_drop70_RandomForest_optimized_v5_2-07-03'.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimisation du modèle : XGBoost\n", "Fitting 3 folds for each of 5 candidates, totalling 15 fits\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026/03/08 07:46:39 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "2026/03/08 07:46:47 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n", "Successfully registered model 'outliers_drop70_XGBoost_optimized_v5_2-07-03'.\n", "Created version '1' of model 'outliers_drop70_XGBoost_optimized_v5_2-07-03'.\n" ] } ], "source": [ "# Forcer MLflow à utiliser le dossier mlruns pour sauvegarder les runs sans passer par mlflow db\n", "mlflow.set_tracking_uri(\"file:///C:/Users/Lenovo/Documents/WCS/GitHub/Classification-Risque-Credit-Pipeline-MLOps-/mlruns\")\n", "\n", "\n", "preprocessings = {\n", " \"missing_flag\": preprocess_missing_flag,\n", " \"imputation\": preprocess_imputation,\n", " \"drop70\": preprocess_drop70,\n", " \"outliers_missing_flag\": preprocess_outliers_missing_flag, \n", " \"outliers_imputation\": preprocess_outliers_imputation, \n", " \"outliers_drop70\": preprocess_outliers_drop70}\n", "\n", "version = \"v5_2-07-03\"\n", "\n", "for prep_name, prep_fn in preprocessings.items():\n", "\n", " # Sans optimisation\n", " mlflow.set_experiment(f\"{prep_name}_base_{version}\")\n", "\n", " with mlflow.start_run(run_name = f\"{prep_name}_base_{version}\"):\n", "\n", " X_prep = prep_fn(X)\n", "\n", " X_train, X_test, y_train, y_test = train_test_split(X_prep, y, test_size = 0.2, stratify = y, random_state = 4)\n", "\n", " # Sauvegarde pour SHAP\n", " X_test.to_csv(f\"data/X_test_prep_{prep_name}.csv\", index=False)\n", " y_test.to_csv(f\"data/y_test_prep_{prep_name}.csv\", index=False)\n", "\n", " preprocessor = tranformation_process(X_prep)\n", " \n", "\n", " # Log du dataset sans optimisation\n", " mlflow.log_input(mlflow.data.from_pandas(X_train, source=f\"{prep_name}_train_{version}\"))\n", "\n", " for model_name, (model, _) in modeles.items():\n", " print(f\"Modèle sans optimisation: {model_name}\")\n", "\n", " with mlflow.start_run(run_name = f\"{model_name}_{version}\", nested = True):\n", " evaluation_modele(model_name=model_name, model=model, X_train=X_train, X_test=X_test, y_train=y_train, y_test=y_test, preprocessor=preprocessor)\n", "\n", "\n", " # Avec optimisation des hyperparamètres\n", " mlflow.set_experiment(f\"{prep_name}_optimisé_{version}\")\n", "\n", " with mlflow.start_run(run_name = f\"{prep_name}_optimisé_{version}\"):\n", "\n", " X_prep = prep_fn(X)\n", "\n", " X_train, X_test, y_train, y_test = train_test_split(X_prep, y, test_size = 0.2, stratify = y, random_state = 4)\n", "\n", " # Sauvegarde pour SHAP\n", " X_test.to_csv(f\"data/X_test_prep_{prep_name}.csv\", index=False)\n", " y_test.to_csv(f\"data/y_test_prep_{prep_name}.csv\", index=False)\n", "\n", " preprocessor = tranformation_process(X_prep)\n", " \n", "\n", " # Log du dataset \n", " mlflow.log_input(mlflow.data.from_pandas(X_train, source=f\"{prep_name}_train_{version}\"))\n", "\n", " for model_name, (model, param_grid) in modeles.items():\n", " print(f\"Optimisation du modèle : {model_name}\")\n", "\n", " meilleur_modele, meilleur_params, meilleur_score = optimisation_hyperparametres( model_name, model, param_grid, preprocessor, X_train, y_train )\n", "\n", " with mlflow.start_run(run_name=f\"{model_name}_optimized_{version}\", nested=True):\n", "\n", " mlflow.log_params(meilleur_params) \n", " mlflow.log_metric(\"auc_cv_meilleur\", meilleur_score)\n", "\n", " evaluation_modele(model_name=f\"{model_name}_optimized\", model=meilleur_modele.named_steps[\"model\"], X_train=X_train, X_test=X_test, \n", " y_train=y_train, y_test=y_test, preprocessor=preprocessor)\n", "\n", " # Enregistrement dans le Model Registry \n", " mlflow.sklearn.log_model( meilleur_modele, artifact_path=\"model\", registered_model_name=f\"{prep_name}_{model_name}_optimized_{version}\" )\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "a2f38554", "metadata": {}, "outputs": [], "source": [ "import os\n", "os.listdir(\"C:/Users/Lenovo/Documents/WCS/GitHub/Classification-Risque-Credit-Pipeline-MLOps/mlruns\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "e19683d4", "metadata": {}, "outputs": [], "source": [ "mlflow.end_run()" ] }, { "cell_type": "code", "execution_count": 67, "id": "93f3f190", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
experimentrun_idrun_namepreprocessingmodemodelaucseuil_optimalcout_minimalprécisionrecall_bad_payersparams
21outliers_missing_flag_optimisé_v5_2-07-0379a042a4457d43c5a89a121722be0a30XGBoost_optimized_v5_2-07-03outliersoptimiséXGBoost_v5_2-07-030.780.5030629.00.1884980.672709{'base_score': 'None', 'booster': 'None', 'cal...
112missing_flag_optimisé_v5-07-03cd71d3352dad456f88a07b1a963d3829XGBoost_optimized_v5-07-03missingoptimiséXGBoost_v5-07-030.780.4730653.00.1872190.715408{'base_score': 'None', 'booster': 'None', 'cal...
82outliers_missing_flag_optimisé_v5-07-033cbe62ccc9344fbaae6cbfee303d3690XGBoost_optimized_v5-07-03outliersoptimiséXGBoost_v5-07-030.780.4730726.00.1874790.710574{'base_score': 'None', 'booster': 'None', 'cal...
51missing_flag_optimisé_v5_2-07-03bd607866a59f4ee6a2885ce926a59439XGBoost_optimized_v5_2-07-03missingoptimiséXGBoost_v5_2-07-030.780.4930771.00.1867580.684189{'base_score': 'None', 'booster': 'None', 'cal...
72outliers_imputation_optimisé_v5-07-03fe9a86b14f514878be5df6bf2692e663XGBoost_optimized_v5-07-03outliersoptimiséXGBoost_v5-07-030.780.5130771.00.1878650.657200{'base_score': 'None', 'booster': 'None', 'cal...
.......................................
133imputation_optimisé_v4-07-0398555b84ce5244eb9543e5abd4ff61e6imputation_optimisé_v4-07-03imputationoptimiséimputation_optimisé_v4-07-03NaNNaNNaNNaNNaN{}
138imputation_base_v4-07-033d975f8448a544fd945a2820eaf6b6a4imputation_base_v4-07-03imputationbaseimputation_base_v4-07-03NaNNaNNaNNaNNaN{}
143missing_flag_optimisé_v4-07-031c85cdcc54d94edba7e757ebab6520b2missing_flag_optimisé_v4-07-03missingoptimisémissing_flag_optimisé_v4-07-03NaNNaNNaNNaNNaN{}
144missing_flag_base_v4-07-0309350d3ffa5a490c82cd576116cf480amissing_flag_base_v4-07-03missingbasemissing_flag_base_v4-07-03NaNNaNNaNNaNNaN{}
149missing_flag_base_v4-07-03d5922ac0b502421dae3d09c6c7fb4596missing_flag_base_v4-07-03missingbasemissing_flag_base_v4-07-03NaNNaNNaNNaNNaN{}
\n", "

150 rows × 12 columns

\n", "
" ], "text/plain": [ " experiment \\\n", "21 outliers_missing_flag_optimisé_v5_2-07-03 \n", "112 missing_flag_optimisé_v5-07-03 \n", "82 outliers_missing_flag_optimisé_v5-07-03 \n", "51 missing_flag_optimisé_v5_2-07-03 \n", "72 outliers_imputation_optimisé_v5-07-03 \n", ".. ... \n", "133 imputation_optimisé_v4-07-03 \n", "138 imputation_base_v4-07-03 \n", "143 missing_flag_optimisé_v4-07-03 \n", "144 missing_flag_base_v4-07-03 \n", "149 missing_flag_base_v4-07-03 \n", "\n", " run_id run_name \\\n", "21 79a042a4457d43c5a89a121722be0a30 XGBoost_optimized_v5_2-07-03 \n", "112 cd71d3352dad456f88a07b1a963d3829 XGBoost_optimized_v5-07-03 \n", "82 3cbe62ccc9344fbaae6cbfee303d3690 XGBoost_optimized_v5-07-03 \n", "51 bd607866a59f4ee6a2885ce926a59439 XGBoost_optimized_v5_2-07-03 \n", "72 fe9a86b14f514878be5df6bf2692e663 XGBoost_optimized_v5-07-03 \n", ".. ... ... \n", "133 98555b84ce5244eb9543e5abd4ff61e6 imputation_optimisé_v4-07-03 \n", "138 3d975f8448a544fd945a2820eaf6b6a4 imputation_base_v4-07-03 \n", "143 1c85cdcc54d94edba7e757ebab6520b2 missing_flag_optimisé_v4-07-03 \n", "144 09350d3ffa5a490c82cd576116cf480a missing_flag_base_v4-07-03 \n", "149 d5922ac0b502421dae3d09c6c7fb4596 missing_flag_base_v4-07-03 \n", "\n", " preprocessing mode model auc \\\n", "21 outliers optimisé XGBoost_v5_2-07-03 0.78 \n", "112 missing optimisé XGBoost_v5-07-03 0.78 \n", "82 outliers optimisé XGBoost_v5-07-03 0.78 \n", "51 missing optimisé XGBoost_v5_2-07-03 0.78 \n", "72 outliers optimisé XGBoost_v5-07-03 0.78 \n", ".. ... ... ... ... \n", "133 imputation optimisé imputation_optimisé_v4-07-03 NaN \n", "138 imputation base imputation_base_v4-07-03 NaN \n", "143 missing optimisé missing_flag_optimisé_v4-07-03 NaN \n", "144 missing base missing_flag_base_v4-07-03 NaN \n", "149 missing base missing_flag_base_v4-07-03 NaN \n", "\n", " seuil_optimal cout_minimal précision recall_bad_payers \\\n", "21 0.50 30629.0 0.188498 0.672709 \n", "112 0.47 30653.0 0.187219 0.715408 \n", "82 0.47 30726.0 0.187479 0.710574 \n", "51 0.49 30771.0 0.186758 0.684189 \n", "72 0.51 30771.0 0.187865 0.657200 \n", ".. ... ... ... ... \n", "133 NaN NaN NaN NaN \n", "138 NaN NaN NaN NaN \n", "143 NaN NaN NaN NaN \n", "144 NaN NaN NaN NaN \n", "149 NaN NaN NaN NaN \n", "\n", " params \n", "21 {'base_score': 'None', 'booster': 'None', 'cal... \n", "112 {'base_score': 'None', 'booster': 'None', 'cal... \n", "82 {'base_score': 'None', 'booster': 'None', 'cal... \n", "51 {'base_score': 'None', 'booster': 'None', 'cal... \n", "72 {'base_score': 'None', 'booster': 'None', 'cal... \n", ".. ... \n", "133 {} \n", "138 {} \n", "143 {} \n", "144 {} \n", "149 {} \n", "\n", "[150 rows x 12 columns]" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Extraction des données finales: scores, coût minimal, seuil optimal, recall de mauvais payeurs pour chaque test effectué et par modèle\n", "\n", "def tous_les_runs():\n", " client = mlflow.tracking.MlflowClient()\n", " experiments = mlflow.search_experiments() # ✔️ compatible toutes versions\n", "\n", " rows = []\n", "\n", " for exp in experiments:\n", " runs = client.search_runs(exp.experiment_id)\n", "\n", " for run in runs:\n", " data = run.data\n", "\n", " row = {\n", " \"experiment\": exp.name,\n", " \"run_id\": run.info.run_id,\n", " \"run_name\": run.info.run_name,\n", " \"preprocessing\": exp.name.split(\"_\")[0],\n", " \"mode\": \"optimisé\" if \"optim\" in exp.name else \"base\",\n", " \"model\": run.info.run_name.replace(\"_optimized\", \"\"),\n", " \"auc\": data.metrics.get(\"auc_test\"),\n", " \"seuil_optimal\": data.metrics.get(\"best_threshold\"),\n", " \"cout_minimal\": data.metrics.get(\"business_cost\"),\n", " \"précision\": data.metrics.get(\"precision_test\"),\n", " \"recall_bad_payers\": data.metrics.get(\"recall_bad_payers\"),\n", " \"params\": data.params\n", " }\n", "\n", " rows.append(row) # ✔️ tu avais oublié d'ajouter la ligne !\n", "\n", " return pd.DataFrame(rows)\n", "\n", "df_results = tous_les_runs()\n", "df_results[\"auc\"] = df_results[\"auc\"].round(2)\n", "df_results_sorted = df_results.sort_values(by=[\"cout_minimal\", \"auc\"], ascending=[True, False])\n", "df_results_sorted\n", "\n" ] }, { "cell_type": "markdown", "id": "c8ba5429", "metadata": {}, "source": [ "### Meilleur modèle\n", "\n", "Après comparaison des modèles entre les éxpériences et les runs exécutés, le modèle **XGBoost** est celui qui a obtenu, toutes expériences confondues:\n", "- le meilleur coût minimal ***30629 €***\n", "- au seuil optimal de ***0,5***\n", "- avec un scor AUC de ***78%***\n", "- un taux de recall de ***67,3%***" ] }, { "cell_type": "code", "execution_count": 58, "id": "1faa4286", "metadata": {}, "outputs": [], "source": [ "def clean_experiment_name(exp_name):\n", " # Supprime la partie version à la fin (ex: _v5_2-07-03)\n", " parts = exp_name.split(\"_v\")\n", " return parts[0] # garde tout avant _v...\n", "\n", "df_results_sorted[\"nom_modele_ppt\"] = df_results_sorted.apply(lambda row: f\"{clean_experiment_name(row['experiment'])}_{row['model']}\", axis=1)\n" ] }, { "cell_type": "code", "execution_count": 59, "id": "d6b8d578", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "61" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_v6 = df_results_sorted[df_results_sorted['experiment'].str.contains('v5_2', na=False)]\n", "len(df_v6)" ] }, { "cell_type": "code", "execution_count": 51, "id": "6507dc95", "metadata": {}, "outputs": [], "source": [ "df_results_sorted.to_csv(\"data/resultats_runs_v4.csv\")" ] }, { "cell_type": "code", "execution_count": 18, "id": "6a2c2f35", "metadata": {}, "outputs": [], "source": [ "# Enregistrer le meilleur modèle pour utilisation ultérieure + pipeline transformation de données\n", "joblib.dump(meilleur_modele, \"best_model.joblib\")\n", "# joblib.dump(preprocessor, \"preprocessor.joblib\")\n", "mlflow.log_artifact(\"best_model.joblib\")\n" ] }, { "cell_type": "markdown", "id": "6e557a1c", "metadata": {}, "source": [ "#### Prédictions finales + décision de la demande" ] }, { "cell_type": "code", "execution_count": 19, "id": "87c3c651", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "set()" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expected_cols = preprocessor.feature_names_in_\n", "missing = set(expected_cols) - set(app_train_clean.columns)\n", "missing" ] }, { "cell_type": "code", "execution_count": 20, "id": "46973180", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "set()" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expected_cols = preprocessor.feature_names_in_\n", "missing = set(expected_cols) - set(app_test_clean.columns)\n", "missing" ] }, { "cell_type": "code", "execution_count": null, "id": "ebe32555", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Downloading artifacts: 0%| | 0/1 [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
SK_ID_CURRTARGETDECISION
01000010.144826REFUSÉ
11000050.523025ACCORDÉ
21000130.084557REFUSÉ
31000280.239340REFUSÉ
41000380.266300REFUSÉ
51000420.099464REFUSÉ
61000570.058770REFUSÉ
71000650.106076REFUSÉ
81000660.172418REFUSÉ
91000670.567248ACCORDÉ
101000740.123175REFUSÉ
111000900.344088REFUSÉ
121000910.679527ACCORDÉ
131000920.419423REFUSÉ
141001060.166479REFUSÉ
\n", "" ], "text/plain": [ " SK_ID_CURR TARGET DECISION\n", "0 100001 0.144826 REFUSÉ\n", "1 100005 0.523025 ACCORDÉ\n", "2 100013 0.084557 REFUSÉ\n", "3 100028 0.239340 REFUSÉ\n", "4 100038 0.266300 REFUSÉ\n", "5 100042 0.099464 REFUSÉ\n", "6 100057 0.058770 REFUSÉ\n", "7 100065 0.106076 REFUSÉ\n", "8 100066 0.172418 REFUSÉ\n", "9 100067 0.567248 ACCORDÉ\n", "10 100074 0.123175 REFUSÉ\n", "11 100090 0.344088 REFUSÉ\n", "12 100091 0.679527 ACCORDÉ\n", "13 100092 0.419423 REFUSÉ\n", "14 100106 0.166479 REFUSÉ" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Récupération du meilleur run\n", "best_row = df_results_sorted.iloc[0]\n", "best_run_id = best_row[\"run_id\"]\n", "best_threshold = best_row[\"seuil_optimal\"]\n", "\n", "# Sauvegarde du seuil et du run_id\n", "joblib.dump(best_threshold, \"best_threshold.joblib\")\n", "\n", "with open(\"best_run_id.txt\", \"w\") as f:\n", " f.write(best_run_id)\n", "\n", "with open(\"best_model_name.txt\", \"w\") as f:\n", " f.write(best_row[\"model\"]) # garder le nom du modèle\n", "\n", "\n", "# Chargement du pipeline complet depuis MLflow - charge le préprocesseur + le modèle déjà fit\n", "pipe = mlflow.sklearn.load_model(f\"runs:/{best_run_id}/model\")\n", "\n", "\n", "# Prédictions finales sur app_test_clean\n", "y_pred_final = pipe.predict_proba(app_test_clean)[:, 1]\n", "\n", "# Application du seuil optimal\n", "decision = (y_pred_final >= best_threshold).astype(int)\n", "\n", "\n", "# Construction du dataframe final\n", "pred_finales3 = pd.DataFrame({\n", " \"SK_ID_CURR\": app_test_clean[\"SK_ID_CURR\"],\n", " \"TARGET\": y_pred_final,\n", " \"DECISION\": decision\n", "})\n", "\n", "pred_finales3[\"DECISION\"] = pred_finales3[\"DECISION\"].map({\n", " 1: \"ACCORDÉ\",\n", " 0: \"REFUSÉ\"\n", "})\n", "\n", "pred_finales3.head(15)\n" ] }, { "cell_type": "code", "execution_count": 22, "id": "c4023f58", "metadata": {}, "outputs": [], "source": [ "pred_finales3.to_csv(\"data/pred_finales3.csv\")" ] }, { "cell_type": "code", "execution_count": 23, "id": "507854c5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "79a042a4457d43c5a89a121722be0a30 XGBoost_optimized_v5_2-07-03\n", "Pipeline(steps=[('preprocess',\n", " ColumnTransformer(transformers=[('num', StandardScaler(),\n", " ['SK_ID_CURR',\n", " 'BUREAU_SK_ID_BUREAU_max',\n", " 'POS_SK_DPD_min',\n", " 'PREV_NAME_TYPE_SUITE_Family',\n", " 'PREV_DAYS_FIRST_DRAWING_sum',\n", " 'PREV_NAME_GOODS_CATEGORY_Other',\n", " 'DAYS_LAST_PHONE_CHANGE',\n", " 'PREV_DAYS_FIRST_DRAWING_max',\n", " 'PREV_PRODUCT_COMBINATION_POS '\n", " 'others without interest',\n", " 'PREV...\n", " feature_types=None, gamma=2, grow_policy=None,\n", " importance_type=None,\n", " interaction_constraints=None, learning_rate=0.1,\n", " max_bin=None, max_cat_threshold=None,\n", " max_cat_to_onehot=None, max_delta_step=None,\n", " max_depth=3, max_leaves=None, min_child_weight=3,\n", " missing=nan, monotone_constraints=None,\n", " multi_strategy=None, n_estimators=200,\n", " n_jobs=None, num_parallel_tree=None,\n", " random_state=42, ...))])\n", "0.5\n" ] } ], "source": [ "# vérifier que le run existe dans MLFlow\n", "client = mlflow.tracking.MlflowClient()\n", "run = client.get_run(best_run_id)\n", "print(run.info.run_id, run.info.run_name)\n", "\n", "# Vérifier que le modèle chargé correspond au run\n", "print(meilleur_modele)\n", "\n", "# Vérifier le seuil optimal\n", "print(best_threshold)\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "6ad2fe1e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.8551737 , 0.14482628]], dtype=float32)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import joblib\n", "import pandas as pd\n", "\n", "pipe = joblib.load(\"../BestModel/pipeline_complet.joblib\")\n", "\n", "df = joblib.load(\"../data/app_test_clean_v2.joblib\") # ton dataset brut à 328 colonnes\n", "test = df.iloc[[0]]\n", "\n", "pipe.predict_proba(test)\n", "\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "38fca3b4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'SK_ID_CURR': 100001,\n", " 'NAME_CONTRACT_TYPE': 'Cash loans',\n", " 'CODE_GENDER': 'F',\n", " 'FLAG_OWN_CAR': 'N',\n", " 'FLAG_OWN_REALTY': 'Y',\n", " 'CNT_CHILDREN': 0,\n", " 'AMT_INCOME_TOTAL': 135000.0,\n", " 'AMT_GOODS_PRICE': 450000.0,\n", " 'NAME_TYPE_SUITE': 'Unaccompanied',\n", " 'NAME_INCOME_TYPE': 'Working',\n", " 'NAME_EDUCATION_TYPE': 'Higher education',\n", " 'NAME_FAMILY_STATUS': 'Married',\n", " 'NAME_HOUSING_TYPE': 'House / apartment',\n", " 'REGION_POPULATION_RELATIVE': 0.01885,\n", " 'DAYS_BIRTH': -19241,\n", " 'DAYS_EMPLOYED': -2329,\n", " 'DAYS_REGISTRATION': -5170.0,\n", " 'DAYS_ID_PUBLISH': -812,\n", " 'OWN_CAR_AGE': nan,\n", " 'FLAG_MOBIL': True,\n", " 'FLAG_EMP_PHONE': True,\n", " 'FLAG_WORK_PHONE': False,\n", " 'FLAG_CONT_MOBILE': True,\n", " 'FLAG_PHONE': False,\n", " 'FLAG_EMAIL': True,\n", " 'OCCUPATION_TYPE': nan,\n", " 'REGION_RATING_CLIENT_W_CITY': 2,\n", " 'WEEKDAY_APPR_PROCESS_START': 'TUESDAY',\n", " 'HOUR_APPR_PROCESS_START': 18,\n", " 'REG_REGION_NOT_LIVE_REGION': False,\n", " 'REG_REGION_NOT_WORK_REGION': False,\n", " 'LIVE_REGION_NOT_WORK_REGION': False,\n", " 'REG_CITY_NOT_LIVE_CITY': False,\n", " 'REG_CITY_NOT_WORK_CITY': False,\n", " 'LIVE_CITY_NOT_WORK_CITY': False,\n", " 'ORGANIZATION_TYPE': 'Kindergarten',\n", " 'EXT_SOURCE_1': 0.7526144906031748,\n", " 'EXT_SOURCE_2': 0.7896543511176771,\n", " 'EXT_SOURCE_3': 0.1595195404777181,\n", " 'BASEMENTAREA_AVG': 0.059,\n", " 'ELEVATORS_AVG': nan,\n", " 'ENTRANCES_AVG': 0.1379,\n", " 'FLOORSMAX_AVG': 0.125,\n", " 'NONLIVINGAPARTMENTS_AVG': nan,\n", " 'NONLIVINGAREA_AVG': nan,\n", " 'YEARS_BEGINEXPLUATATION_MEDI': 0.9732,\n", " 'YEARS_BUILD_MEDI': nan,\n", " 'COMMONAREA_MEDI': nan,\n", " 'LANDAREA_MEDI': nan,\n", " 'FONDKAPREMONT_MODE': nan,\n", " 'HOUSETYPE_MODE': 'block of flats',\n", " 'WALLSMATERIAL_MODE': 'Stone, brick',\n", " 'EMERGENCYSTATE_MODE': 'No',\n", " 'OBS_30_CNT_SOCIAL_CIRCLE': 0.0,\n", " 'DEF_30_CNT_SOCIAL_CIRCLE': 0.0,\n", " 'DAYS_LAST_PHONE_CHANGE': -1740.0,\n", " 'FLAG_DOCUMENT_2': False,\n", " 'FLAG_DOCUMENT_3': True,\n", " 'FLAG_DOCUMENT_4': False,\n", " 'FLAG_DOCUMENT_5': False,\n", " 'FLAG_DOCUMENT_6': False,\n", " 'FLAG_DOCUMENT_7': False,\n", " 'FLAG_DOCUMENT_8': False,\n", " 'FLAG_DOCUMENT_9': False,\n", " 'FLAG_DOCUMENT_10': False,\n", " 'FLAG_DOCUMENT_11': False,\n", " 'FLAG_DOCUMENT_12': False,\n", " 'FLAG_DOCUMENT_13': False,\n", " 'FLAG_DOCUMENT_14': False,\n", " 'FLAG_DOCUMENT_15': False,\n", " 'FLAG_DOCUMENT_16': False,\n", " 'FLAG_DOCUMENT_17': False,\n", " 'FLAG_DOCUMENT_18': False,\n", " 'FLAG_DOCUMENT_19': False,\n", " 'FLAG_DOCUMENT_20': False,\n", " 'FLAG_DOCUMENT_21': False,\n", " 'AMT_REQ_CREDIT_BUREAU_HOUR': 0.0,\n", " 'AMT_REQ_CREDIT_BUREAU_DAY': 0.0,\n", " 'AMT_REQ_CREDIT_BUREAU_WEEK': 0.0,\n", " 'AMT_REQ_CREDIT_BUREAU_MON': 0.0,\n", " 'AMT_REQ_CREDIT_BUREAU_QRT': 0.0,\n", " 'BUREAU_SK_ID_BUREAU_max': 5896636.0,\n", " 'BUREAU_DAYS_CREDIT_mean': -1009.2848837209302,\n", " 'BUREAU_DAYS_CREDIT_max': -49.0,\n", " 'BUREAU_DAYS_CREDIT_min': -1572.0,\n", " 'BUREAU_CREDIT_DAY_OVERDUE_mean': 0.0,\n", " 'BUREAU_CREDIT_DAY_OVERDUE_sum': 0.0,\n", " 'BUREAU_DAYS_CREDIT_ENDDATE_mean': -456.02906976744185,\n", " 'BUREAU_DAYS_CREDIT_ENDDATE_max': 1778.0,\n", " 'BUREAU_DAYS_CREDIT_ENDDATE_min': -1329.0,\n", " 'BUREAU_DAYS_CREDIT_ENDDATE_sum': -78437.0,\n", " 'BUREAU_DAYS_ENDDATE_FACT_max': -544.0,\n", " 'BUREAU_DAYS_ENDDATE_FACT_sum': -127179.0,\n", " 'BUREAU_AMT_CREDIT_MAX_OVERDUE_max': nan,\n", " 'BUREAU_CNT_CREDIT_PROLONG_max': 0.0,\n", " 'BUREAU_CNT_CREDIT_PROLONG_sum': 0.0,\n", " 'BUREAU_AMT_CREDIT_SUM_mean': 161516.25,\n", " 'BUREAU_AMT_CREDIT_SUM_min': 85500.0,\n", " 'BUREAU_AMT_CREDIT_SUM_sum': 27780795.0,\n", " 'BUREAU_AMT_CREDIT_SUM_DEBT_max': 373239.0,\n", " 'BUREAU_AMT_CREDIT_SUM_DEBT_sum': 4109728.5,\n", " 'BUREAU_AMT_CREDIT_SUM_LIMIT_mean': 0.0,\n", " 'BUREAU_AMT_CREDIT_SUM_LIMIT_sum': 0.0,\n", " 'BUREAU_AMT_CREDIT_SUM_OVERDUE_max': 0.0,\n", " 'BUREAU_AMT_CREDIT_SUM_OVERDUE_sum': 0.0,\n", " 'BUREAU_AMT_ANNUITY_mean': 1236.2441860465117,\n", " 'BUREAU_AMT_ANNUITY_min': 0.0,\n", " 'BUREAU_MONTHS_BALANCE_max': 0.0,\n", " 'BUREAU_CREDIT_ACTIVE_NUNIQUE': 2.0,\n", " 'BUREAU_CREDIT_CURRENCY_NUNIQUE': 1.0,\n", " 'BUREAU_CREDIT_TYPE_NUNIQUE': 1.0,\n", " 'BUREAU_STATUS_NUNIQUE': 4.0,\n", " 'BUREAU_CREDIT_ACTIVE_Bad debt': 0.0,\n", " 'BUREAU_CREDIT_ACTIVE_Sold': 0.0,\n", " 'BUREAU_CREDIT_CURRENCY_currency 2': 0.0,\n", " 'BUREAU_CREDIT_CURRENCY_currency 3': 0.0,\n", " 'BUREAU_CREDIT_CURRENCY_currency 4': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Another type of loan': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Car loan': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Cash loan (non-earmarked)': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Interbank credit': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Loan for business development': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Loan for purchase of shares (margin lending)': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Loan for the purchase of equipment': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Loan for working capital replenishment': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Microloan': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Mobile operator loan': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Mortgage': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Real estate loan': 0.0,\n", " 'BUREAU_CREDIT_TYPE_Unknown type of loan': 0.0,\n", " 'BUREAU_STATUS_1': 1.0,\n", " 'BUREAU_STATUS_2': 0.0,\n", " 'BUREAU_STATUS_4': 0.0,\n", " 'BUREAU_STATUS_5': 0.0,\n", " 'PREV_AMT_ANNUITY_mean': 3951.0,\n", " 'PREV_AMT_ANNUITY_min': 3951.0,\n", " 'PREV_AMT_APPLICATION_min': 24835.5,\n", " 'PREV_AMT_DOWN_PAYMENT_sum': 2520.0,\n", " 'PREV_HOUR_APPR_PROCESS_START_mean': 13.0,\n", " 'PREV_NFLAG_LAST_APPL_IN_DAY_max': 1.0,\n", " 'PREV_NFLAG_LAST_APPL_IN_DAY_min': 1.0,\n", " 'PREV_RATE_DOWN_PAYMENT_max': 0.1043261904021397,\n", " 'PREV_RATE_DOWN_PAYMENT_sum': 0.1043261904021397,\n", " 'PREV_RATE_INTEREST_PRIMARY_max': nan,\n", " 'PREV_RATE_INTEREST_PRIMARY_sum': 0.0,\n", " 'PREV_RATE_INTEREST_PRIVILEGED_max': nan,\n", " 'PREV_SELLERPLACE_AREA_sum': 23.0,\n", " 'PREV_CNT_PAYMENT_max': 8.0,\n", " 'PREV_CNT_PAYMENT_min': 8.0,\n", " 'PREV_DAYS_FIRST_DRAWING_mean': 365243.0,\n", " 'PREV_DAYS_FIRST_DRAWING_max': 365243.0,\n", " 'PREV_DAYS_FIRST_DRAWING_sum': 365243.0,\n", " 'PREV_DAYS_FIRST_DUE_min': -1709.0,\n", " 'PREV_DAYS_LAST_DUE_mean': -1619.0,\n", " 'PREV_DAYS_LAST_DUE_min': -1619.0,\n", " 'PREV_DAYS_TERMINATION_mean': -1612.0,\n", " 'PREV_NFLAG_INSURED_ON_APPROVAL_sum': 0.0,\n", " 'PREV_NAME_PAYMENT_TYPE_NUNIQUE': 1.0,\n", " 'PREV_CODE_REJECT_REASON_NUNIQUE': 1.0,\n", " 'PREV_NAME_TYPE_SUITE_NUNIQUE': 1.0,\n", " 'PREV_NAME_CLIENT_TYPE_NUNIQUE': 1.0,\n", " 'PREV_NAME_PRODUCT_TYPE_NUNIQUE': 1.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_NUNIQUE': 1.0,\n", " 'PREV_NAME_CONTRACT_TYPE_XNA': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_FRIDAY': 1.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_MONDAY': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_SATURDAY': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_SUNDAY': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_THURSDAY': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_TUESDAY': 0.0,\n", " 'PREV_WEEKDAY_APPR_PROCESS_START_WEDNESDAY': 0.0,\n", " 'PREV_FLAG_LAST_APPL_PER_CONTRACT_N': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Building a house or an annex': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Business development': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Buying a garage': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Buying a holiday home / land': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Buying a home': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Buying a new car': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Buying a used car': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Car repairs': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Education': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Everyday expenses': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Furniture': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Gasification / water supply': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Hobby': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Journey': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Medicine': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Money for a third person': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Other': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Payments on other loans': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Purchase of electronic equipment': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Refusal to name the goal': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Repairs': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Urgent needs': 0.0,\n", " 'PREV_NAME_CASH_LOAN_PURPOSE_Wedding / gift / holiday': 0.0,\n", " 'PREV_NAME_CONTRACT_STATUS_Refused': 0.0,\n", " 'PREV_NAME_CONTRACT_STATUS_Unused offer': 0.0,\n", " 'PREV_NAME_PAYMENT_TYPE_Cashless from the account of the employer': 0.0,\n", " 'PREV_NAME_PAYMENT_TYPE_Non-cash from your account': 0.0,\n", " 'PREV_CODE_REJECT_REASON_LIMIT': 0.0,\n", " 'PREV_CODE_REJECT_REASON_SCO': 0.0,\n", " 'PREV_CODE_REJECT_REASON_SCOFR': 0.0,\n", " 'PREV_CODE_REJECT_REASON_SYSTEM': 0.0,\n", " 'PREV_CODE_REJECT_REASON_VERIF': 0.0,\n", " 'PREV_CODE_REJECT_REASON_XNA': 0.0,\n", " 'PREV_NAME_TYPE_SUITE_Children': 0.0,\n", " 'PREV_NAME_TYPE_SUITE_Family': 1.0,\n", " 'PREV_NAME_TYPE_SUITE_Group of people': 0.0,\n", " 'PREV_NAME_TYPE_SUITE_Other_A': 0.0,\n", " 'PREV_NAME_TYPE_SUITE_Other_B': 0.0,\n", " 'PREV_NAME_TYPE_SUITE_Spouse, partner': 0.0,\n", " 'PREV_NAME_CLIENT_TYPE_New': 0.0,\n", " 'PREV_NAME_CLIENT_TYPE_Refreshed': 1.0,\n", " 'PREV_NAME_CLIENT_TYPE_XNA': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Additional Service': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Animals': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Audio/Video': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Auto Accessories': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Clothing and Accessories': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Computers': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Consumer Electronics': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Direct Sales': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Education': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Fitness': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Gardening': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Homewares': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Insurance': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Jewelry': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Medical Supplies': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Medicine': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Office Appliances': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Other': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Photo / Cinema Equipment': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Sport and Leisure': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Tourism': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Vehicles': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_Weapon': 0.0,\n", " 'PREV_NAME_GOODS_CATEGORY_XNA': 0.0,\n", " 'PREV_NAME_PORTFOLIO_POS': 1.0,\n", " 'PREV_NAME_PRODUCT_TYPE_walk-in': 0.0,\n", " 'PREV_CHANNEL_TYPE_AP+ (Cash loan)': 0.0,\n", " 'PREV_CHANNEL_TYPE_Car dealer': 0.0,\n", " 'PREV_CHANNEL_TYPE_Channel of corporate sales': 0.0,\n", " 'PREV_CHANNEL_TYPE_Contact center': 0.0,\n", " 'PREV_CHANNEL_TYPE_Regional / Local': 0.0,\n", " 'PREV_CHANNEL_TYPE_Stone': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Auto technology': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Connectivity': 1.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Construction': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Industry': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Jewelry': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_MLM partners': 0.0,\n", " 'PREV_NAME_SELLER_INDUSTRY_Tourism': 0.0,\n", " 'PREV_NAME_YIELD_GROUP_XNA': 0.0,\n", " 'PREV_NAME_YIELD_GROUP_low_action': 0.0,\n", " 'PREV_NAME_YIELD_GROUP_low_normal': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Card Street': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Cash Street: high': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Cash Street: low': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Cash Street: middle': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Cash X-Sell: high': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_Cash X-Sell: middle': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_POS industry with interest': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_POS industry without interest': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_POS mobile without interest': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_POS other with interest': 0.0,\n", " 'PREV_PRODUCT_COMBINATION_POS others without interest': 0.0,\n", " 'INST_PAY_NUM_INSTALMENT_VERSION_mean': 1.1428571428571428,\n", " 'INST_PAY_DAYS_ENTRY_PAYMENT_mean': -2195.0,\n", " 'INST_PAY_DAYS_ENTRY_PAYMENT_min': -2916.0,\n", " 'INST_PAY_AMT_PAYMENT_mean': 5885.132142857144,\n", " 'INST_PAY_AMT_PAYMENT_min': 3951.0,\n", " 'INST_PAY_AMT_PAYMENT_sum': 41195.925,\n", " 'INST_PAY_PAYMENT_DELAY_mean': -7.285714285714286,\n", " 'INST_PAY_PAYMENT_DELAY_max': 11.0,\n", " 'INST_PAY_PAYMENT_DELAY_min': -36.0,\n", " 'INST_PAY_PAYMENT_DELAY_sum': -51.0,\n", " 'INST_PAY_PAYMENT_RATIO_mean': 1.0,\n", " 'INST_PAY_PAYMENT_RATIO_min': 1.0,\n", " 'CC_MONTHS_BALANCE_mean': nan,\n", " 'CC_MONTHS_BALANCE_max': nan,\n", " 'CC_AMT_BALANCE_mean': nan,\n", " 'CC_AMT_CREDIT_LIMIT_ACTUAL_max': nan,\n", " 'CC_AMT_CREDIT_LIMIT_ACTUAL_sum': nan,\n", " 'CC_AMT_DRAWINGS_ATM_CURRENT_mean': nan,\n", " 'CC_AMT_DRAWINGS_ATM_CURRENT_sum': nan,\n", " 'CC_AMT_DRAWINGS_CURRENT_mean': nan,\n", " 'CC_AMT_DRAWINGS_CURRENT_max': nan,\n", " 'CC_AMT_DRAWINGS_CURRENT_min': nan,\n", " 'CC_AMT_DRAWINGS_POS_CURRENT_min': nan,\n", " 'CC_AMT_INST_MIN_REGULARITY_min': nan,\n", " 'CC_AMT_PAYMENT_CURRENT_min': nan,\n", " 'CC_AMT_PAYMENT_TOTAL_CURRENT_max': nan,\n", " 'CC_CNT_DRAWINGS_ATM_CURRENT_mean': nan,\n", " 'CC_CNT_DRAWINGS_ATM_CURRENT_min': nan,\n", " 'CC_CNT_DRAWINGS_ATM_CURRENT_sum': nan,\n", " 'CC_CNT_DRAWINGS_CURRENT_max': nan,\n", " 'CC_CNT_DRAWINGS_CURRENT_min': nan,\n", " 'CC_CNT_DRAWINGS_OTHER_CURRENT_mean': nan,\n", " 'CC_CNT_DRAWINGS_OTHER_CURRENT_min': nan,\n", " 'CC_SK_DPD_max': nan,\n", " 'CC_SK_DPD_DEF_max': nan,\n", " 'CC_UTILIZATION_mean': nan,\n", " 'CC_UTILIZATION_max': nan,\n", " 'CC_UTILIZATION_min': nan,\n", " 'CC_PAYMENT_RATIO_max': nan,\n", " 'CC_PAYMENT_RATIO_min': nan,\n", " 'CC_NAME_CONTRACT_STATUS_NUNIQUE': nan,\n", " 'CC_NAME_CONTRACT_STATUS_Approved': nan,\n", " 'CC_NAME_CONTRACT_STATUS_Completed': nan,\n", " 'CC_NAME_CONTRACT_STATUS_Refused': nan,\n", " 'CC_NAME_CONTRACT_STATUS_Sent proposal': nan,\n", " 'CC_NAME_CONTRACT_STATUS_Signed': nan,\n", " 'POS_CNT_INSTALMENT_min': 4.0,\n", " 'POS_CNT_INSTALMENT_FUTURE_min': 0.0,\n", " 'POS_SK_DPD_mean': 0.7777777777777778,\n", " 'POS_SK_DPD_min': 0.0,\n", " 'POS_SK_DPD_DEF_max': 7.0,\n", " 'POS_SK_DPD_DEF_min': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_NUNIQUE': 2.0,\n", " 'POS_NAME_CONTRACT_STATUS_Amortized debt': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_Approved': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_Canceled': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_Completed': 2.0,\n", " 'POS_NAME_CONTRACT_STATUS_Returned to the store': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_Signed': 0.0,\n", " 'POS_NAME_CONTRACT_STATUS_XNA': 0.0}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "individu = df.iloc[0].to_dict()\n", "individu" ] } ], "metadata": { "kernelspec": { "display_name": "mlops", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.15" } }, "nbformat": 4, "nbformat_minor": 5 }