Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Renamed to anomaly

  • Loading branch information...
commit 20b2bd77f085081b720eee3154fd66aa57e2955b 1 parent 3a5e293
Andrew Kane authored
View
2  Gemfile
@@ -1,4 +1,4 @@
source 'https://rubygems.org'
-# Specify your gem's dependencies in anomaly_detector.gemspec
+# Specify your gem's dependencies in anomaly.gemspec
gemspec
View
7 README.md
@@ -1,5 +1,4 @@
-
-# AnomalyDetector
+# Anomaly
Anomaly detection using a normal distribution.
@@ -8,7 +7,7 @@ Anomaly detection using a normal distribution.
Add this line to your application's Gemfile:
```ruby
-gem "anomaly_detector"
+gem "anomaly"
```
And then execute:
@@ -27,7 +26,7 @@ train_data = [
[0.2, 101, 2.1],
[0.5, 102, 1.6]
]
-ad = AnomalyDetector.new(train_data)
+ad = Anomaly::Detector.new(train_data)
```
That's it! Let's test for anomalies.
View
8 anomaly_detector.gemspec → anomaly.gemspec
@@ -1,19 +1,19 @@
# -*- encoding: utf-8 -*-
-require File.expand_path('../lib/anomaly_detector/version', __FILE__)
+require File.expand_path('../lib/anomaly/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Andrew Kane"]
gem.email = ["andrew@getformidable.com"]
gem.description = %q{Anomaly detection using a normal distribution.}
gem.summary = %q{Anomaly detection using a normal distribution.}
- gem.homepage = "https://github.com/ankane/anomaly_detector"
+ gem.homepage = "https://github.com/ankane/anomaly"
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- gem.name = "anomaly_detector"
+ gem.name = "anomaly"
gem.require_paths = ["lib"]
- gem.version = AnomalyDetector::VERSION
+ gem.version = Anomaly::VERSION
gem.add_development_dependency "rake"
gem.add_development_dependency "rspec", ">= 2.0.0"
View
2  lib/anomaly.rb
@@ -0,0 +1,2 @@
+require "anomaly/version"
+require "anomaly/detector"
View
50 lib/anomaly/detector.rb
@@ -0,0 +1,50 @@
+module Anomaly
+ class Detector
+
+ def initialize(data)
+ # Use NMatrix if possible
+ if defined?(NMatrix) and (!defined?(Matrix) or !data.is_a?(Matrix))
+ d = data.is_a?(NMatrix) ? data : NMatrix.to_na(data)
+
+ # Convert these to an array for Marshal.dump
+ @mean = d.mean(1).to_a
+ @std = d.stddev(1).to_a
+ else
+ d = data.is_a?(Matrix) ? data : Matrix.rows(data)
+ cols = d.column_size.times.map{|i| d.column(i)}
+ @mean = cols.map{|c| mean(c)}
+ @std = cols.each_with_index.map{|c,i| std(c, @mean[i])}
+ end
+
+ raise "Standard deviation cannot be zero" if @std.find_index{|i| i == 0 or i.nan?}
+ end
+
+ def probability(x)
+ raise ArgumentError, "x must have #{@mean.size} elements" if x.size != @mean.size
+ x.each_with_index.map{|a,i| normal_pdf(a, @mean[i], @std[i]) }.reduce(1, :*)
+ end
+
+ def anomaly?(x, epsilon)
+ probability(x) < epsilon
+ end
+
+ protected
+
+ SQRT2PI = Math.sqrt(2*Math::PI)
+
+ def normal_pdf(x, mean = 0, std = 1)
+ 1/(SQRT2PI*std)*Math.exp(-((x - mean)**2/(2.0*(std**2))))
+ end
+
+ # Not used for NArray
+
+ def mean(x)
+ x.inject(0.0){|a, i| a + i}/x.size
+ end
+
+ def std(x, mean)
+ Math.sqrt(x.inject(0.0){|a, i| a + (i - mean) ** 2}/(x.size - 1))
+ end
+
+ end
+end
View
2  lib/anomaly_detector/version.rb → lib/anomaly/version.rb
@@ -1,3 +1,3 @@
-class AnomalyDetector
+module Anomaly
VERSION = "0.0.1"
end
View
57 lib/anomaly_detector.rb
@@ -1,57 +0,0 @@
-require "anomaly_detector/version"
-
-begin
- require "narray"
- require "nmatrix"
-rescue LoadError
- require "matrix"
-end
-
-class AnomalyDetector
-
- def initialize(data)
- # Use NMatrix if possible
- if defined?(NMatrix) and (!defined?(Matrix) or !data.is_a?(Matrix))
- d = data.is_a?(NMatrix) ? data : NMatrix.to_na(data)
-
- # Convert these to an array for Marshal.dump
- @mean = d.mean(1).to_a
- @std = d.stddev(1).to_a
- else
- d = data.is_a?(Matrix) ? data : Matrix.rows(data)
- cols = d.column_size.times.map{|i| d.column(i)}
- @mean = cols.map{|c| mean(c)}
- @std = cols.each_with_index.map{|c,i| std(c, @mean[i])}
- end
-
- raise "Standard deviation cannot be zero" if @std.find_index{|i| i == 0 or i.nan?}
- end
-
- def probability(x)
- raise ArgumentError, "x must have #{@mean.size} elements" if x.size != @mean.size
- x.each_with_index.map{|a,i| normal_pdf(a, @mean[i], @std[i]) }.reduce(1, :*)
- end
-
- def anomaly?(x, epsilon)
- probability(x) < epsilon
- end
-
- protected
-
- SQRT2PI = Math.sqrt(2*Math::PI)
-
- def normal_pdf(x, mean = 0, std = 1)
- 1/(SQRT2PI*std)*Math.exp(-((x - mean)**2/(2.0*(std**2))))
- end
-
- # Not used for NArray
-
- def mean(x)
- x.inject(0.0){|a, i| a + i}/x.size
- end
-
- def std(x, mean)
- Math.sqrt(x.inject(0.0){|a, i| a + (i - mean) ** 2}/(x.size - 1))
- end
-
-end
View
6 spec/anomaly_detector_spec.rb → spec/anomaly/detector_spec.rb
@@ -1,8 +1,8 @@
require "spec_helper"
-describe AnomalyDetector do
+describe Anomaly::Detector do
let(:data) { [[-1,-2],[0,0],[1,2]] }
- let(:ad) { AnomalyDetector.new(data) }
+ let(:ad) { Anomaly::Detector.new(data) }
# mean = [0, 0], std = [1, 2]
it "computes the right probability" do
@@ -34,7 +34,7 @@
let(:sample) { [rand, rand] }
it "returns the same probability as an NMatrix" do
- ad.probability(sample).should == AnomalyDetector.new(Matrix.rows(data)).probability(sample)
+ ad.probability(sample).should == Anomaly::Detector.new(Matrix.rows(data)).probability(sample)
end
end
end
View
2  spec/spec_helper.rb
@@ -1,7 +1,7 @@
require "rubygems"
require "bundler/setup"
-require "anomaly_detector"
+require "anomaly"
require "matrix"
RSpec.configure do |config|
Please sign in to comment.
Something went wrong with that request. Please try again.