Spaces:
Sleeping
Sleeping
feat: update ROC and Precision-Recall curve functions to include best model visualization
Browse files- app/training/generate_figures.py +31 -41
app/training/generate_figures.py
CHANGED
|
@@ -154,33 +154,32 @@ def fig_confusion_matrix(results: dict, y_true: np.ndarray, y_pred: np.ndarray)
|
|
| 154 |
print(" ✓ confusion_matrix.png")
|
| 155 |
|
| 156 |
|
| 157 |
-
def fig_roc_comparison(results: dict) -> None:
|
| 158 |
-
"""
|
| 159 |
fig, ax = plt.subplots(figsize=(8, 6.5))
|
| 160 |
-
colors = plt.cm.plasma(np.linspace(0.15, 0.85, 10))
|
| 161 |
-
|
| 162 |
best = results.get("_best_model", "XGBoost")
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
|
|
|
|
|
|
| 178 |
)
|
| 179 |
|
| 180 |
-
ax.plot([0, 1], [0, 1], "k:", alpha=0.3, lw=1)
|
| 181 |
ax.set_xlabel("Yanlış Pozitif Oranı / False Positive Rate")
|
| 182 |
ax.set_ylabel("Doğru Pozitif Oranı / True Positive Rate")
|
| 183 |
-
ax.set_title("ROC
|
| 184 |
ax.legend(loc="lower right", framealpha=0.85)
|
| 185 |
ax.set_xlim([0, 1])
|
| 186 |
ax.set_ylim([0, 1.02])
|
|
@@ -189,32 +188,23 @@ def fig_roc_comparison(results: dict) -> None:
|
|
| 189 |
print(" ✓ roc_curves_comparison.png")
|
| 190 |
|
| 191 |
|
| 192 |
-
def fig_pr_curves(results: dict) -> None:
|
| 193 |
-
"""Precision-Recall
|
| 194 |
fig, ax = plt.subplots(figsize=(8, 6.5))
|
| 195 |
-
colors = plt.cm.plasma(np.linspace(0.15, 0.85, 10))
|
| 196 |
-
|
| 197 |
best = results.get("_best_model", "XGBoost")
|
| 198 |
-
|
| 199 |
-
|
|
|
|
| 200 |
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
lw = 3 if name == best else 1.5
|
| 207 |
-
ls = "-" if name == best else "--"
|
| 208 |
-
ax.plot(
|
| 209 |
-
rec, prec,
|
| 210 |
-
color=colors[idx],
|
| 211 |
-
lw=lw, ls=ls,
|
| 212 |
-
label=f"{name} (AP = {ap:.4f})",
|
| 213 |
-
)
|
| 214 |
|
| 215 |
ax.set_xlabel("Duyarlılık / Recall")
|
| 216 |
ax.set_ylabel("Kesinlik / Precision")
|
| 217 |
-
ax.set_title("Precision-Recall
|
| 218 |
ax.legend(loc="lower left", framealpha=0.85)
|
| 219 |
ax.set_xlim([0, 1])
|
| 220 |
ax.set_ylim([0, 1.02])
|
|
|
|
| 154 |
print(" ✓ confusion_matrix.png")
|
| 155 |
|
| 156 |
|
| 157 |
+
def fig_roc_comparison(results: dict, y_true: np.ndarray, y_prob: np.ndarray) -> None:
|
| 158 |
+
"""ROC curve for best model + reference diagonal."""
|
| 159 |
fig, ax = plt.subplots(figsize=(8, 6.5))
|
|
|
|
|
|
|
| 160 |
best = results.get("_best_model", "XGBoost")
|
| 161 |
+
fpr, tpr, _ = roc_curve(y_true, y_prob)
|
| 162 |
+
roc_auc = auc(fpr, tpr)
|
| 163 |
+
|
| 164 |
+
ax.plot(fpr, tpr, color=PALETTE["primary"], lw=3,
|
| 165 |
+
label=f"{best} (AUC = {roc_auc:.4f})")
|
| 166 |
+
ax.fill_between(fpr, tpr, alpha=0.15, color=PALETTE["primary"])
|
| 167 |
+
ax.plot([0, 1], [0, 1], "k:", alpha=0.5, lw=1.5, label="Rastgele / Random")
|
| 168 |
+
|
| 169 |
+
# Add other models as AUC markers
|
| 170 |
+
for name, data in results.items():
|
| 171 |
+
if name.startswith("_") or not isinstance(data, dict) or name == best:
|
| 172 |
+
continue
|
| 173 |
+
auc_v = data.get("roc_auc", 0)
|
| 174 |
+
ax.annotate(
|
| 175 |
+
f"{name}: AUC={auc_v:.3f}",
|
| 176 |
+
xy=(0.45, 0.05 + 0.04 * list(results.keys()).index(name)),
|
| 177 |
+
fontsize=8, alpha=0.7,
|
| 178 |
)
|
| 179 |
|
|
|
|
| 180 |
ax.set_xlabel("Yanlış Pozitif Oranı / False Positive Rate")
|
| 181 |
ax.set_ylabel("Doğru Pozitif Oranı / True Positive Rate")
|
| 182 |
+
ax.set_title("ROC Eğrisi — En İyi Model (5-fold CV)", fontsize=13, fontweight="bold")
|
| 183 |
ax.legend(loc="lower right", framealpha=0.85)
|
| 184 |
ax.set_xlim([0, 1])
|
| 185 |
ax.set_ylim([0, 1.02])
|
|
|
|
| 188 |
print(" ✓ roc_curves_comparison.png")
|
| 189 |
|
| 190 |
|
| 191 |
+
def fig_pr_curves(results: dict, y_true: np.ndarray, y_prob: np.ndarray) -> None:
|
| 192 |
+
"""Precision-Recall curve for best model."""
|
| 193 |
fig, ax = plt.subplots(figsize=(8, 6.5))
|
|
|
|
|
|
|
| 194 |
best = results.get("_best_model", "XGBoost")
|
| 195 |
+
prec, rec, _ = precision_recall_curve(y_true, y_prob)
|
| 196 |
+
ap = average_precision_score(y_true, y_prob)
|
| 197 |
+
baseline = y_true.mean()
|
| 198 |
|
| 199 |
+
ax.plot(rec, prec, color=PALETTE["primary"], lw=3,
|
| 200 |
+
label=f"{best} (AP = {ap:.4f})")
|
| 201 |
+
ax.fill_between(rec, prec, alpha=0.15, color=PALETTE["primary"])
|
| 202 |
+
ax.axhline(baseline, color="k", linestyle=":", alpha=0.5,
|
| 203 |
+
label=f"Baseline = {baseline:.3f}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
|
| 205 |
ax.set_xlabel("Duyarlılık / Recall")
|
| 206 |
ax.set_ylabel("Kesinlik / Precision")
|
| 207 |
+
ax.set_title("Precision-Recall Eğrisi — En İyi Model", fontsize=13, fontweight="bold")
|
| 208 |
ax.legend(loc="lower left", framealpha=0.85)
|
| 209 |
ax.set_xlim([0, 1])
|
| 210 |
ax.set_ylim([0, 1.02])
|