I've built a number of anomaly detectors for streaming data. Here's what I would suggest:
First, consider each of your 30 features (signals) independently, i.e., build an unsupervised anomaly detector for each feature and run them in parallel. For a given component, I would:
- create bins for the values, e.g., if $x$ is in range [0,100], maybe make 10 bins [0,10), [10, 20), .. Or for something like temp, maybe your bins are [0,70), [70, 85), [85, 95), [95, 100), [100, 140), [140, infinity). Varying the width of the bins may help with some dominating all of the data. Since you're looking for anomalies, you will want the bins to be crafted so you can have less likely bins than others. On the other hand you don't want bins that never occur and ones that always occur.
- create a multinomial (a die) with the probability of a new data feature/signal observation landing in each bin. To do this, before you see any data, instantiate the bin count to 1 for all bins and store the denominator as n (number of bins).
- given a new observation of the signal, you will compute its p-value, then increment the count of the bin it landed in and the denominator.
E.g., suppose we have three bins, $b1, b2, b3$. We initialize
counts = {b_1: 1, b_2: 1, b_3: 1}
n = 3
This means the multinomial when starting is $p(bj) = 1/3 $ for $j = 1,2,3$.
def p(b): return counts[b]/n
Suppose we see new data (signal) with value $x1$ and it lands in bin $b2$. First, we compute the p-value$(b_2 = \sum_{\{j:p(b_j)<= p(b_2)\}} p(b_j) = 1$ (b/c all bins have the same probability at start). Next we'd increment the count of $b_2, n$:
counts[b_2] += 1
n+=1
Second, suppose we see a second value $x_2$ that lands in bin $b_3$. Then we'd repeat the previous paragraph, computing p_value$(b_3)$ (and you'll get 2/3), and incrementing bin b_2
's count and the n
.
Finally, those signals with low p-value are the anomalies.
This has lots of advantages: your p-values are comparable across all these different signals, and across time (note that your distribution is changing in time); it is fast and easy to implement. you can alert or look back over historical data;
These papers describe this workflow or an application of it in more detail: