Closed cboulay closed 1 year ago
Admittedly, my ewm implementation was pulled from a stack overflow article and I haven't diligently checked it for correctness. It's definitely not implemented as optimally as it could be, and its a VERY difficult read due to its reliance on another window unit and complicated math. Of all the existing signal processing units in ezmsg-sigproc, it's the one that could use the most TLC.
Here's river
's AdaptiveStandardScaler
: https://github.com/online-ml/river/blob/main/river/preprocessing/scale.py#L545-L555
(
Just a quick primer on river
to help you read that code: they expect the input to this function to be a single sample in a dict, with channels | features as keys and float values. i.e.,:
{'ch1': 123.4, 'ch2': 567.8, ...}
)
You'd have to dive in a bit if you want to find their exponentially-weighted mean and var update
functions. They come from a rust library called watermill
. Here is the mean update code. It's just mean = alpha * new_sample + (1 - alpha) * mean
Edit:
For variance it's a bit more complicated. The mean and mean-of-squares are both updated just as above, and then the resultant var is mean-of-squares - square(mean)
.
Anyway, the key point is that EWM doesn't require a window.
Closed with #52
But I'll refer back to this when making an AdaptiveStandardScaler unit.
The following snippet right above the
def ewma
can make it work, but I had putting a while loop inside a function that gets called frequently. I'm sure there's a better way.And this would have to be accompanied by removing the
, np.newaxis]
slicing on scale_arr within the function.