baby_face 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d3c03bdf7d6799c174a0c9c535c6fab41f18bccb
4
+ data.tar.gz: a6919788bac4954f5c982c2ca359e492c5bdfae9
5
+ SHA512:
6
+ metadata.gz: 20a084a3ff38c57b8d480a396a11592285287b632c61172f444bb74a4247bf763865c15a916bdf466d3dcd08d093a415ed7460d00d55d7e7caf0e915fd5de036
7
+ data.tar.gz: 2c4955b4aff1056b0022a21f3838f771aa20f698b34007b7d78024873ca89ee5a483a0788e90d1f428e4ebd6aa3d57734e66fdf498afe8efe1d1ec50b8bde788
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in baby_face.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Yoshiori SHOJI
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # BabyFace
2
+
3
+ baby_face is a simple machine learning module.
4
+
5
+ ![](http://farm3.staticflickr.com/2835/11172696593_2e98d981d0_o.jpg)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'baby_face'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install baby_face
20
+
21
+ ## Usage
22
+
23
+ ### target model( Poro, ActiveModel, ...)
24
+ ```ruby
25
+ class Jedi
26
+ include BabyFace
27
+ acts_as_babyface features: :name,
28
+ categories: [:light_side, :dark_side]
29
+
30
+ attr_accessor :name
31
+ def initialize(name)
32
+ @name = name
33
+ end
34
+ end
35
+ ```
36
+
37
+ ### training
38
+
39
+ ```ruby
40
+ Jedi.new("Anakin Skywalker").babyface.train_light_side
41
+ Jedi.new("Darth Maul").babyface.train_dark_side
42
+ ```
43
+
44
+ ### classify
45
+
46
+ ```ruby
47
+ Jedi.new("Luke Skywalker").babyface.light_side? # => true
48
+ Jedi.new("Darth Vader").babyface.dark_side? # => true
49
+ ```
50
+
51
+ ### save training data
52
+
53
+ ```ruby
54
+ BabyFace.configuration.data_dir = "/tmp/baby_face"
55
+ Jedi.new("Luke Skywalker").babyface.save # => /tmp/baby_face/jedi.babyface
56
+ ```
57
+
58
+
59
+ ## more
60
+ ### tokenizer
61
+ default : String#split
62
+
63
+ ```ruby
64
+ acts_as_babyface features: :name,
65
+ categories: [:ham, :spam],
66
+ tokenizer: ->(text) {[text.upcase]}
67
+
68
+ ```
69
+
70
+ ### nested object
71
+ support nested BabyFace object, array and hash.
72
+
73
+ ```ruby
74
+ class Entry < ActiveRecord::Base
75
+ has_many :comments
76
+ include BabyFace
77
+ acts_as_babyface features: :title, :body, :comments,
78
+ categories: [:ham, :spam]
79
+ end
80
+
81
+ class Comment < ActiveRecord::Base
82
+ include BabyFace
83
+ acts_as_babyface features: :title, :message
84
+ end
85
+ ```
86
+
87
+
88
+ ## Contributing
89
+
90
+ 1. Fork it
91
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
92
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
93
+ 4. Push to the branch (`git push origin my-new-feature`)
94
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/baby_face.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'baby_face/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "baby_face"
8
+ spec.version = BabyFace::VERSION
9
+ spec.authors = ["Yoshiori SHOJI"]
10
+ spec.email = ["yoshiori@gmail.com"]
11
+ spec.description = "baby_face is a simple machine learning module."
12
+ spec.summary = spec.description
13
+ spec.homepage = "https://github.com/yoshiori/baby_face"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "classifier"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
data/bin/baby_face ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baby_face'
@@ -0,0 +1,9 @@
1
+ require "singleton"
2
+
3
+ module BabyFace
4
+ class Configuration
5
+ include Singleton
6
+
7
+ attr_accessor :data_dir
8
+ end
9
+ end
@@ -0,0 +1,92 @@
1
+ require "baby_face/configuration"
2
+ require 'pstore'
3
+ require 'classifier'
4
+
5
+ class BabyFace::Stand
6
+ def initialize(mod)
7
+ @mod = mod
8
+ @categories = mod.class.class_variable_get(:@@_categories)
9
+ @categories.each do |category|
10
+ self.class.class_eval do
11
+ define_method("#{category}?") {
12
+ bayes.classify(to_feature).gsub(" ", "_").downcase == category.to_s
13
+ }
14
+
15
+ define_method("train_#{category}") {
16
+ bayes.train(category, to_feature)
17
+ }
18
+ end
19
+ end
20
+ @tokenizer = mod.class.class_variable_get(:@@_tokenizer)
21
+ end
22
+
23
+ def to_feature
24
+ def scan(prefix, obj)
25
+ obj.class.class_variable_get(:@@_features).map do |attr|
26
+ _prefix = prefix.nil? ? attr : "#{prefix}_#{attr}"
27
+ value = obj.send(attr)
28
+ if value.is_a? BabyFace
29
+ scan(_prefix, value)
30
+ elsif value.is_a? Array
31
+ value.map do |val|
32
+ scan(_prefix, val)
33
+ end
34
+ elsif value.is_a? Hash
35
+ value.map do |key, val|
36
+ scan("#{_prefix}_#{key}", val)
37
+ end
38
+ else
39
+ wakachi(value.to_s).map do |text|
40
+ "#{_prefix}_#{text}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ scan(nil, @mod).flatten.join(" ")
46
+ end
47
+
48
+ def wakachi(text)
49
+ @tokenizer ? @tokenizer.call(text) : text.split
50
+ end
51
+
52
+ def save
53
+ bayes # Memoization (first access is in transaction)
54
+ pstore.transaction do
55
+ pstore[@mod.class.name] = bayes
56
+ pstore.commit
57
+ end
58
+ end
59
+
60
+ private
61
+ def data_path
62
+ if BabyFace.configuration.data_dir
63
+ Pathname.new(BabyFace.configuration.data_dir).join("#{@mod.class.name.downcase}.babyface")
64
+ else
65
+ Pathname.new("#{@mod.class.name.downcase}.babyface")
66
+ end
67
+ end
68
+
69
+ def pstore
70
+ if @mod.class.class_variable_defined?(:@@_pstore)
71
+ @mod.class.class_variable_get(:@@_pstore)
72
+ else
73
+ @mod.class.class_variable_set(:@@_pstore, PStore.new(data_path))
74
+ end
75
+ end
76
+
77
+ def bayes
78
+ if @mod.class.class_variable_defined?(:@@_bayes)
79
+ @mod.class.class_variable_get(:@@_bayes)
80
+ else
81
+ @mod.class.class_variable_set(:@@_bayes,
82
+ if data_path && data_path.exist?
83
+ pstore.transaction(true) do
84
+ pstore[@mod.class.name]
85
+ end
86
+ else
87
+ ::Classifier::Bayes.new *@categories
88
+ end
89
+ )
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,3 @@
1
+ module BabyFace
2
+ VERSION = "0.0.1"
3
+ end
data/lib/baby_face.rb ADDED
@@ -0,0 +1,27 @@
1
+ require "baby_face/stand"
2
+ require "baby_face/configuration"
3
+ require "baby_face/version"
4
+
5
+ module BabyFace
6
+
7
+ def self.configuration
8
+ @configuration ||= Configuration.instance
9
+ end
10
+
11
+ def BabyFace.included(mod)
12
+ mod.define_singleton_method(
13
+ :acts_as_babyface,
14
+ lambda { |config|
15
+ features = *config[:features]
16
+ categories = *config[:categories]
17
+ mod.class_variable_set(:@@_features, features)
18
+ mod.class_variable_set(:@@_categories, categories)
19
+ mod.class_variable_set(:@@_tokenizer, config[:tokenizer])
20
+ }
21
+ )
22
+ end
23
+
24
+ def babyface
25
+ @_babyface ||= BabyFace::Stand.new(self)
26
+ end
27
+ end
@@ -0,0 +1,109 @@
1
+ require "baby_face"
2
+
3
+ describe BabyFace::Stand do
4
+
5
+ describe "#to_feature" do
6
+ subject { target.babyface.to_feature }
7
+
8
+ class Hoge
9
+ include BabyFace
10
+ attr_accessor :title, :name
11
+ acts_as_babyface features: [:title, :name]
12
+
13
+ def initialize(title: "Revenge of the Sith", name: "Anakin Skywalker")
14
+ @title = title
15
+ @name = name
16
+ end
17
+ end
18
+
19
+ class Bar
20
+ include BabyFace
21
+ attr_accessor :attr1, :attr2
22
+ acts_as_babyface features: [:attr1, :attr2]
23
+
24
+ def initialize(attr1: "foo", attr2: "bar")
25
+ @attr1 = attr1
26
+ @attr2 = attr2
27
+ end
28
+ end
29
+
30
+ context "Simple object" do
31
+ let(:target) { Hoge.new }
32
+
33
+ it { should eq "title_Revenge title_of title_the title_Sith name_Anakin name_Skywalker" }
34
+ end
35
+
36
+ context "Nested object" do
37
+ let(:target) { Hoge.new(name: Bar.new) }
38
+
39
+ it { should eq "title_Revenge title_of title_the title_Sith name_attr1_foo name_attr2_bar" }
40
+ end
41
+
42
+ context "Nested array" do
43
+ let(:target) { Hoge.new(name: [Bar.new, Bar.new]) }
44
+
45
+ it { should eq "title_Revenge title_of title_the title_Sith name_attr1_foo name_attr2_bar name_attr1_foo name_attr2_bar" }
46
+ end
47
+
48
+ context "Nested hash" do
49
+ let(:target) { Hoge.new(name: {bar1: Bar.new,bar2: Bar.new}) }
50
+
51
+ it { should eq "title_Revenge title_of title_the title_Sith name_bar1_attr1_foo name_bar1_attr2_bar name_bar2_attr1_foo name_bar2_attr2_bar" }
52
+ end
53
+ end
54
+
55
+ describe "#wakachi" do
56
+ context "Default" do
57
+ class Dummy
58
+ include BabyFace
59
+ attr_accessor :name
60
+ acts_as_babyface features: :name
61
+ end
62
+ let(:babyface) { Dummy.new.babyface }
63
+
64
+ it { expect(babyface.wakachi("aaa bbb")).to eq ["aaa", "bbb"] }
65
+ end
66
+
67
+ context "Use tokenizer" do
68
+ class Dummy2
69
+ include BabyFace
70
+ attr_accessor :name
71
+ acts_as_babyface features: :name,
72
+ tokenizer: ->(text) {[text.upcase]}
73
+
74
+ end
75
+ let(:babyface) { Dummy2.new.babyface }
76
+
77
+ it { expect(babyface.wakachi("aaa bbb")).to eq ["AAA BBB"] }
78
+ end
79
+ end
80
+
81
+ describe "#train" do
82
+ class Jedi
83
+ include BabyFace
84
+ attr_accessor :name
85
+ acts_as_babyface features: :name,
86
+ categories: [:light_side, :dark_side]
87
+
88
+ def initialize(name)
89
+ @name = name
90
+ end
91
+ end
92
+
93
+ it 'train jedi' do
94
+ 10.times {
95
+ Jedi.new("Anakin Skywalker").babyface.train_light_side
96
+ }
97
+
98
+ 10.times {
99
+ Jedi.new("Darth Maul").babyface.train_dark_side
100
+ }
101
+
102
+ luke = Jedi.new("Luke Skywalker")
103
+ vader = Jedi.new("Darth Vader")
104
+
105
+ expect(luke.babyface).to be_light_side
106
+ expect(vader.babyface).to be_dark_side
107
+ end
108
+ end
109
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: baby_face
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yoshiori SHOJI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: classifier
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: baby_face is a simple machine learning module.
70
+ email:
71
+ - yoshiori@gmail.com
72
+ executables:
73
+ - baby_face
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - baby_face.gemspec
83
+ - bin/baby_face
84
+ - lib/baby_face.rb
85
+ - lib/baby_face/configuration.rb
86
+ - lib/baby_face/stand.rb
87
+ - lib/baby_face/version.rb
88
+ - spec/baby_face/stand_spec.rb
89
+ homepage: https://github.com/yoshiori/baby_face
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.0.0
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: baby_face is a simple machine learning module.
113
+ test_files:
114
+ - spec/baby_face/stand_spec.rb