Functional Weave
Code in TypeScript

monitor.anomaly@1.0.0

vectors.json

4,453 bytes · view raw

[
  {"name": "stddev: mean 5, sd 2, value 12 is z 3.5, above 3.0", "args": [[2, 4, 4, 4, 5, 5, 7, 9], 12, "stddev", 300], "expect": {"anomaly": true, "direction": "high", "centerMilli": 5000, "spreadMilli": 2000, "scoreHundredths": 350}},
  {"name": "stddev: z of exactly 3.0 against a threshold of 3.0 is not an anomaly", "args": [[2, 4, 4, 4, 5, 5, 7, 9], 11, "stddev", 300], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 5000, "spreadMilli": 2000, "scoreHundredths": 300}},
  {"name": "stddev: z of exactly -3.0 is not an anomaly either", "args": [[2, 4, 4, 4, 5, 5, 7, 9], -1, "stddev", 300], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 5000, "spreadMilli": 2000, "scoreHundredths": 300}},
  {"name": "stddev: a low outlier is low", "args": [[2, 4, 4, 4, 5, 5, 7, 9], -2, "stddev", 300], "expect": {"anomaly": true, "direction": "low", "centerMilli": 5000, "spreadMilli": 2000, "scoreHundredths": 350}},
  {"name": "stddev: an irrational standard deviation, sqrt(20)/4, floored to 1118", "args": [[1, 2, 3, 4], 10, "stddev", 300], "expect": {"anomaly": true, "direction": "high", "centerMilli": 2500, "spreadMilli": 1118, "scoreHundredths": 670}},
  {"name": "stddev: a mean of 2/3 rounds half up to 667", "args": [[0, 1, 1], 1, "stddev", 200], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 667, "spreadMilli": 471, "scoreHundredths": 70}},
  {"name": "stddev: a flat history has no spread, so any other value is an anomaly with no score", "args": [[5, 5, 5], 6, "stddev", 300], "expect": {"anomaly": true, "direction": "high", "centerMilli": 5000, "spreadMilli": 0, "scoreHundredths": null}},
  {"name": "stddev: a flat history and the same value is normal", "args": [[5, 5, 5], 5, "stddev", 300], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 5000, "spreadMilli": 0, "scoreHundredths": null}},
  {"name": "stddev: values near 10^9 whose squares pass 2^53 are still exact", "args": [[1000000000, 1000000002], 1000000010, "stddev", 300], "expect": {"anomaly": true, "direction": "high", "centerMilli": 1000000001000, "spreadMilli": 1000, "scoreHundredths": 900}},
  {"name": "stddev: one spike in the history inflates the sd and hides a new one", "args": [[10, 12, 11, 13, 50], 30, "stddev", 350], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 19200, "spreadMilli": 15432, "scoreHundredths": 69}},
  {"name": "mad: the same spike barely moves the median and MAD, so 30 is an anomaly", "args": [[10, 12, 11, 13, 50], 30, "mad", 350], "expect": {"anomaly": true, "direction": "high", "centerMilli": 12000, "spreadMilli": 1000, "scoreHundredths": 1214}},
  {"name": "mad: median 12, MAD 1, value 18 is M = 4.047", "args": [[10, 12, 11, 13, 50], 18, "mad", 350], "expect": {"anomaly": true, "direction": "high", "centerMilli": 12000, "spreadMilli": 1000, "scoreHundredths": 404}},
  {"name": "mad: value 16 is M = 2.698, under 3.5", "args": [[10, 12, 11, 13, 50], 16, "mad", 350], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 12000, "spreadMilli": 1000, "scoreHundredths": 269}},
  {"name": "mad: an even history has a half-way median 2.5; value 8 is M = 3.70975", "args": [[4, 1, 3, 2], 8, "mad", 350], "expect": {"anomaly": true, "direction": "high", "centerMilli": 2500, "spreadMilli": 1000, "scoreHundredths": 370}},
  {"name": "mad: a fractional MAD of 1.5 and a low outlier", "args": [[1, 2, 4, 8], -3, "mad", 250], "expect": {"anomaly": true, "direction": "low", "centerMilli": 3000, "spreadMilli": 1500, "scoreHundredths": 269}},
  {"name": "mad: more than half the history equal gives MAD 0; a different value is an anomaly", "args": [[7, 7, 7, 9], 8, "mad", 350], "expect": {"anomaly": true, "direction": "high", "centerMilli": 7000, "spreadMilli": 0, "scoreHundredths": null}},
  {"name": "mad: MAD 0 and the median itself is normal", "args": [[7, 7, 7, 9], 7, "mad", 350], "expect": {"anomaly": false, "direction": "normal", "centerMilli": 7000, "spreadMilli": 0, "scoreHundredths": null}},
  {"name": "a history of one value is an error", "args": [[5], 5, "stddev", 300], "expectError": "history must have at least 2 values, received 1"},
  {"name": "a threshold of zero is an error", "args": [[1, 2], 5, "mad", 0], "expectError": "thresholdHundredths must be at least 1, received 0"},
  {"name": "an unknown method is an error", "args": [[1, 2], 5, "iqr", 300], "expectError": "unknown anomaly method: iqr"}
]