cabalist 0.0.3 → 0.0.4

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 (39) hide show
  1. data/.yardopts +1 -0
  2. data/cabalist.gemspec +4 -1
  3. data/lib/cabalist.rb +7 -2
  4. data/lib/cabalist/configuration.rb +17 -1
  5. data/lib/cabalist/frontend.rb +52 -5
  6. data/lib/cabalist/model_additions.rb +483 -82
  7. data/lib/cabalist/railtie.rb +11 -1
  8. data/lib/cabalist/version.rb +4 -1
  9. data/lib/cabalist/views/classifier.haml +4 -2
  10. data/lib/cabalist/views/index.haml +21 -16
  11. data/lib/generators/cabalist/classifier/classifier_generator.rb +9 -0
  12. data/lib/generators/cabalist/install/install_generator.rb +7 -1
  13. data/lib/generators/cabalist/install/templates/public/stylesheets/cabalist.css +55 -1
  14. data/lib/tasks/retrain.rake +21 -0
  15. data/spec/cabalist/model_additions_spec.rb +15 -0
  16. data/spec/cabalist/non_cabalist_model_spec.rb +95 -0
  17. data/spec/spec_helper.rb +14 -0
  18. metadata +32 -38
  19. data/doc/Cabalist.html +0 -257
  20. data/doc/Cabalist/ClassifierGenerator.html +0 -320
  21. data/doc/Cabalist/Configuration.html +0 -404
  22. data/doc/Cabalist/Frontend.html +0 -152
  23. data/doc/Cabalist/InstallGenerator.html +0 -282
  24. data/doc/Cabalist/ModelAdditions.html +0 -1583
  25. data/doc/Cabalist/Railtie.html +0 -127
  26. data/doc/_index.html +0 -158
  27. data/doc/class_list.html +0 -47
  28. data/doc/css/common.css +0 -1
  29. data/doc/css/full_list.css +0 -53
  30. data/doc/css/style.css +0 -320
  31. data/doc/file.README.html +0 -182
  32. data/doc/file_list.html +0 -49
  33. data/doc/frames.html +0 -13
  34. data/doc/index.html +0 -182
  35. data/doc/js/app.js +0 -205
  36. data/doc/js/full_list.js +0 -150
  37. data/doc/js/jquery.js +0 -16
  38. data/doc/method_list.html +0 -206
  39. data/doc/top-level-namespace.html +0 -103
@@ -2,13 +2,23 @@ require 'rails'
2
2
  require 'active_record'
3
3
 
4
4
  module Cabalist
5
+
6
+ # This is the link between Rails application and the Cabalist gem
7
+ #
8
+ # This Railtie extends ActiveRecord::Base with Cabalist::ModelAdditions
9
+ # once ActiveRecord is loaded. It also adds relevant Rake tasks to the
10
+ # application which provide CLI to the Cabalist functionality.
5
11
  class Railtie < ::Rails::Railtie
6
12
 
7
- initializer 'cabalist.model_additions', do
13
+ initializer 'cabalist.model_additions' do
8
14
  ActiveSupport.on_load :active_record do
9
15
  extend ModelAdditions
10
16
  end
11
17
  end
18
+
19
+ rake_tasks do
20
+ load 'tasks/retrain.rake'
21
+ end
12
22
 
13
23
  end
14
24
  end
@@ -1,3 +1,6 @@
1
1
  module Cabalist
2
- VERSION = "0.0.3"
2
+
3
+ # Version of the gem
4
+ VERSION = "0.0.4"
5
+
3
6
  end
@@ -10,6 +10,9 @@
10
10
  %a{ :href => "/cabalist/#{klass.to_s.downcase}/manual" } Manually Classified
11
11
  %li
12
12
  %a{ :href => "/cabalist/#{klass.to_s.downcase}/auto" } Automatically Classified
13
+ %li.retrain
14
+ %form.retrain{ :action => "/cabalist/#{klass.to_s.downcase}/retrain", :method => "POST" }
15
+ %button.retrain Retrain model
13
16
 
14
17
  - unless @collection.empty?
15
18
  %table.cabalist_records
@@ -52,7 +55,7 @@
52
55
  %span.label_info Use existing class:
53
56
  %select{ :name => 'classification' }
54
57
  %option{ :value => nil } - choose classification -
55
- - el.class.classifier.data_set.build_domain(-1).to_a.each do |opt|
58
+ - el.class.class_variable_domain.to_a.each do |opt|
56
59
  %option{ :value => opt.to_s,
57
60
  :selected => (el.get_class_variable == opt) }= opt
58
61
  %p
@@ -68,7 +71,6 @@
68
71
  :src => '/images/target_12x12.png',
69
72
  :title => "Autoclassify (#{el.classify.to_s})" }/
70
73
 
71
-
72
74
  %table.kaminari_nav
73
75
  %tr
74
76
  %td.previous
@@ -2,20 +2,25 @@
2
2
 
3
3
  %h1 Dashboard
4
4
 
5
- %ul.classifiers
5
+ .classifiers
6
6
  - @classes.each do |klass|
7
- %li
8
- %ul.specs
9
- %lh
10
- = klass.to_s
11
- classifier
12
- %li
13
- Classifies the
14
- %span.attr_name= klass.classifier.data_set.data_labels[-1]
15
- attribute
16
- %li
17
- = klass.classifier.data_set.data_items.length
18
- data points
19
- %li
20
- Signals:
21
- %span.attr_name= klass.classifier.data_set.data_labels[0...-1].join(', ')
7
+ .classifier
8
+ %h3.header= "#{klass.to_s} classifier"
9
+ .classifier_content
10
+ %ul.specs
11
+ %li
12
+ Classifies the
13
+ %span.attr_name= klass::get_class_variable_name.to_s
14
+ attribute
15
+ %li
16
+ Features selected:
17
+ %span.attr_name= klass::get_feature_names.join(', ')
18
+ %li
19
+ Trained based on
20
+ = klass::classifier.data_set.data_items.length
21
+ data points from among
22
+ = klass::count
23
+ total records of the #{klass.to_s} class
24
+ .charts
25
+ = piechart_by_class_variable(klass)
26
+ = piechart_by_scope(klass)
@@ -1,4 +1,10 @@
1
1
  module Cabalist
2
+
3
+ # A Rails-specific generator which enables a class to use Cabalist methods.
4
+ #
5
+ # This generator creates a migration to add autoclassified_at attribute
6
+ # to a chosen ActiveRecord model. It also prompts the user whether the
7
+ # resulting classifier should be exposed through the GUI.
2
8
  class ClassifierGenerator < Rails::Generators::NamedBase
3
9
  desc <<-EOF
4
10
  This generator creates a migration to add autoclassified_at attribute
@@ -12,15 +18,18 @@ module Cabalist
12
18
  source_root File.expand_path('../templates/', __FILE__)
13
19
  argument :name, :type => :string
14
20
 
21
+ # Get the next available number for a database migration
15
22
  def self.next_migration_number(dirname)
16
23
  Time.now.strftime("%Y%m%d%H%M%S")
17
24
  end
18
25
 
26
+ # Create a database migration adding autoclassified_at attribute.
19
27
  def create_migration
20
28
  migration_template("migrations/add_cabalist.rb.erb",
21
29
  "db/migrate/add_cabalist_to_#{name.tableize}.rb")
22
30
  end
23
31
 
32
+ # Prompt whether to expose the classifier through GUI
24
33
  def add_to_gui_if_necessary
25
34
  add_to_gui = ''
26
35
  until %w(y Y n N).include?(add_to_gui)
@@ -1,10 +1,16 @@
1
1
  module Cabalist
2
+
3
+ # A Rails-specific generator which installs Cabalist in an application
4
+ #
5
+ # This generator copies Cabalist assets to the application public directory,
6
+ # creates a relevant initializer in config/initializers and adds a route to
7
+ # the config/routes.rb, mounting the GUI at /cabalist endpoint.
2
8
  class InstallGenerator < Rails::Generators::Base
3
9
  desc <<-EOF
4
10
  This generator installs the Cabalist initializer and
5
11
  adds the route to Cabalist GUI (Cabalist::Frontend).
6
12
  Usage:
7
- rails generate cabalist:install <ModelName>
13
+ rails generate cabalist:install
8
14
  EOF
9
15
 
10
16
  source_root File.expand_path('../templates/', __FILE__)
@@ -194,4 +194,58 @@ form.autoclassify {
194
194
  span.label_info {
195
195
  display: inline-block;
196
196
  width: 130px;
197
- }
197
+ }
198
+
199
+ /* Dashboard */
200
+
201
+ .classifier {
202
+ border: 1px solid #DDD;
203
+ margin-bottom: 10px;
204
+ }
205
+
206
+ .classifier:last-child {
207
+ margin-bottom: 0px;
208
+ }
209
+
210
+ .classifier .header {
211
+ margin: 0px;
212
+ padding: 3px 8px;
213
+ border-bottom: 1px solid #ddd;
214
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #DEDEDE), color-stop(100%, #CCC));
215
+ text-shadow: white 0px 1px 1px;
216
+ }
217
+
218
+ .classifier .classifier_content {
219
+ padding: 0px 5px 5px;
220
+ }
221
+
222
+ .specs {
223
+ list-style-type: none;
224
+ padding: 0;
225
+ font-size: 0.8em;
226
+ }
227
+
228
+ ul.scopes {
229
+ position: relative;
230
+ }
231
+
232
+ li.retrain {
233
+ position: absolute;
234
+ right: 10px;
235
+ }
236
+
237
+ button.retrain {
238
+ border: 0px none;
239
+ background: none;
240
+ font-family: "Helvetica Neue", sans-serif;
241
+ font-size: 14px;
242
+ padding: 0;
243
+ margin: 0;
244
+ color: #6EB41E;
245
+ text-shadow: white 0px 1px 1px;
246
+ }
247
+
248
+ button.retrain:hover {
249
+ color: white;
250
+ text-shadow: #888 0px 1px 1px;;
251
+ }
@@ -0,0 +1,21 @@
1
+ namespace :cabalist do
2
+
3
+ desc 'Retrain a Cabalist model'
4
+ task :retrain, [:model] => :environment do |t, args|
5
+ unless args.model
6
+ puts "Usage: rake cabalist:retrain[<CLASS NAME>]"
7
+ else
8
+ begin
9
+ args.model.constantize.train_model
10
+ rescue Exception => e
11
+ puts "Could not retrain the classifier"
12
+ puts "Possibly the class is not Cabalist-enabled?"
13
+ puts "Anyway, here is your stack trace:"
14
+ puts e.backtrace
15
+ else
16
+ puts "Classifier retrained successfully"
17
+ end
18
+ end
19
+ end
20
+
21
+ end
@@ -57,6 +57,21 @@ describe Cabalist::ModelAdditions do
57
57
  it "Should return class variable value domain" do
58
58
  Cat::class_variable_domain.should eq [false, true]
59
59
  end
60
+
61
+ it "Should return percentage agreement between 0 and 1" do
62
+ Cat::test_cats
63
+ Cat::percentage_agreement.should be_between(0, 1)
64
+ end
65
+
66
+ it "Should return percentage random agreement between 0 and 1" do
67
+ Cat::test_cats
68
+ Cat::percentage_random_agreement.should be_between(0, 1)
69
+ end
70
+
71
+ it "Should return Cohen's kappa between -1 and 1" do
72
+ Cat::test_cats
73
+ Cat::cohens_kappa.should be_between(-1, 1)
74
+ end
60
75
  # == END =========================================================== #
61
76
 
62
77
  # == Test instance methods ========================================= #
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cabalist::ModelAdditions do
4
+
5
+ with_model :Dog 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
+ end
16
+
17
+ end
18
+
19
+ before(:each) do
20
+ @new_dog = Dog::new(:color => 'white', :evil => false)
21
+ end
22
+
23
+ # == Test class (static) methods =================================== #
24
+ it "Should not recognize the 'auto_classified' method" do
25
+ expect { Dog::auto_classified }.to raise_error NoMethodError
26
+ end
27
+
28
+ it "Should not recognize the 'build_model' method" do
29
+ expect { Dog::build_model }.to raise_error NoMethodError
30
+ end
31
+
32
+ it "Should not recognize the 'class_variable_domain' method" do
33
+ expect { Dog::class_variable_domain }.to raise_error NoMethodError
34
+ end
35
+
36
+ it "Should not recognize the 'cohens_kappa' method" do
37
+ expect { Dog::cohens_kappa }.to raise_error NoMethodError
38
+ end
39
+
40
+ it "Should not recognize the 'get_class_variable_name' method" do
41
+ expect { Dog::get_class_variable_name }.to raise_error NoMethodError
42
+ end
43
+
44
+ it "Should not recognize the 'get_feature_names' method" do
45
+ expect { Dog::get_feature_names }.to raise_error NoMethodError
46
+ end
47
+
48
+ it "Should not recognize the 'manually_classified' method" do
49
+ expect { Dog::manually_classified }.to raise_error NoMethodError
50
+ end
51
+
52
+ it "Should not recognize the 'not_classified' method" do
53
+ expect { Dog::not_classified }.to raise_error NoMethodError
54
+ end
55
+
56
+ it "Should not recognize the 'percentage_ageement' method" do
57
+ expect { Dog::percentage_ageement }.to raise_error NoMethodError
58
+ end
59
+
60
+ it "Should not recognize the 'percentage_random_agreement' method" do
61
+ expect { Dog::percentage_random_agreement }.to raise_error NoMethodError
62
+ end
63
+
64
+ it "Should not recognize the 'train_model' method" do
65
+ expect { Dog::train_model }.to raise_error NoMethodError
66
+ end
67
+ # == END =========================================================== #
68
+
69
+ # == Test instance methods ========================================= #
70
+ it "Should not recognize the 'classify' method" do
71
+ expect { @new_dog.classify }.to raise_error NoMethodError
72
+ end
73
+
74
+ it "Should not recognize the 'classify!' method" do
75
+ expect { @new_dog.classify! }.to raise_error NoMethodError
76
+ end
77
+
78
+ it "Should not recognize the 'get_class_variable' method" do
79
+ expect { @new_dog.get_class_variable }.to raise_error NoMethodError
80
+ end
81
+
82
+ it "Should not recognize the 'get_features' method" do
83
+ expect { @new_dog.get_features }.to raise_error NoMethodError
84
+ end
85
+
86
+ it "Should not recognize the 'set_class_variable' method" do
87
+ expect { @new_dog.set_class_variable(false) }.to raise_error NoMethodError
88
+ end
89
+
90
+ it "Should not recognize the 'teach' method" do
91
+ expect { @new_dog.teach(false) }.to raise_error NoMethodError
92
+ end
93
+ # == END =========================================================== #
94
+
95
+ end
@@ -14,6 +14,20 @@ Cabalist.configure do |config|
14
14
  config.db_path = '/tmp/cabalist_level.db'
15
15
  end
16
16
 
17
+ RSpec::Matchers.define :be_between do |low,high|
18
+ match do |actual|
19
+ @low, @high = low, high
20
+ actual.between? low, high
21
+ end
22
+
23
+ failure_message_for_should do |actual|
24
+ "expected to be between #{@low} and #{@high}, but was #{actual}"
25
+ end
26
+ failure_message_for_should_not do |actual|
27
+ "expected not to be between #{@low} and #{@high}, but was #{actual}"
28
+ end
29
+ end
30
+
17
31
  RSpec.configure do |config|
18
32
  config.include Rack::Test::Methods
19
33
  config.extend WithModel
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cabalist
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.0.4
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: 2012-04-25 00:00:00 Z
13
+ date: 2012-04-29 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ai4r
@@ -35,29 +35,29 @@ dependencies:
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
37
  - !ruby/object:Gem::Dependency
38
- name: kaminari
38
+ name: googlecharts
39
39
  prerelease: false
40
40
  requirement: &id003 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 0.13.0
45
+ version: 1.6.8
46
46
  type: :runtime
47
47
  version_requirements: *id003
48
48
  - !ruby/object:Gem::Dependency
49
- name: leveldb-ruby
49
+ name: kaminari
50
50
  prerelease: false
51
51
  requirement: &id004 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ">="
55
55
  - !ruby/object:Gem::Version
56
- version: "0"
56
+ version: 0.13.0
57
57
  type: :runtime
58
58
  version_requirements: *id004
59
59
  - !ruby/object:Gem::Dependency
60
- name: padrino-helpers
60
+ name: leveldb-ruby
61
61
  prerelease: false
62
62
  requirement: &id005 !ruby/object:Gem::Requirement
63
63
  none: false
@@ -68,7 +68,7 @@ dependencies:
68
68
  type: :runtime
69
69
  version_requirements: *id005
70
70
  - !ruby/object:Gem::Dependency
71
- name: rake
71
+ name: padrino-helpers
72
72
  prerelease: false
73
73
  requirement: &id006 !ruby/object:Gem::Requirement
74
74
  none: false
@@ -79,7 +79,7 @@ dependencies:
79
79
  type: :runtime
80
80
  version_requirements: *id006
81
81
  - !ruby/object:Gem::Dependency
82
- name: sinatra
82
+ name: rake
83
83
  prerelease: false
84
84
  requirement: &id007 !ruby/object:Gem::Requirement
85
85
  none: false
@@ -90,7 +90,7 @@ dependencies:
90
90
  type: :runtime
91
91
  version_requirements: *id007
92
92
  - !ruby/object:Gem::Dependency
93
- name: activerecord
93
+ name: sinatra
94
94
  prerelease: false
95
95
  requirement: &id008 !ruby/object:Gem::Requirement
96
96
  none: false
@@ -98,10 +98,10 @@ dependencies:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
100
  version: "0"
101
- type: :development
101
+ type: :runtime
102
102
  version_requirements: *id008
103
103
  - !ruby/object:Gem::Dependency
104
- name: rspec
104
+ name: activerecord
105
105
  prerelease: false
106
106
  requirement: &id009 !ruby/object:Gem::Requirement
107
107
  none: false
@@ -112,7 +112,7 @@ dependencies:
112
112
  type: :development
113
113
  version_requirements: *id009
114
114
  - !ruby/object:Gem::Dependency
115
- name: sqlite3
115
+ name: rspec
116
116
  prerelease: false
117
117
  requirement: &id010 !ruby/object:Gem::Requirement
118
118
  none: false
@@ -123,7 +123,7 @@ dependencies:
123
123
  type: :development
124
124
  version_requirements: *id010
125
125
  - !ruby/object:Gem::Dependency
126
- name: with_model
126
+ name: sqlite3
127
127
  prerelease: false
128
128
  requirement: &id011 !ruby/object:Gem::Requirement
129
129
  none: false
@@ -133,6 +133,17 @@ dependencies:
133
133
  version: "0"
134
134
  type: :development
135
135
  version_requirements: *id011
136
+ - !ruby/object:Gem::Dependency
137
+ name: with_model
138
+ prerelease: false
139
+ requirement: &id012 !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: "0"
145
+ type: :development
146
+ version_requirements: *id012
136
147
  description: |
137
148
  Cabalist is conceived as a simple way of adding some smarts
138
149
  (machine learning capabilities) to your Ruby on Rails models
@@ -151,32 +162,12 @@ extra_rdoc_files: []
151
162
  files:
152
163
  - .gitignore
153
164
  - .travis.yml
165
+ - .yardopts
154
166
  - Gemfile
155
167
  - LICENSE
156
168
  - README.md
157
169
  - Rakefile
158
170
  - cabalist.gemspec
159
- - doc/Cabalist.html
160
- - doc/Cabalist/ClassifierGenerator.html
161
- - doc/Cabalist/Configuration.html
162
- - doc/Cabalist/Frontend.html
163
- - doc/Cabalist/InstallGenerator.html
164
- - doc/Cabalist/ModelAdditions.html
165
- - doc/Cabalist/Railtie.html
166
- - doc/_index.html
167
- - doc/class_list.html
168
- - doc/css/common.css
169
- - doc/css/full_list.css
170
- - doc/css/style.css
171
- - doc/file.README.html
172
- - doc/file_list.html
173
- - doc/frames.html
174
- - doc/index.html
175
- - doc/js/app.js
176
- - doc/js/full_list.js
177
- - doc/js/jquery.js
178
- - doc/method_list.html
179
- - doc/top-level-namespace.html
180
171
  - lib/cabalist.rb
181
172
  - lib/cabalist/configuration.rb
182
173
  - lib/cabalist/frontend.rb
@@ -201,13 +192,15 @@ files:
201
192
  - lib/generators/cabalist/install/templates/public/images/x_14x14.png
202
193
  - lib/generators/cabalist/install/templates/public/javascripts/cabalist.js
203
194
  - lib/generators/cabalist/install/templates/public/stylesheets/cabalist.css
195
+ - lib/tasks/retrain.rake
204
196
  - spec/cabalist/frontend_spec.rb
205
197
  - spec/cabalist/model_additions_spec.rb
198
+ - spec/cabalist/non_cabalist_model_spec.rb
206
199
  - spec/cabalist/performance_benchmark_spec.rb
207
200
  - spec/spec_helper.rb
208
201
  homepage: http://github.com/marcinwyszynski/cabalist
209
- licenses: []
210
-
202
+ licenses:
203
+ - MIT
211
204
  post_install_message:
212
205
  rdoc_options: []
213
206
 
@@ -218,7 +211,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
211
  requirements:
219
212
  - - ">="
220
213
  - !ruby/object:Gem::Version
221
- version: "0"
214
+ version: 1.9.2
222
215
  required_rubygems_version: !ruby/object:Gem::Requirement
223
216
  none: false
224
217
  requirements:
@@ -235,5 +228,6 @@ summary: Minimum setup machine learning (classification) library for Ruby on Rai
235
228
  test_files:
236
229
  - spec/cabalist/frontend_spec.rb
237
230
  - spec/cabalist/model_additions_spec.rb
231
+ - spec/cabalist/non_cabalist_model_spec.rb
238
232
  - spec/cabalist/performance_benchmark_spec.rb
239
233
  - spec/spec_helper.rb