Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PushFixed function for static dataset size #10

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ To capture seasonality, the bootstrap ks test should consider an active window l

### Fence

The fence test can be configured to use custom `UpperBound` and `LowerBound` values for the fences. If no lower bound is desired, set the value of `LowerBound` to `anomalyzer.NA`.
The fence test can be configured to use custom `UpperBound` and `LowerBound` values for the fences. If no lower bound is desired, set the value of `LowerBound` to the const variable: `anomalyzer.NA`.

### Diff & Rank

Expand Down Expand Up @@ -77,6 +77,13 @@ func main() {
// by a call to the Eval method.
prob := anom.Push(8.0)
fmt.Println("Anomalous Probability:", prob)

// PushFixed method will keep the size of the Data vector constant.
// Oldest data points will be evicted as points are added.
anom2, _ := anomalyzer.NewAnomalyzer(conf, data)
prob2, _ := anom2.PushFixed(8.0)
// returns an error as second value if the array size changed unexpectantly
fmt.Println("Anomalous Probability:", prob2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Indentation here and I think "unexpectantly" -> "unexpectedly"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup!

}
```

11 changes: 11 additions & 0 deletions anomalyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ func (a *Anomalyzer) Push(x float64) float64 {
return a.Eval()
}

func (a *Anomalyzer) PushFixed(x float64) (float64, error) {
// Add data to fixed size array which will not grow
err := a.Data.PushFixed(x)
if err != nil {
return NA, err
}

// evaluate the anomalous probability
return a.Eval(), nil
}

// Return the weighted average of all statistical tests
// for anomaly detection, which yields the probability that
// the currently observed behavior is anomalous.
Expand Down
52 changes: 52 additions & 0 deletions anomalyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,58 @@ func TestAnomalyzer(t *testing.T) {
assert.Tf(t, prob > 0.5, "Anomalyzer returned a probability that was too small")
}

func TestAnomalyzerPushFixed(t *testing.T) {
conf := &AnomalyzerConf{
Sensitivity: 0.1,
UpperBound: 5,
LowerBound: 0,
ActiveSize: 1,
NSeasons: 4,
Methods: []string{"cdf", "fence", "highrank", "lowrank", "magnitude"},
}

// initialize with empty data or an actual slice of floats
data := []float64{0.1, 2.05, 1.5, 2.5, 2.6, 2.55}

anomalyzer, err := NewAnomalyzer(conf, data)
assert.Equal(t, nil, err, "Error initializing new anomalyzer")

prob, err := anomalyzer.PushFixed(8.0)
prob, err = anomalyzer.PushFixed(10.0)
prob, err = anomalyzer.PushFixed(8.0)
prob, err = anomalyzer.PushFixed(9.0)
assert.Equal(t, err, nil, "There was an error with array size")
assert.Tf(t, prob > 0.5, "Anomalyzer returned a probability that was too small")
assert.Equal(t, len(anomalyzer.Data), 6, "Array size did not stay at original size")
}

func TestAnomalyzerPushMixed(t *testing.T) {
conf := &AnomalyzerConf{
Sensitivity: 0.1,
UpperBound: 5,
LowerBound: 0,
ActiveSize: 1,
NSeasons: 4,
Methods: []string{"cdf", "fence", "highrank", "lowrank", "magnitude"},
}

// initialize with empty data or an actual slice of floats
data := []float64{0.1, 2.05, 1.5, 2.5, 2.6, 2.55}

anomalyzer, err := NewAnomalyzer(conf, data)
assert.Equal(t, nil, err, "Error initializing new anomalyzer")

prob, err := anomalyzer.PushFixed(8.0)
prob = anomalyzer.Push(10.0)
prob, err = anomalyzer.PushFixed(8.0)
prob = anomalyzer.Push(9.0)
assert.Equal(t, err, nil, "There was an error with mixing array extension")
assert.Tf(t, prob > 0.5, "Anomalyzer returned a probability that was too small")
assert.Equal(t, len(anomalyzer.Data), 8, "Array size Push* functions failed to grow Data to expected size")
assert.Equal(t, anomalyzer.Data[7], 9.0)
assert.Equal(t, anomalyzer.Data[0], 1.5, "Two values were appended, two values were popped from the array. 3rd original element should be tail.")
}

func Example() {
conf := &AnomalyzerConf{
Sensitivity: 0.1,
Expand Down