nbayes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", ">= 2.8.0"
10
+ gem "rdoc", ">= 3.12"
11
+ gem "bundler", ">= 1.0.0"
12
+ gem "jeweler", ">= 1.8.3"
13
+ end
14
+ gem 'simplecov', :require => false, :group => :test
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ git (1.2.5)
6
+ jeweler (1.8.3)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rdoc
11
+ json (1.7.3)
12
+ multi_json (1.3.6)
13
+ rake (0.9.2.2)
14
+ rdoc (3.12)
15
+ json (~> 1.4)
16
+ rspec (2.10.0)
17
+ rspec-core (~> 2.10.0)
18
+ rspec-expectations (~> 2.10.0)
19
+ rspec-mocks (~> 2.10.0)
20
+ rspec-core (2.10.1)
21
+ rspec-expectations (2.10.0)
22
+ diff-lcs (~> 1.1.3)
23
+ rspec-mocks (2.10.1)
24
+ simplecov (0.6.4)
25
+ multi_json (~> 1.0)
26
+ simplecov-html (~> 0.5.3)
27
+ simplecov-html (0.5.3)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler (>= 1.0.0)
34
+ jeweler (>= 1.8.3)
35
+ rdoc (>= 3.12)
36
+ rspec (>= 2.8.0)
37
+ simplecov
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Oasic Technologies LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,31 @@
1
+ == nbayes
2
+
3
+ _gem install nbayes_
4
+
5
+ NBayes is a full-featured, Ruby implementation of Naive Bayes. Some of the features include:
6
+
7
+ * allows prior distribution on classes to be assumed uniform (optional)
8
+ * generic to work with all types of tokens, not just text
9
+ * outputs probabilities, instead of just class w/max probability
10
+ * customizable constant value for Laplacian smoothing
11
+ * optional and customizable purging of low-frequency tokens (for performance)
12
+ * optional binarized mode
13
+ * uses log probabilities to avoid underflow
14
+
15
+ For more information, view this blog post (coming soon)
16
+
17
+ == Contributing to nbayes
18
+
19
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
20
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
21
+ * Fork the project.
22
+ * Start a feature/bugfix branch.
23
+ * Commit and push until you are happy with your contribution.
24
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
25
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
26
+
27
+ == Copyright
28
+
29
+ Copyright (c) 2012 Oasic Technologies LLC. See LICENSE.txt for
30
+ further details.
31
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "nbayes"
18
+ gem.homepage = "http://github.com/oasic/nbayes"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Full-featured Ruby implementation of Naive Bayes classifier}
21
+ gem.description = %Q{Ruby implementation of Naive Bayes that generates true probabilities per class, works with many token types, and provides lots of bells and whistles while being optimized for performance.}
22
+ gem.email = "j@oasic.net"
23
+ gem.authors = ["oasic"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "nbayes #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/nbayes.rb ADDED
@@ -0,0 +1,187 @@
1
+ require 'yaml'
2
+
3
+ # == NBayes::Base
4
+ #
5
+ # Robust implementation of NaiveBayes:
6
+ # - using log probabilities to avoid floating point issues
7
+ # - Laplacian smoothing for unseen tokens
8
+ # - allows binarized or standard NB
9
+ # - allows Prior distribution on category to be assumed uniform (optional)
10
+ # - generic to work with all types of tokens, not just text
11
+ #
12
+
13
+ module NBayes
14
+
15
+ class Base
16
+
17
+ attr_accessor :assume_uniform, :debug, :k, :vocab, :data, :log_vocab
18
+ attr_reader :binarized
19
+
20
+ def initialize(options={})
21
+ @debug = false
22
+ @k = 1
23
+ @binarized = options[:binarized] || false
24
+ @log_vocab = false # for smoothing, use log of vocab size, rather than vocab size
25
+ @assume_uniform = false
26
+ @vocab = Hash.new # used to calculate vocab size (@vocab.keys.length)
27
+ @data = Hash.new
28
+ @data.default_proc = get_default_proc()
29
+ #@data = {
30
+ # "category1": {
31
+ # "tokens": Hash.new(0),
32
+ # "total_tokens": 0,
33
+ # "examples": 0
34
+ # },
35
+ # ...
36
+ #}
37
+ end
38
+
39
+
40
+ # Allows removal of low frequency words that increase processing time and may overfit
41
+ # - tokens with a count less than x (measured by summing across all classes) are removed
42
+ # Ex: nb.purge_less_than(2)
43
+ #
44
+ # NOTE: this does not decrement the "examples" count, so purging is not *always* the same
45
+ # as if the item was never added in the first place, but usually so
46
+ def purge_less_than(x)
47
+ remove_list = {}
48
+ @vocab.keys.each do |token|
49
+ count = @data.keys.inject(0){|sum, cat| sum + @data[cat][:tokens][token] }
50
+ next if count >= x
51
+ @data.each do |cat, cat_data|
52
+ count = cat_data[:tokens][token]
53
+ cat_data[:tokens].delete(token) # delete and retrieve count
54
+ cat_data[:total_tokens] -= count # subtract that count from cat counts
55
+ end # each category hash
56
+ #print "removing #{token}\n"
57
+ remove_list[token]=1
58
+ end # each vocab word
59
+ remove_list.keys.each {|token| @vocab.delete(token) }
60
+ #print "total vocab size is now #{vocab_size}\n"
61
+ end
62
+
63
+
64
+ # Returns the default proc used by the data hash
65
+ # Separate method so that it can be used after data import
66
+ def get_default_proc
67
+ return lambda do |hash, category|
68
+ hash[category]= {
69
+ :tokens => Hash.new(0), # holds freq counts
70
+ :total_tokens => 0,
71
+ :examples => 0
72
+ }
73
+ end
74
+ end
75
+
76
+ # called internally after yaml import to reset Hash defaults
77
+ def reset_after_import
78
+ @data.default_proc = get_default_proc()
79
+ @data.each {|cat, cat_hash| cat_hash[:tokens].default=0 }
80
+ end
81
+
82
+ def train(tokens, category)
83
+ cat_data = @data[category]
84
+ cat_data[:examples]+=1
85
+ tokens = tokens.uniq if binarized
86
+ tokens.each do |w|
87
+ @vocab[w]=1
88
+ cat_data[:tokens][w]+=1
89
+ cat_data[:total_tokens]+=1
90
+ end
91
+ end
92
+
93
+ def classify(tokens)
94
+ print "classify: #{tokens.join(', ')}\n" if @debug
95
+ probs = {}
96
+ tokens = tokens.uniq if binarized
97
+ probs = calculate_probabilities(tokens)
98
+ print "results: #{probs.to_yaml}\n" if @debug
99
+ probs.extend(NBayes::Result)
100
+ probs
101
+ end
102
+
103
+ # Total number of training instances
104
+ def total_examples
105
+ sum = 0
106
+ @data.each {|cat, cat_data| sum += cat_data[:examples] }
107
+ sum
108
+ end
109
+
110
+ # Returns the size of the "vocab" - the number of unique tokens found in the text
111
+ # This is used in the Laplacian smoothing.
112
+ def vocab_size
113
+ return Math.log(@vocab.keys.length) if @log_vocab
114
+ @vocab.keys.length
115
+ end
116
+
117
+ # Calculates the actual probability of a class given the tokens
118
+ # (this is the work horse of the code)
119
+ def calculate_probabilities(tokens)
120
+ # P(class|words) = P(w1,...,wn|class) * P(class) / P(w1,...,wn)
121
+ # = argmax P(w1,...,wn|class) * P(class)
122
+ #
123
+ # P(wi|class) = (count(wi, class) + k)/(count(w,class) + kV)
124
+ prob_numerator = {}
125
+ v_size = vocab_size
126
+ @data.keys.each do |category|
127
+ cat_data = @data[category]
128
+ cat_prob = Math.log(cat_data[:examples]/total_examples().to_f)
129
+ cat_prob = Math.log(1/@data.keys.length.to_f) if assume_uniform
130
+ log_probs = 0
131
+ cat_denominator = (cat_data[:total_tokens]+ @k*v_size).to_f
132
+ tokens.each do |token|
133
+ log_probs += Math.log( (cat_data[:tokens][token] + @k)/cat_denominator )
134
+ end
135
+ prob_numerator[category] = log_probs + cat_prob
136
+ end
137
+ # calculate the denominator, which normalizes this into a probability; it's just the sum of all numerators from above
138
+ normalizer = 0
139
+ prob_numerator.each {|cat, numerator| normalizer += numerator }
140
+ # One more caveat:
141
+ # We're using log probabilities, so the numbers are negative and the smallest negative number is actually the largest prob.
142
+ # To convert, we need to maintain the relative distance between all of the probabilities:
143
+ # - divide log prob by normalizer: this keeps ratios the same, but reverses the ordering
144
+ # - re-normalize based off new counts
145
+ # - final calculation
146
+ # Ex: -1,-1,-2 => -4/-1, -4/-1, -4/-2
147
+ # - renormalize and calculate => 4/10, 4/10, 2/10
148
+ intermed = {}
149
+ renormalizer = 0
150
+ prob_numerator.each do |cat, numerator|
151
+ intermed[cat]=normalizer/numerator.to_f
152
+ renormalizer += intermed[cat]
153
+ end
154
+ # calculate final probs
155
+ final_probs = {}
156
+ intermed.each do |cat, value|
157
+ final_probs[cat]=value/renormalizer.to_f
158
+ end
159
+ final_probs
160
+ end
161
+
162
+
163
+ # Loads class instance from a data file (e.g., yaml)
164
+ def self.from(yml_file)
165
+ nbayes = YAML.load_file(yml_file)
166
+ nbayes.reset_after_import() # yaml does not properly set the defaults on the Hashes
167
+ nbayes
168
+ end
169
+
170
+ # Dumps class instance to a file
171
+ def dump(yml_file)
172
+ File.open(yml_file, "w") {|f| YAML.dump(self, f) }
173
+ end
174
+
175
+ end
176
+
177
+
178
+ module Result
179
+ def max_class
180
+ keys.max{|a,b| self[a] <=> self[b] }
181
+ end
182
+ end
183
+
184
+ end
185
+
186
+
187
+
data/nbayes.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "nbayes"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["oasic"]
12
+ s.date = "2012-06-27"
13
+ s.description = "Ruby implementation of Naive Bayes that generates true probabilities per class, works with many token types, and provides lots of bells and whistles while being optimized for performance."
14
+ s.email = "j@oasic.net"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/nbayes.rb",
29
+ "nbayes.gemspec",
30
+ "spec/nbayes_spec.rb",
31
+ "spec/spec_helper.rb"
32
+ ]
33
+ s.homepage = "http://github.com/oasic/nbayes"
34
+ s.licenses = ["MIT"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = "1.8.15"
37
+ s.summary = "Full-featured Ruby implementation of Naive Bayes classifier"
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
44
+ s.add_development_dependency(%q<rdoc>, [">= 3.12"])
45
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
46
+ s.add_development_dependency(%q<jeweler>, [">= 1.8.3"])
47
+ else
48
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
49
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
50
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
51
+ s.add_dependency(%q<jeweler>, [">= 1.8.3"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
55
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
56
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
57
+ s.add_dependency(%q<jeweler>, [">= 1.8.3"])
58
+ end
59
+ end
60
+
@@ -0,0 +1,151 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'fileutils'
3
+
4
+ describe "NBayes" do
5
+ before do
6
+ @nbayes = NBayes::Base.new
7
+ end
8
+
9
+ it "should assign equal probability to each class" do
10
+ @nbayes.train( %w[a b c d e f g], 'classA' )
11
+ @nbayes.train( %w[a b c d e f g], 'classB' )
12
+ results = @nbayes.classify( %w[a b c] )
13
+ results['classA'].should == 0.5
14
+ results['classB'].should == 0.5
15
+ end
16
+
17
+ it "should handle more than 2 classes" do
18
+ @nbayes.train( %w[a a a a], 'classA' )
19
+ @nbayes.train( %w[b b b b], 'classB' )
20
+ @nbayes.train( %w[c c], 'classC' )
21
+ results = @nbayes.classify( %w[a a a a b c] )
22
+ results.max_class.should == 'classA'
23
+ results['classA'].should >= 0.4
24
+ results['classB'].should <= 0.3
25
+ results['classC'].should <= 0.3
26
+ end
27
+
28
+ it "should use smoothing by default to eliminate errors w/division by zero" do
29
+ @nbayes.train( %w[a a a a], 'classA' )
30
+ @nbayes.train( %w[b b b b], 'classB' )
31
+ results = @nbayes.classify( %w[x y z] )
32
+ results['classA'].should >= 0.0
33
+ results['classB'].should >= 0.0
34
+ end
35
+
36
+ it "should optionally purge low frequency data" do
37
+ 100.times do
38
+ @nbayes.train( %w[a a a a], 'classA' )
39
+ @nbayes.train( %w[b b b b], 'classB' )
40
+ end
41
+ @nbayes.train( %w[a], 'classA' )
42
+ @nbayes.train( %w[c b], 'classB' )
43
+ results = @nbayes.classify( %w[c] )
44
+ results.max_class.should == 'classB'
45
+ results['classB'].should > 0.5
46
+ @nbayes.data['classB'][:tokens]['c'].should == 1
47
+
48
+ @nbayes.purge_less_than(2) # this removes the entry for 'c' in 'classB' because it has freq of 1
49
+ # NOTE: this does not decrement the 'example' count
50
+ results = @nbayes.classify( %w[c] )
51
+ @nbayes.data['classB'][:tokens]['c'].should == 0
52
+ results['classA'].should == 0.5
53
+ results['classB'].should == 0.5
54
+ end
55
+
56
+ it "works on all tokens - not just strings" do
57
+ @nbayes.train( [1, 2, 3], 'low' )
58
+ @nbayes.train( [5, 6, 7], 'high' )
59
+ results = @nbayes.classify( [2] )
60
+ results.max_class.should == 'low'
61
+ results = @nbayes.classify( [6] )
62
+ results.max_class.should == 'high'
63
+ end
64
+
65
+ it "should optionally allow class distribution to be assumed uniform" do
66
+ # before uniform distribution
67
+ @nbayes.train( %w[a a a a b], 'classA' )
68
+ @nbayes.train( %w[a a a a], 'classA' )
69
+ @nbayes.train( %w[a a a a], 'classB' )
70
+ results = @nbayes.classify( ['a'] )
71
+ results.max_class.should == 'classA'
72
+ results['classA'].should > 0.5
73
+ # after uniform distribution assumption
74
+ @nbayes.assume_uniform = true
75
+ results = @nbayes.classify( ['a'] )
76
+ results.max_class.should == 'classB'
77
+ results['classB'].should > 0.5
78
+ end
79
+
80
+ it "should allow log of vocab size in smoothing" do
81
+
82
+ end
83
+
84
+ # In binarized mode, the frequency count is set to 1 for each token in each instance
85
+ # For text, this is "set of words" rather than "bag of words"
86
+ it "should allow binarized mode" do
87
+ # w/o binarized mode, token repetition can skew the results
88
+ def train_it
89
+ @nbayes.train( %w[a a a a a a a a a a a], 'classA' )
90
+ @nbayes.train( %w[b b], 'classA' )
91
+ @nbayes.train( %w[a c], 'classB' )
92
+ @nbayes.train( %w[a c], 'classB' )
93
+ @nbayes.train( %w[a c], 'classB' )
94
+ end
95
+ train_it
96
+ results = @nbayes.classify( ['a'] )
97
+ results.max_class.should == 'classA'
98
+ results['classA'].should > 0.5
99
+ # this does not happen in binarized mode
100
+ @nbayes = NBayes::Base.new(:binarized => true)
101
+ train_it
102
+ results = @nbayes.classify( ['a'] )
103
+ results.max_class.should == 'classB'
104
+ results['classB'].should > 0.5
105
+ end
106
+
107
+ it "allows smoothing constant k to be set to any value" do
108
+ # increasing k increases smoothing
109
+ @nbayes.train( %w[a a a c], 'classA' )
110
+ @nbayes.train( %w[b b b d], 'classB' )
111
+ @nbayes.k.should == 1
112
+ results = @nbayes.classify( ['c'] )
113
+ prob_k1 = results['classA']
114
+ @nbayes.k = 5
115
+ results = @nbayes.classify( ['c'] )
116
+ prob_k5 = results['classA']
117
+ prob_k1.should > prob_k5 # increasing smoothing constant dampens the effect of the rare token 'c'
118
+ end
119
+
120
+ it "optionally allows using the log of vocab size during smoothing" do
121
+ 10_000.times do
122
+ @nbayes.train( [rand(100)], 'classA' )
123
+ @nbayes.train( %w[b b b d], 'classB' )
124
+ end
125
+ end
126
+
127
+ describe "saving" do
128
+ before do
129
+ @tmp_dir = File.join( File.dirname(__FILE__), 'tmp')
130
+ FileUtils.mkdir(@tmp_dir) if !File.exists?(@tmp_dir)
131
+ @yml_file = File.join(@tmp_dir, 'test.yml')
132
+ end
133
+
134
+ after do
135
+ FileUtils.rm(@yml_file) if File.exists?(@yml_file)
136
+ end
137
+
138
+ it "should save to yaml and load from yaml" do
139
+ @nbayes.train( %w[a a a a], 'classA' )
140
+ @nbayes.train( %w[b b b b], 'classB' )
141
+ results = @nbayes.classify( ['b'] )
142
+ results['classB'].should >= 0.5
143
+ @nbayes.dump(@yml_file)
144
+ File.exists?(@yml_file).should == true
145
+ @nbayes2 = NBayes::Base.from(@yml_file)
146
+ results = @nbayes.classify( ['b'] )
147
+ results['classB'].should >= 0.5
148
+ end
149
+ end
150
+
151
+ end
@@ -0,0 +1,16 @@
1
+ # These 2 lines MUST be first
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'rspec'
8
+ require 'nbayes'
9
+
10
+ # Requires supporting files with custom matchers and macros, etc,
11
+ # in ./support/ and its subdirectories.
12
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
13
+
14
+ RSpec.configure do |config|
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nbayes
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - oasic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-06-27 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.8.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rdoc
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "3.12"
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.0.0
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: jeweler
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.8.3
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ description: Ruby implementation of Naive Bayes that generates true probabilities per class, works with many token types, and provides lots of bells and whistles while being optimized for performance.
60
+ email: j@oasic.net
61
+ executables: []
62
+
63
+ extensions: []
64
+
65
+ extra_rdoc_files:
66
+ - LICENSE.txt
67
+ - README.rdoc
68
+ files:
69
+ - .document
70
+ - .rspec
71
+ - Gemfile
72
+ - Gemfile.lock
73
+ - LICENSE.txt
74
+ - README.rdoc
75
+ - Rakefile
76
+ - VERSION
77
+ - lib/nbayes.rb
78
+ - nbayes.gemspec
79
+ - spec/nbayes_spec.rb
80
+ - spec/spec_helper.rb
81
+ homepage: http://github.com/oasic/nbayes
82
+ licenses:
83
+ - MIT
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: -4266862066196834109
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.15
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Full-featured Ruby implementation of Naive Bayes classifier
111
+ test_files: []
112
+