pub struct SpectralResidual {
pub averaging_window: usize,
pub judgement_window: usize,
pub threshold: f64,
pub min_zscore: f64,
pub sensitivity: f64,
pub batch_size: Option<usize>,
}Expand description
Spectral residual anomaly scorer.
Built with SpectralResidual::new (the defaults of Ren et al. 2019) and
adjusted with the with_* methods; run with SpectralResidual::analyze.
Fields§
§averaging_window: usizeWidth of the moving average applied to the log amplitude spectrum
(q in Ren et al.; default 3).
judgement_window: usizeHow many preceding saliency values a point is compared against
(z; default 40).
threshold: f64Score above which a point is an anomaly (τ; default 3).
min_zscore: f64Minimum |value − mean| / std of the point against the judgement
window before it, for it to be an anomaly (default 1.5), so that
saliency alone does not flag noise on a flat series. A window with no
spread passes any departure from its level.
sensitivity: f64Coverage of the band around the expected value, in percent (default 70): its half-width is the normal quantile for that two-sided coverage times the robust spread of the non-anomalous residuals.
batch_size: Option<usize>Process the series in consecutive batches of this many points instead
of at once (default None). Long series with slow drift are scored
against their local context this way; the last batch absorbs a short
remainder.
Implementations§
Source§impl SpectralResidual
impl SpectralResidual
Sourcepub fn new() -> Self
pub fn new() -> Self
The defaults of Ren et al. (2019): q = 3, z = 40, τ = 3, z-score gate 1.5, 70% band, no batching.
Sourcepub fn with_averaging_window(self, q: usize) -> Self
pub fn with_averaging_window(self, q: usize) -> Self
Sets the spectral averaging window (≥ 1).
Sourcepub fn with_judgement_window(self, z: usize) -> Self
pub fn with_judgement_window(self, z: usize) -> Self
Sets the judgement window (≥ 1).
Sourcepub fn with_threshold(self, threshold: f64) -> Self
pub fn with_threshold(self, threshold: f64) -> Self
Sets the anomaly threshold on the score (> 0).
Sourcepub fn with_min_zscore(self, min_zscore: f64) -> Self
pub fn with_min_zscore(self, min_zscore: f64) -> Self
Sets the z-score gate (≥ 0; 0 disables it).
Sourcepub fn with_sensitivity(self, sensitivity: f64) -> Self
pub fn with_sensitivity(self, sensitivity: f64) -> Self
Sets the band coverage in percent (0 < s < 100).
Sourcepub fn with_batch_size(self, batch_size: Option<usize>) -> Self
pub fn with_batch_size(self, batch_size: Option<usize>) -> Self
Sets the batch size (≥ MIN_OBSERVATIONS), or None for one batch.
Sourcepub fn analyze(
&self,
series: &[f64],
) -> Result<Vec<SrPoint>, SpectralResidualError>
pub fn analyze( &self, series: &[f64], ) -> Result<Vec<SrPoint>, SpectralResidualError>
Scores every point of the series.
The result has one SrPoint per input point, in order.
§Errors
Returns the one condition that was not met — the option that is out of its domain, the shortfall in observations, or the position of the first non-finite value — rather than a refusal a caller has to match against the whole rulebook to interpret.
§Examples
use u_analytics::detection::{SpectralResidual, SpectralResidualError};
let mut series: Vec<f64> = (0..60).map(|t| (t as f64 * 0.3).sin()).collect();
series[40] += 4.0; // a spike
let points = SpectralResidual::new().analyze(&series).unwrap();
assert!(points[40].is_anomaly);
assert!(points[40].score > points[20].score);
// A refusal names the option it is about, the value and its domain.
let refused = SpectralResidual::new().with_threshold(0.0).analyze(&series);
assert_eq!(
refused,
Err(SpectralResidualError::OptionOutOfRange {
option: "threshold",
requirement: "a finite number > 0",
got: 0.0,
min: None,
exclusive_min: Some(0.0),
max: None,
exclusive_max: None,
})
);