cabalist 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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