|
10 | 10 | import matplotlib.pyplot as plt |
11 | 11 | import numpy as np |
12 | 12 | import yaml |
| 13 | +from cdifflib import CSequenceMatcher |
13 | 14 | from tqdm.auto import tqdm |
14 | 15 | from unidiff import PatchSet |
15 | 16 |
|
|
18 | 19 | from codeclash.games import ARENAS |
19 | 20 |
|
20 | 21 | MODELS_PATH = Path("configs/models.yaml") |
21 | | -TARGET_ROUNDS = [1, 5, 10, 15] |
| 22 | +TARGET_ROUNDS = [1, 15, 5, 10] |
22 | 23 |
|
23 | 24 |
|
24 | 25 | def get_model_arena_logs(model: str | list[str], arena: str | list[str]) -> list[Path]: |
@@ -77,6 +78,7 @@ def _compute_code_sim_difflib(diff1: PatchSet, diff2: PatchSet) -> float: |
77 | 78 | """Compute similarity score between two diffs using edit distance (0.0 = different, 1.0 = identical).""" |
78 | 79 | diff1_str = "\n".join(str(f) for f in diff1) |
79 | 80 | diff2_str = "\n".join(str(f) for f in diff2) |
| 81 | + difflib.SequenceMatcher = CSequenceMatcher |
80 | 82 | seq_matcher = difflib.SequenceMatcher(None, diff1_str, diff2_str, autojunk=False) |
81 | 83 | return seq_matcher.ratio() |
82 | 84 |
|
@@ -321,6 +323,36 @@ def plot_opponent_effect_heatmap(data_cache: str, target_round: int, output_path |
321 | 323 | if opponent in opponent_matrix[model]: |
322 | 324 | matrix[i, j] = opponent_matrix[model][opponent] |
323 | 325 |
|
| 326 | + # Calculate row averages (model consistency) |
| 327 | + row_means = np.nanmean(matrix, axis=1) |
| 328 | + model_stats = [(models[i], row_means[i]) for i in range(n_models)] |
| 329 | + model_stats_sorted = sorted(model_stats, key=lambda x: x[1], reverse=True) |
| 330 | + |
| 331 | + # Calculate column averages (opponent effect) |
| 332 | + col_means = np.nanmean(matrix, axis=0) |
| 333 | + opponent_stats = [(opponents[i], col_means[i]) for i in range(n_opponents)] |
| 334 | + opponent_stats_sorted = sorted(opponent_stats, key=lambda x: x[1], reverse=True) |
| 335 | + |
| 336 | + print(f"\n{'=' * 60}") |
| 337 | + print(f"Model Consistency Statistics (Round {target_round}):") |
| 338 | + print(f"{'=' * 60}") |
| 339 | + print(f"{'Model':<25} {'Avg Similarity'}") |
| 340 | + print(f"{'-' * 60}") |
| 341 | + for model, avg_sim in model_stats_sorted: |
| 342 | + display = MODEL_TO_DISPLAY_NAME.get(model, model) |
| 343 | + print(f"{display:<25} {avg_sim:.3f}") |
| 344 | + print(f"{'=' * 60}") |
| 345 | + |
| 346 | + print(f"\n{'=' * 60}") |
| 347 | + print(f"Opponent Effect Statistics (Round {target_round}):") |
| 348 | + print(f"{'=' * 60}") |
| 349 | + print(f"{'Opponent':<25} {'Avg Similarity'}") |
| 350 | + print(f"{'-' * 60}") |
| 351 | + for opp, avg_sim in opponent_stats_sorted: |
| 352 | + display = MODEL_TO_DISPLAY_NAME.get(opp, opp) |
| 353 | + print(f"{display:<25} {avg_sim:.3f}") |
| 354 | + print(f"{'=' * 60}\n") |
| 355 | + |
324 | 356 | # Create heatmap with blue-white-red colormap like win_rates |
325 | 357 | FONT_BOLD.set_size(14) |
326 | 358 | _, ax = plt.subplots(figsize=(6, 6)) |
|
0 commit comments