mirror of
https://github.com/BreizhHardware/cours-ISEN-MD.git
synced 2026-01-18 16:47:24 +01:00
Obisidian vault auto-backup: 29-09-2025 15:19:43 on . 1 files edited
This commit is contained in:
@@ -1583,9 +1583,203 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 53,
|
||||
"id": "b4a6c352",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"=== Calcul des métriques de performance avec sklearn.metrics ===\n",
|
||||
"\n",
|
||||
"Précision (Precision): 0.6687\n",
|
||||
"Rappel (Recall): 0.8441\n",
|
||||
"Score F1: 0.7462\n",
|
||||
"\n",
|
||||
"=== Interprétation des résultats ===\n",
|
||||
"\n",
|
||||
"1. PRÉCISION = 0.6687 (66.87%)\n",
|
||||
" • Sur toutes les images que le modèle a classées comme '5',\n",
|
||||
" 66.87% sont réellement des '5'\n",
|
||||
" • 33.13% sont des faux positifs (erreurs)\n",
|
||||
"\n",
|
||||
"2. RAPPEL = 0.8441 (84.41%)\n",
|
||||
" • Sur toutes les vraies images de '5' dans la base,\n",
|
||||
" le modèle en a détecté 84.41%\n",
|
||||
" • Il a manqué 15.59% des vrais '5' (faux négatifs)\n",
|
||||
"\n",
|
||||
"3. SCORE F1 = 0.7462 (74.62%)\n",
|
||||
" • Moyenne harmonique entre précision et rappel\n",
|
||||
" • Mesure équilibrée des performances globales\n",
|
||||
"\n",
|
||||
"=== Analyse comparative ===\n",
|
||||
"✓ Rappel > Précision : Le modèle est plutôt libéral\n",
|
||||
" → Il détecte bien les '5' mais fait quelques erreurs en trop\n",
|
||||
"\n",
|
||||
"✅ CONCLUSION: Performances BONNES (F1 ≥ 60%)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from sklearn.metrics import precision_score, recall_score, f1_score\n",
|
||||
"\n",
|
||||
"print(\"=== Calcul des métriques de performance avec sklearn.metrics ===\\n\")\n",
|
||||
"\n",
|
||||
"# Calculer la précision\n",
|
||||
"precision = precision_score(y_train_5, y_train_pred)\n",
|
||||
"print(f\"Précision (Precision): {precision:.4f}\")\n",
|
||||
"\n",
|
||||
"# Calculer le rappel\n",
|
||||
"recall = recall_score(y_train_5, y_train_pred)\n",
|
||||
"print(f\"Rappel (Recall): {recall:.4f}\")\n",
|
||||
"\n",
|
||||
"# Calculer le score F1\n",
|
||||
"f1 = f1_score(y_train_5, y_train_pred)\n",
|
||||
"print(f\"Score F1: {f1:.4f}\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n=== Interprétation des résultats ===\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n1. PRÉCISION = {precision:.4f} ({precision*100:.2f}%)\")\n",
|
||||
"print(f\" • Sur toutes les images que le modèle a classées comme '5',\")\n",
|
||||
"print(f\" {precision*100:.2f}% sont réellement des '5'\")\n",
|
||||
"print(f\" • {(1-precision)*100:.2f}% sont des faux positifs (erreurs)\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n2. RAPPEL = {recall:.4f} ({recall*100:.2f}%)\")\n",
|
||||
"print(f\" • Sur toutes les vraies images de '5' dans la base,\")\n",
|
||||
"print(f\" le modèle en a détecté {recall*100:.2f}%\")\n",
|
||||
"print(f\" • Il a manqué {(1-recall)*100:.2f}% des vrais '5' (faux négatifs)\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n3. SCORE F1 = {f1:.4f} ({f1*100:.2f}%)\")\n",
|
||||
"print(f\" • Moyenne harmonique entre précision et rappel\")\n",
|
||||
"print(f\" • Mesure équilibrée des performances globales\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n=== Analyse comparative ===\")\n",
|
||||
"if precision > recall:\n",
|
||||
" print(f\"✓ Précision > Rappel : Le modèle est plutôt conservateur\")\n",
|
||||
" print(f\" → Il évite les faux positifs mais manque quelques vrais '5'\")\n",
|
||||
"elif recall > precision:\n",
|
||||
" print(f\"✓ Rappel > Précision : Le modèle est plutôt libéral\")\n",
|
||||
" print(f\" → Il détecte bien les '5' mais fait quelques erreurs en trop\")\n",
|
||||
"else:\n",
|
||||
" print(f\"✓ Précision ≈ Rappel : Modèle équilibré\")\n",
|
||||
"\n",
|
||||
"# Évaluation globale\n",
|
||||
"if f1 >= 0.8:\n",
|
||||
" print(f\"\\n🎯 CONCLUSION: Performances EXCELLENTES (F1 ≥ 80%)\")\n",
|
||||
"elif f1 >= 0.6:\n",
|
||||
" print(f\"\\n✅ CONCLUSION: Performances BONNES (F1 ≥ 60%)\")\n",
|
||||
"elif f1 >= 0.4:\n",
|
||||
" print(f\"\\n⚠️ CONCLUSION: Performances MOYENNES (F1 ≥ 40%)\")\n",
|
||||
"else:\n",
|
||||
" print(f\"\\n❌ CONCLUSION: Performances FAIBLES (F1 < 40%)\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 54,
|
||||
"id": "1ad09da3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"=== Calcul des scores de décision avec cross_val_predict ===\n",
|
||||
"\n",
|
||||
"Type des scores: <class 'numpy.ndarray'>\n",
|
||||
"Forme des scores: (60000,)\n",
|
||||
"Type des éléments: <class 'numpy.float64'>\n",
|
||||
"\n",
|
||||
"Premiers 20 scores: [ 2233.76472412 -16999.83146625 -29880.24945215 -16853.32804962\n",
|
||||
" -18123.62732289 -16786.05163476 -14344.66419922 -19160.60912277\n",
|
||||
" -6866.69750684 -13676.7779591 -17430.53807378 764.86406397\n",
|
||||
" -32548.13164662 -17809.33743497 -5282.69063153 -17399.14087231\n",
|
||||
" -24825.67568325 -17165.2237745 -4832.03170209 -23564.24796162]\n",
|
||||
"Derniers 20 scores: [ -2239.56847032 -12125.14890084 -6850.7198163 -20119.91822338\n",
|
||||
" -11602.78108538 -24718.65480959 -4477.63088789 -7211.15680865\n",
|
||||
" -6894.02349027 -6421.21472386 -9677.81738926 -10311.26010833\n",
|
||||
" -3368.75566452 5493.88995718 -3859.07168195 -11446.19872796\n",
|
||||
" -10968.14148588 3272.83384068 -3009.89051515 -8557.27433151]\n",
|
||||
"\n",
|
||||
"=== Statistiques des scores de décision ===\n",
|
||||
"Nombre total de scores: 60000\n",
|
||||
"Score minimum: -122128.9854\n",
|
||||
"Score maximum: 33569.8437\n",
|
||||
"Score moyen: -12893.4394\n",
|
||||
"Écart-type: 11346.1342\n",
|
||||
"\n",
|
||||
"=== Répartition selon le seuil par défaut (0) ===\n",
|
||||
"Scores positifs (> 0): 5233 - Prédits comme '5'\n",
|
||||
"Scores négatifs (≤ 0): 54767 - Prédits comme 'Non-5'\n",
|
||||
"Pourcentage de scores positifs: 8.72%\n",
|
||||
"Pourcentage de scores négatifs: 91.28%\n",
|
||||
"\n",
|
||||
"=== Vérification de cohérence ===\n",
|
||||
"Les prédictions binaires (score > 0) correspondent aux prédictions précédentes: False\n",
|
||||
"\n",
|
||||
"=== Conclusion ===\n",
|
||||
"Les scores de décision permettent de comprendre la 'confiance' du modèle:\n",
|
||||
"• Plus le score est élevé, plus le modèle est confiant que c'est un '5'\n",
|
||||
"• Plus le score est faible (négatif), plus le modèle est confiant que ce n'est PAS un '5'\n",
|
||||
"• Le seuil par défaut de 0 sépare les deux classes\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from sklearn.model_selection import cross_val_predict\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"print(\"=== Calcul des scores de décision avec cross_val_predict ===\\n\")\n",
|
||||
"\n",
|
||||
"# Utiliser cross_val_predict avec method='decision_function' pour obtenir les scores\n",
|
||||
"# Cette fonction retourne les scores de décision pour chaque échantillon lors de la validation croisée 3-fold\n",
|
||||
"y_train_scores = cross_val_predict(sgd_classifier, X_train, y_train_5, cv=3, method='decision_function')\n",
|
||||
"\n",
|
||||
"print(f\"Type des scores: {type(y_train_scores)}\")\n",
|
||||
"print(f\"Forme des scores: {y_train_scores.shape}\")\n",
|
||||
"print(f\"Type des éléments: {type(y_train_scores[0])}\")\n",
|
||||
"\n",
|
||||
"# Afficher quelques exemples de scores\n",
|
||||
"print(f\"\\nPremiers 20 scores: {y_train_scores[:20]}\")\n",
|
||||
"print(f\"Derniers 20 scores: {y_train_scores[-20:]}\")\n",
|
||||
"\n",
|
||||
"# Statistiques des scores\n",
|
||||
"print(f\"\\n=== Statistiques des scores de décision ===\")\n",
|
||||
"print(f\"Nombre total de scores: {len(y_train_scores)}\")\n",
|
||||
"print(f\"Score minimum: {y_train_scores.min():.4f}\")\n",
|
||||
"print(f\"Score maximum: {y_train_scores.max():.4f}\")\n",
|
||||
"print(f\"Score moyen: {y_train_scores.mean():.4f}\")\n",
|
||||
"print(f\"Écart-type: {y_train_scores.std():.4f}\")\n",
|
||||
"\n",
|
||||
"# Compter les scores positifs et négatifs (seuil par défaut = 0)\n",
|
||||
"scores_positifs = np.sum(y_train_scores > 0)\n",
|
||||
"scores_negatifs = np.sum(y_train_scores <= 0)\n",
|
||||
"\n",
|
||||
"print(f\"\\n=== Répartition selon le seuil par défaut (0) ===\")\n",
|
||||
"print(f\"Scores positifs (> 0): {scores_positifs} - Prédits comme '5'\")\n",
|
||||
"print(f\"Scores négatifs (≤ 0): {scores_negatifs} - Prédits comme 'Non-5'\")\n",
|
||||
"print(f\"Pourcentage de scores positifs: {(scores_positifs / len(y_train_scores) * 100):.2f}%\")\n",
|
||||
"print(f\"Pourcentage de scores négatifs: {(scores_negatifs / len(y_train_scores) * 100):.2f}%\")\n",
|
||||
"\n",
|
||||
"# Comparaison avec les prédictions binaires précédentes\n",
|
||||
"predictions_binaires = (y_train_scores > 0)\n",
|
||||
"coherence = np.array_equal(predictions_binaires, y_train_pred)\n",
|
||||
"print(f\"\\n=== Vérification de cohérence ===\")\n",
|
||||
"print(f\"Les prédictions binaires (score > 0) correspondent aux prédictions précédentes: {coherence}\")\n",
|
||||
"\n",
|
||||
"print(f\"\\n=== Conclusion ===\")\n",
|
||||
"print(\"Les scores de décision permettent de comprendre la 'confiance' du modèle:\")\n",
|
||||
"print(\"• Plus le score est élevé, plus le modèle est confiant que c'est un '5'\")\n",
|
||||
"print(\"• Plus le score est faible (négatif), plus le modèle est confiant que ce n'est PAS un '5'\")\n",
|
||||
"print(\"• Le seuil par défaut de 0 sépare les deux classes\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0a4ec288",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user