Rthur2003 commited on
Commit
ca749ec
·
1 Parent(s): 0ea8f54

feat: update ROC and Precision-Recall curve functions to include best model visualization

Browse files
Files changed (1) hide show
  1. 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
- """All models ROC curves overlaid."""
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
- items = [(k, v) for k, v in results.items() if not k.startswith("_") and isinstance(v, dict)]
164
- items.sort(key=lambda x: x[1].get("roc_auc", 0), reverse=True)
165
-
166
- for idx, (name, data) in enumerate(items):
167
- y_true = np.array(data["y_true"])
168
- y_prob = np.array(data["y_prob"])
169
- fpr, tpr, _ = roc_curve(y_true, y_prob)
170
- roc_auc = auc(fpr, tpr)
171
- lw = 3 if name == best else 1.5
172
- ls = "-" if name == best else "--"
173
- ax.plot(
174
- fpr, tpr,
175
- color=colors[idx],
176
- lw=lw, ls=ls,
177
- label=f"{name} (AUC = {roc_auc:.4f})",
 
 
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 Eğrileri — Model Karşılaştırması", fontsize=13, fontweight="bold")
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 curves — critical for imbalanced classes."""
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
- items = [(k, v) for k, v in results.items() if not k.startswith("_") and isinstance(v, dict)]
199
- items.sort(key=lambda x: x[1].get("roc_auc", 0), reverse=True)
 
200
 
201
- for idx, (name, data) in enumerate(items):
202
- y_true = np.array(data["y_true"])
203
- y_prob = np.array(data["y_prob"])
204
- prec, rec, _ = precision_recall_curve(y_true, y_prob)
205
- ap = average_precision_score(y_true, y_prob)
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 Eğrileri", fontsize=13, fontweight="bold")
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ğrisiEn İ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])