pub fn discover_shapelets(
data: &FdMatrix,
labels: &[usize],
config: &ShapeletDiscoveryConfig,
) -> Result<ShapeletSet, FdarError>Expand description
Discover a non-redundant ShapeletSet from a labeled training curve set.
Enumerates candidate subsequences over [config.min_length, config.max_length]
(exhaustively, or a deterministic seeded random sample of
config.max_candidates), scores each candidate by how well its distance
orderline separates the class labels (information gain or F-statistic per
config.quality), then greedily selects the top config.max_shapelets with
self-similarity pruning: once a shapelet from series i spanning
[start, start+length) is selected, any not-yet-selected candidate from the
same series whose range overlaps it is discarded.
data is a column-major FdMatrix with rows = curves and columns =
evaluation points; labels[i] is the integer class of curve i.
§Determinism
The result is byte-identical across runs with the same config and identical
whether or not the parallel feature is enabled.
§Errors
FdarError::InvalidDimensioniflabels.len()!= number of curves.FdarError::InvalidParameterif fewer than 2 distinct classes are present, ifmin_length < 1,min_length > max_length,max_length > ncols, or the resolvedmax_shapelets < 1.
§Examples
use fdars_core::matrix::FdMatrix;
use fdars_core::shapelet::{discover_shapelets, ShapeletDiscoveryConfig};
// Two classes of length-8 curves; class 1 carries a rising ramp in the
// middle that class 0 lacks.
let n = 8usize;
let m = 8usize;
let mut data = vec![0.0f64; n * m];
let mut labels = vec![0usize; n];
for i in 0..n {
let class1 = i % 2 == 1;
labels[i] = usize::from(class1);
for j in 0..m {
// column-major: element (i, j) at i + j*n
let base = 0.1 * (i as f64) + 0.05 * (j as f64);
let motif = if class1 && (3..6).contains(&j) { (j as f64) * 2.0 } else { 0.0 };
data[i + j * n] = base + motif;
}
}
let data = FdMatrix::from_column_major(data, n, m).unwrap();
let cfg = ShapeletDiscoveryConfig { max_shapelets: 3, ..Default::default() };
let set = discover_shapelets(&data, &labels, &cfg).unwrap();
assert!(!set.is_empty());
assert!(set.len() <= 3);