Skip to content

fix: prevent NaN from division by zero in TFT interpretation + fix headless test backend#2207

Open
haoyu-haoyu wants to merge 1 commit intosktime:mainfrom
haoyu-haoyu:fix/tft-division-by-zero-and-matplotlib-backend
Open

fix: prevent NaN from division by zero in TFT interpretation + fix headless test backend#2207
haoyu-haoyu wants to merge 1 commit intosktime:mainfrom
haoyu-haoyu:fix/tft-division-by-zero-and-matplotlib-backend

Conversation

@haoyu-haoyu
Copy link
Copy Markdown

Summary

Two independent fixes bundled together:

1. TFT Division by Zero → NaN Propagation

The TFT interpretation methods divide attention/variable-importance tensors by their sum or max. When attention values fall below 1e-5 (deliberately set to NaN at line 799), downstream sums become zero, causing 0/0 = NaN that silently corrupts all interpretation statistics.

5 locations fixed by adding .clamp(min=1e-8) to the denominator:

Line Expression Context
852 masked_op(attention, ..., op="sum") Attention renormalization
942 attention.sum(-1) plot_interpretation
959 values.sum(-1) make_selection_plot
1009 attention_occurrences.max() Attention occurrence normalization
1025 interpretation["attention"].sum() Final attention normalization

2. Matplotlib Backend for Headless Testing (fixes #2140)

Tests calling model.plot_prediction() crash on Windows/headless CI because plt.subplots() defaults to TkAgg backend, which requires Tkinter.

Fix: Add matplotlib.use("Agg") at the top of tests/conftest.py.

Test plan

  • pytest tests/ -x -q passes on Linux and Windows
  • TFT interpretation no longer produces NaN values
  • model.plot_prediction() works in headless environments

Fixes #2140

…adless test backend

Two fixes:

1. TFT interpretation functions divide attention/variable-importance
   tensors by their sum/max without guarding against zero denominators.
   When all attention values are below 1e-5 (set to NaN at line 799),
   the downstream sums become zero, producing NaN that propagates
   through all interpretation statistics.

   Add .clamp(min=1e-8) to 5 denominator expressions:
   - line 852: masked attention renormalization
   - line 942: attention weights in plot_interpretation
   - line 959: variable importance in make_selection_plot
   - line 1009: attention_occurrences normalization
   - line 1025: final attention sum normalization

2. Tests crash on Windows/headless CI with TclError because matplotlib
   defaults to TkAgg backend. Add matplotlib.use("Agg") to conftest.py
   so all test-generated plots use the non-interactive backend.

   Fixes sktime#2140

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@haoyu-haoyu haoyu-haoyu force-pushed the fix/tft-division-by-zero-and-matplotlib-backend branch from 7fd5d0e to 1923915 Compare March 18, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] : Test suite crashes on Windows/headless environments due to Matplotlib Tkinter backend

1 participant