cabalist 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/.gitignore +4 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +0 -0
  5. data/README.md +121 -0
  6. data/Rakefile +17 -0
  7. data/cabalist.gemspec +42 -0
  8. data/lib/cabalist.rb +13 -2
  9. data/lib/cabalist/configuration.rb +20 -0
  10. data/lib/cabalist/frontend.rb +111 -0
  11. data/lib/cabalist/model_additions.rb +127 -0
  12. data/lib/cabalist/railtie.rb +14 -0
  13. data/lib/cabalist/version.rb +3 -0
  14. data/lib/cabalist/views/classifier.haml +82 -0
  15. data/lib/cabalist/views/index.haml +21 -0
  16. data/lib/cabalist/views/layout.haml +39 -0
  17. data/lib/generators/cabalist/classifier/USAGE +0 -0
  18. data/lib/generators/cabalist/classifier/classifier_generator.rb +37 -0
  19. data/lib/generators/cabalist/classifier/templates/migrations/add_cabalist.rb.erb +11 -0
  20. data/lib/generators/cabalist/install/USAGE +0 -0
  21. data/lib/generators/cabalist/install/install_generator.rb +26 -0
  22. data/lib/generators/cabalist/install/templates/initializers/cabalist.rb +4 -0
  23. data/lib/generators/cabalist/install/templates/public/images/eye_12x9.png +0 -0
  24. data/lib/generators/cabalist/install/templates/public/images/logo.png +0 -0
  25. data/lib/generators/cabalist/install/templates/public/images/ncirl.png +0 -0
  26. data/lib/generators/cabalist/install/templates/public/images/pen_12x12.png +0 -0
  27. data/lib/generators/cabalist/install/templates/public/images/symbol.png +0 -0
  28. data/lib/generators/cabalist/install/templates/public/images/target_12x12.png +0 -0
  29. data/lib/generators/cabalist/install/templates/public/images/x_14x14.png +0 -0
  30. data/lib/generators/cabalist/install/templates/public/javascripts/cabalist.js +23 -0
  31. data/lib/generators/cabalist/install/templates/public/stylesheets/cabalist.css +197 -0
  32. data/spec/cabalist/frontend_spec.rb +79 -0
  33. data/spec/cabalist/model_additions_spec.rb +104 -0
  34. data/spec/cabalist/performance_benchmark_spec.rb +76 -0
  35. data/spec/spec_helper.rb +30 -0
  36. metadata +164 -12
  37. data/lib/cabalist/manager.rb +0 -30
  38. data/lib/cabalist/object_hooks.rb +0 -59
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cabalist::Frontend do
4
+
5
+ with_model :Cat do
6
+
7
+ table do |t|
8
+ t.string :color
9
+ t.boolean :evil
10
+ t.timestamp :autoclassified_at
11
+ end
12
+
13
+ model do
14
+ extend Cabalist::ModelAdditions
15
+
16
+ def self.test_cats
17
+ result = []
18
+ 100.times { result << Cat::create(:color => 'white', :evil => false) }
19
+ 100.times { result << Cat::create(:color => 'black', :evil => true) }
20
+ return result
21
+ end
22
+
23
+ acts_as_cabalist :class_variable => :evil,
24
+ :features => [:color],
25
+ :collection => :test_cats
26
+ end
27
+
28
+ end
29
+
30
+ before(:each) do
31
+ Cat::test_cats
32
+ Cabalist::Configuration.instance.frontend_classes = [Cat]
33
+ end
34
+
35
+ it "should respond to GET at /" do
36
+ get '/'
37
+ last_response.should be_ok
38
+ last_response.body.should match /Cats/
39
+ end
40
+
41
+ it "should list all records for Cat" do
42
+ get "/cat/all/1"
43
+ last_response.should be_ok
44
+ end
45
+
46
+ it "should list non-classified records for Cat" do
47
+ get "/cat/none/1"
48
+ last_response.should be_ok
49
+ end
50
+
51
+ it "should list manually classified records for Cat" do
52
+ get "/cat/manual/1"
53
+ last_response.should be_ok
54
+ end
55
+
56
+ it "should list automatically classified records for Cat" do
57
+ get "/cat/auto/1"
58
+ last_response.should be_ok
59
+ end
60
+
61
+ it "should set the value of class variable for a Cat with a given ID" do
62
+ cat = Cat.first
63
+ post "/cat/teach/#{cat.id}", { :classification => true, :classification_freeform => '' },
64
+ { :referer => '/cat/all/1' }
65
+ last_response.should be_redirect
66
+ end
67
+
68
+ it "should automatically classify the Cat with a given ID" do
69
+ cat = Cat.first
70
+ post "/cat/autoclassify/#{cat.id}", {}, { :referer => '/cat/manual/1' }
71
+ last_response.should be_redirect
72
+ end
73
+
74
+ it "should retrain the Cat classification model" do
75
+ post "/cat/retrain", {}, { :referer => '/cat/manual/1' }
76
+ last_response.should be_redirect
77
+ end
78
+
79
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cabalist::ModelAdditions do
4
+
5
+ with_model :Cat do
6
+
7
+ table do |t|
8
+ t.string :color
9
+ t.boolean :evil
10
+ t.timestamp :autoclassified_at
11
+ end
12
+
13
+ model do
14
+ extend Cabalist::ModelAdditions
15
+
16
+ def self.test_cats
17
+ result = []
18
+ 10.times { result << Cat::create(:color => 'white', :evil => false) }
19
+ 10.times { result << Cat::create(:color => 'black', :evil => true) }
20
+ return result
21
+ end
22
+
23
+ acts_as_cabalist :class_variable => :evil,
24
+ :features => [:color],
25
+ :collection => :test_cats
26
+ end
27
+
28
+ end
29
+
30
+ before(:each) do
31
+ @new_cat = Cat::new(:color => 'white', :evil => false)
32
+ @white_cat = Cat::new(:color => 'white')
33
+ @black_cat = Cat::new(:color => 'black')
34
+ end
35
+
36
+ # == Test class (static) methods =================================== #
37
+ it "Should return feature names" do
38
+ Cat::get_feature_names.should eq [:color]
39
+ end
40
+
41
+ it "Shoud return class variable name" do
42
+ Cat::get_class_variable_name.should eq :evil
43
+ end
44
+
45
+ it "Should be able to build a classifier" do
46
+ Cat::build_model.should be_an_instance_of Ai4r::Classifiers::ID3
47
+ end
48
+
49
+ it "Should be able to train a classifier" do
50
+ Cat::train_model.should be_an_instance_of Ai4r::Classifiers::ID3
51
+ end
52
+
53
+ it "Should be able to return a classifier" do
54
+ Cat::classifier.should be_an_instance_of Ai4r::Classifiers::ID3
55
+ end
56
+
57
+ it "Should return class variable value domain" do
58
+ Cat::class_variable_domain.should eq [false, true]
59
+ end
60
+ # == END =========================================================== #
61
+
62
+ # == Test instance methods ========================================= #
63
+ it "Should return feature values" do
64
+ @new_cat.get_features.should eq ['white']
65
+ end
66
+
67
+ it "Should return class variable value" do
68
+ @new_cat.get_class_variable.should eq false
69
+ end
70
+
71
+ it "Should be able to set class variable accordingly" do
72
+ @new_cat.set_class_variable(true)
73
+ @new_cat.evil?.should eq true
74
+ end
75
+
76
+ it "Should be able to predict the value of class variable" do
77
+ @white_cat.classify.should eq false
78
+ @black_cat.classify.should eq true
79
+ end
80
+
81
+ it "Should not timestamp an object when calling \#classify" do
82
+ @white_cat.classify
83
+ @white_cat.autoclassified_at.should eq nil
84
+ end
85
+
86
+ it "Should autoclassify an object when calling \#classify!" do
87
+ @white_cat.classify!
88
+ @white_cat.autoclassified_at.should be_an_instance_of DateTime
89
+ @white_cat.evil?.should eq false
90
+
91
+ @black_cat.classify!
92
+ @black_cat.autoclassified_at.should be_an_instance_of DateTime
93
+ @black_cat.evil?.should eq true
94
+ end
95
+
96
+ it "Should remove an autoclassification timestamp when calling \#teach" do
97
+ @black_cat.classify!
98
+ @black_cat.teach(false)
99
+ @black_cat.autoclassified_at.should eq nil
100
+ @black_cat.evil?.should eq false
101
+ end
102
+ # == END =========================================================== #
103
+
104
+ end
@@ -0,0 +1,76 @@
1
+ require 'benchmark'
2
+ require 'spec_helper'
3
+
4
+ RSpec::Matchers.define :take_less_than do |n|
5
+ chain :seconds do; end
6
+
7
+ match do |block|
8
+ @elapsed = Benchmark.realtime do
9
+ block.call
10
+ end
11
+ @elapsed <= n
12
+ end
13
+
14
+ end
15
+
16
+ describe Cabalist::ModelAdditions do
17
+
18
+ with_model :Cat do
19
+
20
+ table do |t|
21
+ t.string :color
22
+ t.string :gender
23
+ t.boolean :evil
24
+ t.timestamp :autoclassified_at
25
+ end
26
+
27
+ model do
28
+ extend Cabalist::ModelAdditions
29
+
30
+ # Overall, the model will cover 8,000 cats. The idea is:
31
+ # - all white cats are good
32
+ # - all black cats are evil
33
+ # - all grey female cats are good
34
+ # - all grey make cats are evil
35
+ # - all ginger female cats are evil
36
+ # - all ginger male cats are good
37
+ def self.create_test_cats
38
+ result = []
39
+ 1000.times { result << Cat::create(:color => 'white', :gender => 'female', :evil => false) }
40
+ 1000.times { result << Cat::create(:color => 'white', :gender => 'male', :evil => false) }
41
+ 1000.times { result << Cat::create(:color => 'black', :gender => 'female', :evil => true) }
42
+ 1000.times { result << Cat::create(:color => 'black', :gender => 'male', :evil => true) }
43
+ 1000.times { result << Cat::create(:color => 'grey', :gender => 'female', :evil => false) }
44
+ 1000.times { result << Cat::create(:color => 'grey', :gender => 'male', :evil => true) }
45
+ 1000.times { result << Cat::create(:color => 'ginger', :gender => 'female', :evil => true) }
46
+ 1000.times { result << Cat::create(:color => 'ginger', :gender => 'male', :evil => false) }
47
+ return result
48
+ end
49
+
50
+ acts_as_cabalist :class_variable => :evil,
51
+ :features => [:color, :gender],
52
+ :collection => :all
53
+ end
54
+
55
+ end
56
+
57
+ it "Creates a model within less than 5 seconds" do
58
+ Cat::create_test_cats
59
+ Cat::count.should eq 8000
60
+ expect do
61
+ Cat::classifier
62
+ end.to take_less_than(5).seconds
63
+ end
64
+
65
+ it "Classifies a new cat correctly and in less than 0.1 seconds" do
66
+ Cat::create_test_cats
67
+ Cat::count.should eq 8000
68
+ Cat::train_model
69
+ c = Cat::new(:color => 'white', :gender => 'male')
70
+ c.classify.should eq false
71
+ expect do
72
+ c.classify
73
+ end.to take_less_than(0.1).seconds
74
+ end
75
+
76
+ end
@@ -0,0 +1,30 @@
1
+ require 'active_record'
2
+ require 'cabalist'
3
+ require 'rack/test'
4
+ require 'sinatra'
5
+ require 'sqlite3'
6
+ require 'with_model'
7
+
8
+ ActiveRecord::Base.establish_connection(
9
+ :adapter => "sqlite3",
10
+ :database => "/tmp/cabalist.sqlite3"
11
+ )
12
+
13
+ Cabalist.config do |c|
14
+ c.db_path = '/tmp/cabalist_level.db'
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.include Rack::Test::Methods
19
+ config.extend WithModel
20
+ end
21
+
22
+ # setup test environment
23
+ set :environment, :test
24
+ set :run, false
25
+ set :raise_errors, true
26
+ set :logging, false
27
+
28
+ def app
29
+ Cabalist::Frontend
30
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cabalist
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Marcin Wyszynski
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-09-04 00:00:00 Z
13
+ date: 2012-04-23 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ai4r
@@ -20,11 +20,128 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: "1.10"
23
+ version: "0"
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
- description:
27
- email: marcin.pixie@gmail.com
26
+ - !ruby/object:Gem::Dependency
27
+ name: haml
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "3.0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: kaminari
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.13.0
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: leveldb-ruby
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: padrino-helpers
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :runtime
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :runtime
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: sinatra
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :runtime
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: activerecord
94
+ prerelease: false
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :development
102
+ version_requirements: *id008
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec
105
+ prerelease: false
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ type: :development
113
+ version_requirements: *id009
114
+ - !ruby/object:Gem::Dependency
115
+ name: sqlite3
116
+ prerelease: false
117
+ requirement: &id010 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ type: :development
124
+ version_requirements: *id010
125
+ - !ruby/object:Gem::Dependency
126
+ name: with_model
127
+ prerelease: false
128
+ requirement: &id011 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: "0"
134
+ type: :development
135
+ version_requirements: *id011
136
+ description: |
137
+ Cabalist is conceived as a simple way of adding some smarts
138
+ (machine learning capabilities) to your Ruby on Rails models
139
+ without having to dig deep into mind-boggling AI algorithms.
140
+ Using it is meant to be as straightforward as adding a few
141
+ lines to your existing code and running a Rails generator or two.
142
+
143
+ email:
144
+ - marcin.pixie@gmail.com
28
145
  executables: []
29
146
 
30
147
  extensions: []
@@ -32,10 +149,42 @@ extensions: []
32
149
  extra_rdoc_files: []
33
150
 
34
151
  files:
35
- - lib/cabalist/manager.rb
36
- - lib/cabalist/object_hooks.rb
152
+ - .gitignore
153
+ - .travis.yml
154
+ - Gemfile
155
+ - LICENSE
156
+ - README.md
157
+ - Rakefile
158
+ - cabalist.gemspec
37
159
  - lib/cabalist.rb
38
- homepage: https://github.com/marcinwyszynski/cabalist
160
+ - lib/cabalist/configuration.rb
161
+ - lib/cabalist/frontend.rb
162
+ - lib/cabalist/model_additions.rb
163
+ - lib/cabalist/railtie.rb
164
+ - lib/cabalist/version.rb
165
+ - lib/cabalist/views/classifier.haml
166
+ - lib/cabalist/views/index.haml
167
+ - lib/cabalist/views/layout.haml
168
+ - lib/generators/cabalist/classifier/USAGE
169
+ - lib/generators/cabalist/classifier/classifier_generator.rb
170
+ - lib/generators/cabalist/classifier/templates/migrations/add_cabalist.rb.erb
171
+ - lib/generators/cabalist/install/USAGE
172
+ - lib/generators/cabalist/install/install_generator.rb
173
+ - lib/generators/cabalist/install/templates/initializers/cabalist.rb
174
+ - lib/generators/cabalist/install/templates/public/images/eye_12x9.png
175
+ - lib/generators/cabalist/install/templates/public/images/logo.png
176
+ - lib/generators/cabalist/install/templates/public/images/ncirl.png
177
+ - lib/generators/cabalist/install/templates/public/images/pen_12x12.png
178
+ - lib/generators/cabalist/install/templates/public/images/symbol.png
179
+ - lib/generators/cabalist/install/templates/public/images/target_12x12.png
180
+ - lib/generators/cabalist/install/templates/public/images/x_14x14.png
181
+ - lib/generators/cabalist/install/templates/public/javascripts/cabalist.js
182
+ - lib/generators/cabalist/install/templates/public/stylesheets/cabalist.css
183
+ - spec/cabalist/frontend_spec.rb
184
+ - spec/cabalist/model_additions_spec.rb
185
+ - spec/cabalist/performance_benchmark_spec.rb
186
+ - spec/spec_helper.rb
187
+ homepage: http://github.com/marcinwyszynski/cabalist
39
188
  licenses: []
40
189
 
41
190
  post_install_message:
@@ -58,9 +207,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
207
  requirements: []
59
208
 
60
209
  rubyforge_project: cabalist
61
- rubygems_version: 1.8.5
210
+ rubygems_version: 1.8.15
62
211
  signing_key:
63
212
  specification_version: 3
64
- summary: Cabalist adds some precognition to your models using machine learning algorithms. It is more or less a simple, easy to use wrapper around Ai4r - Ruby implementation of AI algorithms.
65
- test_files: []
66
-
213
+ summary: Minimum setup machine learning (classification) library for Ruby on Rails applications.
214
+ test_files:
215
+ - spec/cabalist/frontend_spec.rb
216
+ - spec/cabalist/model_additions_spec.rb
217
+ - spec/cabalist/performance_benchmark_spec.rb
218
+ - spec/spec_helper.rb