Second Opinion

History detector

The history detector flags readings that differ from their own series' recent history or that trigger a data-quality rule. It runs independently of the AI layer and never compares plants with each other. A flag is a candidate for investigation, not a diagnosis.

See the methodology for the reasoning behind each choice.

Run #

After a complete data preparation, from the repository root and with a new, empty output directory:

python src/history_detector/history_detector.py --prepared data/tai/prepared_history --output data/tai/history_oxygen --measurement oxygen

To run every group together with the AI layer, use the pipeline driver.

Measurement groups #

--measurement selects one group per run: influent_volume (default), oxygen, ammonium, nitrate, suspended_solids or temperature. Descriptions and input types are matched case-insensitively. Units are matched exactly and never converted. The exact filters are listed in the methodology.

Algorithm #

Options #

Option Default Meaning
--window-days 28 History window length
--minimum-history 14 Valid days required to score
--scale-floor-fraction 0.05 Spread floor as a fraction of the median
--clip-limit 3.5 History clipping in spreads; 0 disables clipping
--stuck-days 7 Consecutive equal values for the stuck rule
--no-rules off Disable the data-quality rules
--calibration-end 2023-12-31 Last date used to calibrate thresholds
--target-flag-rate 0.01 Assumed review workload used for calibration
--threshold none A fixed threshold instead of calibration
--case-gap-days 1 Unflagged days allowed inside one case
--max-points none Smoke run on the first N selected points (marked smoke_run_partial)

Outputs #

history_days is blank for observations rejected before a window was built, and zero when an eligible observation had no usable history.

Artificial-fault evaluation #

python src/history_detector/synthetic_faults.py --prepared data/tai/prepared_history --output data/tai/faults_influent --measurement influent_volume --sample 100

This copies a seeded sample of series, injects one fault per copy in the held-out year (a spike of 6 spreads, a 3-day dropout, a 10-day stuck value or a 28-day drift to 4 spreads), and scores each copy with three variants: legacy (no floor, no clipping, no rules, fixed threshold 3.5), revised (current defaults) and revised_no_clip. It also reports the workload on unmodified data. These results describe artificial cases only.

Code: src/history_detector/. Tests: tests/test_history_detector.py.

Edit this page on GitHub ↗

Second Opinion · Built for TAI / Z-infoBack to top ↑