Spaces:
Running
Running
Deploy Space: update src
Browse files- src/utils.py +67 -45
src/utils.py
CHANGED
|
@@ -175,6 +175,21 @@ def format_number(value):
|
|
| 175 |
return f"{number:.2f}"
|
| 176 |
|
| 177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
def aggregate_gmean(series: pd.Series) -> float:
|
| 179 |
values = pd.to_numeric(series, errors="coerce").dropna()
|
| 180 |
values = values[np.isfinite(values) & (values >= 0.0)]
|
|
@@ -192,7 +207,8 @@ def format_df(df: pd.DataFrame) -> pd.DataFrame:
|
|
| 192 |
formatted = df.copy()
|
| 193 |
for col in formatted.columns:
|
| 194 |
if pd.api.types.is_numeric_dtype(formatted[col]):
|
| 195 |
-
|
|
|
|
| 196 |
return formatted
|
| 197 |
|
| 198 |
|
|
@@ -419,8 +435,9 @@ def load_gift_aggregate_table(
|
|
| 419 |
table["Coverage"] = table["coverage"].map(
|
| 420 |
lambda value: "n/a" if pd.isna(value) else f"{100.0 * float(value):.2f}%"
|
| 421 |
)
|
| 422 |
-
for metric in ("MSE", "CRPS"
|
| 423 |
table[metric] = pd.to_numeric(table[metric], errors="coerce").map(format_number)
|
|
|
|
| 424 |
table = table.rename(columns={dimension: label, "model": "Model"})
|
| 425 |
return table.loc[:, columns].reset_index(drop=True)
|
| 426 |
|
|
@@ -508,6 +525,7 @@ def load_live_aggregate_table(
|
|
| 508 |
)
|
| 509 |
for metric in ("MSE", "RMSE", "MAPE", "CRPS", "RTG", "Stability", "Improvement"):
|
| 510 |
frame[metric] = pd.to_numeric(frame[metric], errors="coerce").map(format_number)
|
|
|
|
| 511 |
else:
|
| 512 |
source_columns = [
|
| 513 |
"Rank",
|
|
@@ -531,7 +549,12 @@ def load_live_aggregate_table(
|
|
| 531 |
"pairwise_matches": "Pairwise Matches",
|
| 532 |
}
|
| 533 |
)
|
| 534 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 535 |
frame[metric] = pd.to_numeric(frame[metric], errors="coerce").map(format_number)
|
| 536 |
return frame.loc[:, columns].reset_index(drop=True)
|
| 537 |
|
|
@@ -549,8 +572,8 @@ def load_live_aggregate_metadata_md(root_dir: str = "results") -> str:
|
|
| 549 |
f"**Up to now:** {metadata.get('num_models', 0)} models, "
|
| 550 |
f"{metadata.get('num_datasets', 0)} datasets, and "
|
| 551 |
f"{metadata.get('num_unique_releases', 0)} distinct future releases. "
|
| 552 |
-
"
|
| 553 |
-
"
|
| 554 |
f"{generated}."
|
| 555 |
)
|
| 556 |
|
|
@@ -772,7 +795,7 @@ def _read_rank_history(path: Path, date_col: str) -> pd.DataFrame:
|
|
| 772 |
return pd.DataFrame(columns=[date_col] + _RANK_COLS)
|
| 773 |
for col in _RANK_COLS:
|
| 774 |
if col in df.columns:
|
| 775 |
-
df[col] = pd.to_numeric(df[col], errors="coerce").map(
|
| 776 |
if date_col in df.columns:
|
| 777 |
df = df.sort_values(date_col)
|
| 778 |
present = [c for c in [date_col] + _RANK_COLS if c in df.columns]
|
|
@@ -1002,26 +1025,44 @@ def _today_start_utc8() -> datetime:
|
|
| 1002 |
|
| 1003 |
def get_dataset_last_eval_time(ds_base: str, root_dir: str = "results") -> datetime | None:
|
| 1004 |
latest_dt: datetime | None = None
|
| 1005 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1006 |
for model_dir in Path(root_dir).iterdir():
|
| 1007 |
if not model_dir.is_dir():
|
| 1008 |
continue
|
| 1009 |
-
|
| 1010 |
-
if not
|
| 1011 |
continue
|
| 1012 |
-
|
| 1013 |
-
|
| 1014 |
-
|
| 1015 |
-
|
| 1016 |
-
|
| 1017 |
-
|
| 1018 |
-
|
| 1019 |
-
|
| 1020 |
-
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
|
| 1024 |
-
|
|
|
|
|
|
|
| 1025 |
return latest_dt
|
| 1026 |
|
| 1027 |
|
|
@@ -1076,30 +1117,11 @@ def make_domain_pie_chart(root_dir: str = "results") -> object | None:
|
|
| 1076 |
except Exception:
|
| 1077 |
pass
|
| 1078 |
|
| 1079 |
-
# Fallback to
|
| 1080 |
if not timestamp_counts:
|
| 1081 |
-
|
| 1082 |
-
|
| 1083 |
-
|
| 1084 |
-
continue
|
| 1085 |
-
forecasts_dir = model_dir / "forecasts"
|
| 1086 |
-
if not forecasts_dir.is_dir():
|
| 1087 |
-
continue
|
| 1088 |
-
for fp in forecasts_dir.glob("*.json"):
|
| 1089 |
-
try:
|
| 1090 |
-
snap = json.loads(fp.read_text())
|
| 1091 |
-
except Exception:
|
| 1092 |
-
continue
|
| 1093 |
-
ds_full = snap.get("dataset", "")
|
| 1094 |
-
ds_base = ds_full.split("/")[0]
|
| 1095 |
-
if ds_base in seen_datasets:
|
| 1096 |
-
continue
|
| 1097 |
-
seen_datasets.add(ds_base)
|
| 1098 |
-
|
| 1099 |
-
domain = get_domain(ds_base)
|
| 1100 |
-
n_ts = len(snap.get("context", [])) + len(snap.get("actuals", []))
|
| 1101 |
-
timestamp_counts[domain] = timestamp_counts.get(domain, 0) + n_ts
|
| 1102 |
-
domain_datasets.setdefault(domain, set()).add(dataset_short_name(ds_base))
|
| 1103 |
|
| 1104 |
if not timestamp_counts:
|
| 1105 |
return None
|
|
|
|
| 175 |
return f"{number:.2f}"
|
| 176 |
|
| 177 |
|
| 178 |
+
def format_rank_number(value):
|
| 179 |
+
"""Format rank-like columns as positive integers for leaderboard display."""
|
| 180 |
+
if pd.isna(value):
|
| 181 |
+
return "n/a"
|
| 182 |
+
number = float(value)
|
| 183 |
+
if not np.isfinite(number):
|
| 184 |
+
return "n/a"
|
| 185 |
+
return str(max(1, int(round(number))))
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def _is_rank_display_column(column: object) -> bool:
|
| 189 |
+
name = str(column)
|
| 190 |
+
return "Rank" in name and name != RANK_SCORE_COLUMN
|
| 191 |
+
|
| 192 |
+
|
| 193 |
def aggregate_gmean(series: pd.Series) -> float:
|
| 194 |
values = pd.to_numeric(series, errors="coerce").dropna()
|
| 195 |
values = values[np.isfinite(values) & (values >= 0.0)]
|
|
|
|
| 207 |
formatted = df.copy()
|
| 208 |
for col in formatted.columns:
|
| 209 |
if pd.api.types.is_numeric_dtype(formatted[col]):
|
| 210 |
+
formatter = format_rank_number if _is_rank_display_column(col) else format_number
|
| 211 |
+
formatted[col] = formatted[col].map(formatter)
|
| 212 |
return formatted
|
| 213 |
|
| 214 |
|
|
|
|
| 435 |
table["Coverage"] = table["coverage"].map(
|
| 436 |
lambda value: "n/a" if pd.isna(value) else f"{100.0 * float(value):.2f}%"
|
| 437 |
)
|
| 438 |
+
for metric in ("MSE", "CRPS"):
|
| 439 |
table[metric] = pd.to_numeric(table[metric], errors="coerce").map(format_number)
|
| 440 |
+
table["Rank"] = pd.to_numeric(table["Rank"], errors="coerce").map(format_rank_number)
|
| 441 |
table = table.rename(columns={dimension: label, "model": "Model"})
|
| 442 |
return table.loc[:, columns].reset_index(drop=True)
|
| 443 |
|
|
|
|
| 525 |
)
|
| 526 |
for metric in ("MSE", "RMSE", "MAPE", "CRPS", "RTG", "Stability", "Improvement"):
|
| 527 |
frame[metric] = pd.to_numeric(frame[metric], errors="coerce").map(format_number)
|
| 528 |
+
frame["Rank"] = pd.to_numeric(frame["Rank"], errors="coerce").map(format_rank_number)
|
| 529 |
else:
|
| 530 |
source_columns = [
|
| 531 |
"Rank",
|
|
|
|
| 549 |
"pairwise_matches": "Pairwise Matches",
|
| 550 |
}
|
| 551 |
)
|
| 552 |
+
frame["Rank"] = pd.to_numeric(frame["Rank"], errors="coerce").map(format_rank_number)
|
| 553 |
+
frame["Average Rank"] = pd.to_numeric(
|
| 554 |
+
frame["Average Rank"],
|
| 555 |
+
errors="coerce",
|
| 556 |
+
).map(format_rank_number)
|
| 557 |
+
for metric in ("Win Rate", "Elo"):
|
| 558 |
frame[metric] = pd.to_numeric(frame[metric], errors="coerce").map(format_number)
|
| 559 |
return frame.loc[:, columns].reset_index(drop=True)
|
| 560 |
|
|
|
|
| 572 |
f"**Up to now:** {metadata.get('num_models', 0)} models, "
|
| 573 |
f"{metadata.get('num_datasets', 0)} datasets, and "
|
| 574 |
f"{metadata.get('num_unique_releases', 0)} distinct future releases. "
|
| 575 |
+
"Metrics are stored without forecasts or ground truth; RTG is relative to "
|
| 576 |
+
"matched Seasonal-Naive MSE. **Generated:** "
|
| 577 |
f"{generated}."
|
| 578 |
)
|
| 579 |
|
|
|
|
| 795 |
return pd.DataFrame(columns=[date_col] + _RANK_COLS)
|
| 796 |
for col in _RANK_COLS:
|
| 797 |
if col in df.columns:
|
| 798 |
+
df[col] = pd.to_numeric(df[col], errors="coerce").map(format_rank_number)
|
| 799 |
if date_col in df.columns:
|
| 800 |
df = df.sort_values(date_col)
|
| 801 |
present = [c for c in [date_col] + _RANK_COLS if c in df.columns]
|
|
|
|
| 1025 |
|
| 1026 |
def get_dataset_last_eval_time(ds_base: str, root_dir: str = "results") -> datetime | None:
|
| 1027 |
latest_dt: datetime | None = None
|
| 1028 |
+
|
| 1029 |
+
history_path = Path(root_dir) / "eval_history.jsonl"
|
| 1030 |
+
if history_path.exists():
|
| 1031 |
+
try:
|
| 1032 |
+
with history_path.open(encoding="utf-8") as handle:
|
| 1033 |
+
for line in handle:
|
| 1034 |
+
if not line.strip():
|
| 1035 |
+
continue
|
| 1036 |
+
entry = json.loads(line)
|
| 1037 |
+
if _dataset_key(entry.get("dataset", "")) != _dataset_key(ds_base):
|
| 1038 |
+
continue
|
| 1039 |
+
dt = _parse_timestamp(entry.get("evaluated_at"))
|
| 1040 |
+
if dt is not None and (latest_dt is None or dt > latest_dt):
|
| 1041 |
+
latest_dt = dt
|
| 1042 |
+
except Exception:
|
| 1043 |
+
pass
|
| 1044 |
+
|
| 1045 |
for model_dir in Path(root_dir).iterdir():
|
| 1046 |
if not model_dir.is_dir():
|
| 1047 |
continue
|
| 1048 |
+
meta_path = model_dir / "online_meta.json"
|
| 1049 |
+
if not meta_path.exists():
|
| 1050 |
continue
|
| 1051 |
+
try:
|
| 1052 |
+
meta = json.loads(meta_path.read_text())
|
| 1053 |
+
except Exception:
|
| 1054 |
+
continue
|
| 1055 |
+
matched = False
|
| 1056 |
+
for item in meta.get("datasets", []):
|
| 1057 |
+
raw_name = str(item.get("dataset", ""))
|
| 1058 |
+
if _dataset_key(raw_name) == _dataset_key(ds_base) or ds_base.lower() in raw_name.lower():
|
| 1059 |
+
matched = True
|
| 1060 |
+
break
|
| 1061 |
+
if not matched:
|
| 1062 |
+
continue
|
| 1063 |
+
dt = _parse_timestamp(meta.get("evaluated_at"))
|
| 1064 |
+
if dt is not None and (latest_dt is None or dt > latest_dt):
|
| 1065 |
+
latest_dt = dt
|
| 1066 |
return latest_dt
|
| 1067 |
|
| 1068 |
|
|
|
|
| 1117 |
except Exception:
|
| 1118 |
pass
|
| 1119 |
|
| 1120 |
+
# Fallback to one count per current dataset if history is unavailable.
|
| 1121 |
if not timestamp_counts:
|
| 1122 |
+
for ds_base, domain in domain_map.items():
|
| 1123 |
+
timestamp_counts[domain] = timestamp_counts.get(domain, 0) + 1
|
| 1124 |
+
domain_datasets.setdefault(domain, set()).add(dataset_short_name(ds_base))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1125 |
|
| 1126 |
if not timestamp_counts:
|
| 1127 |
return None
|