Source code for moosefs.metrics.stability_metrics

from itertools import combinations

from moosefs.core.novovicova import StabilityNovovicova


[docs] def compute_stability_metrics(features_list: list) -> float: """Compute stability SH(S) across selections. Args: features_list: Selected feature names per selector. Returns: Stability in [0, 1]. """ return StabilityNovovicova(features_list).compute_stability()
[docs] def _jaccard(a: set, b: set) -> float: """Return Jaccard similarity, handling empty sets as 1.0 if both empty.""" return len(a & b) / len(a | b) if a | b else 1.0
[docs] def diversity_agreement(selectors: list, merged: list, alpha: float = 0.5) -> float: """Blend diversity and agreement into a single score. Args: selectors: List of selected feature lists (one per selector). merged: Merged/core feature names for the group. alpha: Weight on agreement (0 → pure diversity, 1 → pure agreement). Returns: Score in [0, 1] (higher is better). """ k = len(selectors) if k < 2: return 0.0 # cannot measure diversity with a single selector sets = [set(s) for s in selectors] core = set(merged) # 1) diversity (average Jaccard *dissimilarity* across selector pairs) pair_dis = [ 1.0 - _jaccard(sets[i], sets[j]) for i, j in combinations(range(k), 2) ] diversity = sum(pair_dis) / len(pair_dis) # 2) agreement (mean similarity of each selector to the core) agree = sum(_jaccard(s, core) for s in sets) / k # 3) linear blend return (1.0 - alpha) * diversity + alpha * agree