A machine reports several sensor values every minute. The maintenance team has a log normal of readings taken while the machine was known to be healthy, and wants to check new readings against it.
Write zscore_alarm(normal, readings, limit) that returns one entry per new reading:
- From
normalonly, compute every feature's mean and standard deviation (divide byninside the square root). - For a new reading, compute every feature's absolute z-score
|x - mean| / sd. - If the largest of them is greater than
limit, the entry is the index of that feature (the lowest index if several share the largest value); otherwise the entry isNone.
machine_log(n, seed) gives normal readings [temperature, vibration, current] of the kind the tests use; it is available in your code.
Examples
Input: normal = [[50, 5.0], [54, 6.0], [46, 4.0], [52, 5.5], [48, 4.5]],
readings = [[51, 5.1], [62, 5.0], [50, 1.0], [58, 7.5]], limit = 3
Output: [None, 0, 1, 1]
Explanation: the means are 50 and 5, the standard deviations 2.828 and 0.7071. [62, 5.0] has
z-scores 4.24 and 0; [58, 7.5] has 2.83 and 3.54, so the vibration raised the alarm.
Input: normal = machine_log(200, 1),
readings = [[50.2, 4.9, 13.0], [75.0, 8.3, 19.0], [59.0, 2.6, 17.5], [43.0, 7.5, 9.0]], limit = 3
Output: [None, 0, None, None]
Explanation: the third and fourth readings are strange combinations (hot but barely vibrating,
cool but shaking hard), yet every value on its own is in the normal range.
Constraints
2 <= len(normal) <= 5000, 1 to 10 features, no feature is constant innormal0 <= len(readings) <= 5000,limit > 0
Goals
- Learn what normal looks like from readings of normal operation only
- Score new readings feature by feature with z-scores
- Report which feature is furthest from normal when a reading is flagged