Skip to content

v-code01/dbflip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dbflip

torchmetrics declares DaviesBouldinScore.higher_is_better = True. The Davies-Bouldin index is lower-is-better: it decreases as clusters get tighter and better separated, with a minimum of 0. So the flag says a higher Davies-Bouldin score is better, the opposite of what the index means, and MetricTracker, which reads the flag to pick the best epoch, selects the worst clustering.

The contradiction

In torchmetrics/clustering/davies_bouldin_score.py:

  • higher_is_better: bool = True (line 79)
  • plot_lower_bound: float = 0.0 (line 81)
  • the docstring is copied verbatim from Calinski-Harabasz: line 51 "The score is higher when clusters are dense and well separated," and line 62 describes the output as "Calinski Harabasz Score."

The index itself, DB = (1/n) sum_i max_{j != i} (S_i + S_j) / D_ij with S the intra-cluster scatter and D the centroid distance, is minimized by good clustering, and scikit-learn documents it as "the minimum score is zero, with lower values indicating better clustering." A plot_lower_bound of 0.0 is the shape of a minimized metric, which agrees with lower-is-better and disagrees with the higher_is_better=True flag on the same class. The sibling CalinskiHarabaszScore also declares higher_is_better=True, but that one is correct, so Davies-Bouldin is the odd one out: the flag and the docstring rode in together from a copy of Calinski-Harabasz.

metric direction higher_is_better correct
Calinski-Harabasz higher is better True yes
Davies-Bouldin lower is better (min 0) True no

What it does

MetricTracker sets maximize = metric.higher_is_better (wrappers/tracker.py:126) and its best_metric() returns the epoch with the largest value when maximize is True. Tracking Davies-Bouldin to choose a checkpoint should minimize it; with the wrong flag the tracker maximizes it:

Davies-Bouldin: well-separated = 0.026, overlapping = 5.939
MetricTracker (maximize = higher_is_better = True) picks: epoch_bad
actually best (lowest DB):                                epoch_good

Any run that tracks DaviesBouldinScore across epochs or models and lets MetricTracker pick the best gets the worst clustering selected.

Layout

  • excerpt.py: the higher_is_better and plot_lower_bound declarations and the copied docstring lines, quoted with line numbers (Apache-2.0), plus the MetricTracker flag use.
  • direction.py: the metric is lower-is-better, so the flag should be False; the plot_lower_bound agrees with lower-is-better and the Calinski-Harabasz sibling is correct.
  • consequence.py: the Davies-Bouldin index from its definition and the tracker's own selection, showing the worst clustering picked as best.
  • test_dbflip.py: lower DB is better, the flag contradicts the definition, the lower bound matches a minimized metric, the sibling is correct, and the tracker selects the worst clustering.

Reproduce

python direction.py
python consequence.py
python test_dbflip.py

The declarations are quoted from the master branch; the fix is higher_is_better = False for DaviesBouldinScore, and repairing the copied docstring.

About

torchmetrics declares DaviesBouldinScore.higher_is_better=True but the Davies-Bouldin index is lower-is-better (min 0), so MetricTracker selects the worst clustering as best (flag+docstring copied from Calinski-Harabasz)

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages