Download source/src/bgc_retrieval/statistics.py from rustambekurokov/bgc-setnet: direct link, hf CLI and curl.
- Browser
- Download file 2.53 kB
-
https://huggingface.co/rustambekurokov/bgc-setnet/resolve/main/source/src/bgc_retrieval/statistics.py
- Command line
-
hf download hf://rustambekurokov/bgc-setnet/source/src/bgc_retrieval/statistics.py
-
curl -L -o statistics.py https://huggingface.co/rustambekurokov/bgc-setnet/resolve/main/source/src/bgc_retrieval/statistics.py
2.53 kB
| """Family-level uncertainty and multiple-comparison correction.""" | |
| from __future__ import annotations | |
| from collections.abc import Iterable | |
| import numpy as np | |
| import pandas as pd | |
| from scipy import stats | |
| def aggregate_draws_by_group(results: pd.DataFrame, metric_columns: Iterable[str]) -> pd.DataFrame: | |
| required = {"method", "group_id", "draw"} | |
| if missing := required.difference(results.columns): | |
| raise ValueError(f"Results missing columns: {sorted(missing)}") | |
| columns = list(metric_columns) | |
| return results.groupby(["method", "group_id"], as_index=False)[columns].mean() | |
| def hierarchical_bootstrap_ci( | |
| group_values: pd.Series, | |
| samples: int = 10000, | |
| confidence: float = 0.95, | |
| seed: int = 0, | |
| ) -> tuple[float, float]: | |
| values = group_values.dropna().to_numpy(dtype=float) | |
| if len(values) < 2: | |
| raise ValueError("At least two groups are required for a confidence interval") | |
| random_state = np.random.RandomState(seed) | |
| indices = random_state.randint(0, len(values), size=(samples, len(values))) | |
| bootstrap_means = values[indices].mean(axis=1) | |
| tail = (1.0 - confidence) / 2.0 | |
| return tuple(float(value) for value in np.quantile(bootstrap_means, [tail, 1.0 - tail])) | |
| def paired_family_test( | |
| aggregated: pd.DataFrame, | |
| method: str, | |
| baseline: str, | |
| metric: str, | |
| ) -> dict[str, float | int | str]: | |
| pivot = aggregated.pivot(index="group_id", columns="method", values=metric).dropna( | |
| subset=[method, baseline] | |
| ) | |
| if len(pivot) < 2: | |
| raise ValueError("At least two paired groups are required") | |
| differences = pivot[method] - pivot[baseline] | |
| if np.allclose(differences, 0.0): | |
| statistic, p_value = 0.0, 1.0 | |
| else: | |
| statistic, p_value = stats.wilcoxon( | |
| pivot[method], pivot[baseline], alternative="greater", zero_method="wilcox" | |
| ) | |
| return { | |
| "method": method, | |
| "baseline": baseline, | |
| "metric": metric, | |
| "groups": len(pivot), | |
| "mean_delta": float(differences.mean()), | |
| "statistic": float(statistic), | |
| "p_value": float(p_value), | |
| } | |
| def holm_adjust(p_values: Iterable[float]) -> list[float]: | |
| values = np.asarray(list(p_values), dtype=float) | |
| order = np.argsort(values) | |
| adjusted = np.empty_like(values) | |
| running = 0.0 | |
| count = len(values) | |
| for rank, index in enumerate(order): | |
| running = max(running, (count - rank) * values[index]) | |
| adjusted[index] = min(1.0, running) | |
| return adjusted.tolist() | |