tree_thinking 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +43 -0
- data/README.md +27 -0
- data/lib/tree_thinking.rb +6 -0
- data/lib/tree_thinking/binary_tree.rb +36 -0
- data/lib/tree_thinking/binary_tree_factory.rb +35 -0
- data/lib/tree_thinking/version.rb +3 -0
- data/tree_thinking.gemspec +28 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 12adb5716b0ac77981cfcd8cae52860a948e01f9
|
4
|
+
data.tar.gz: 71a92dca72fb0a22e5b6810adb2818d6cb9b0b6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3468cb179c74602796a835f7a86ba0465f0c11ad08d353d466504917f17a34877672bf02e7777d5c4ccea2c4887987161300acd8a6c74ee6ae25aef72e47e399
|
7
|
+
data.tar.gz: 4e6cbdaddfb3ffe19de423c16abbc6ed072ca83abd3514fedb44e6d069d5aba69dfaebaae35878fba1010dd61cdbf8e12e6e50866a1f7153a0670496ae329f89
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tree_thinking (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.1)
|
10
|
+
diff-lcs (1.2.5)
|
11
|
+
method_source (0.8.2)
|
12
|
+
pry (0.10.4)
|
13
|
+
coderay (~> 1.1.0)
|
14
|
+
method_source (~> 0.8.1)
|
15
|
+
slop (~> 3.4)
|
16
|
+
rake (10.5.0)
|
17
|
+
rspec (3.5.0)
|
18
|
+
rspec-core (~> 3.5.0)
|
19
|
+
rspec-expectations (~> 3.5.0)
|
20
|
+
rspec-mocks (~> 3.5.0)
|
21
|
+
rspec-core (3.5.4)
|
22
|
+
rspec-support (~> 3.5.0)
|
23
|
+
rspec-expectations (3.5.0)
|
24
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
+
rspec-support (~> 3.5.0)
|
26
|
+
rspec-mocks (3.5.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.5.0)
|
29
|
+
rspec-support (3.5.0)
|
30
|
+
slop (3.6.0)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
bundler (~> 1.13)
|
37
|
+
pry
|
38
|
+
rake (~> 10.0)
|
39
|
+
rspec (~> 3.0)
|
40
|
+
tree_thinking!
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
1.13.1
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# The Ruby Gem
|
2
|
+
|
3
|
+
The ruby gem currently supports loading and applying a YAML decision tree. The
|
4
|
+
following example is from the tests and shows how a YAML fixture file is parsed
|
5
|
+
into a `BinaryTree` object:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
tree = TreeThinking::BinaryTreeFactory.from_yaml('./spec/fixtures/simple_tree.yaml')
|
9
|
+
```
|
10
|
+
|
11
|
+
This tree can then be used to get a probability from an answer vector:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
tree.call([1, 0])
|
15
|
+
#> 0.1
|
16
|
+
```
|
17
|
+
|
18
|
+
In this case, the answer vector is `[1,0]`, however another approach that can
|
19
|
+
be used is a `Struct` where the attribute order matches the order of the
|
20
|
+
features in the decision tree. For example:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
Answer = Struct.new(:likes_ice_cream, :likes_chocolate)
|
24
|
+
answer_vector = Answer.new(1,0)
|
25
|
+
tree.call(answer_vector)
|
26
|
+
#> 0.1
|
27
|
+
```
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module TreeThinking
|
2
|
+
class BinaryTree
|
3
|
+
attr_reader :name
|
4
|
+
attr_accessor :tree
|
5
|
+
|
6
|
+
Node = Struct.new(:feature_idx, :operator, :threshold, :probablity, :results)
|
7
|
+
|
8
|
+
def initialize(name: nil)
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(answer_vector)
|
13
|
+
node = self.tree
|
14
|
+
|
15
|
+
while node.probablity.nil? do
|
16
|
+
node = node.results.fetch(decision(node, answer_vector))
|
17
|
+
end
|
18
|
+
|
19
|
+
node.probablity
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def decision(node, answer_vector)
|
25
|
+
case node.operator
|
26
|
+
when '=' then answer_vector[node.feature_idx] == node.threshold
|
27
|
+
when '>' then answer_vector[node.feature_idx] > node.threshold
|
28
|
+
when '<' then answer_vector[node.feature_idx] < node.threshold
|
29
|
+
when '>=' then answer_vector[node.feature_idx] >= node.threshold
|
30
|
+
when '<=' then answer_vector[node.feature_idx] <= node.threshold
|
31
|
+
else
|
32
|
+
answer_vector[node.feature_idx] <= node.threshold
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module TreeThinking
|
4
|
+
class BinaryTreeFactory
|
5
|
+
attr_reader :tree
|
6
|
+
|
7
|
+
def self.from_yaml(path)
|
8
|
+
new(YAML.load(File.read(path))).build!
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(tree)
|
12
|
+
@tree = tree
|
13
|
+
end
|
14
|
+
|
15
|
+
def build!
|
16
|
+
btree = BinaryTree.new(name: tree['class_name'])
|
17
|
+
btree.tree = nodify(tree['tree'])
|
18
|
+
btree
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def nodify(attrs)
|
24
|
+
BinaryTree::Node.new(
|
25
|
+
attrs['feature_idx'],
|
26
|
+
attrs['op'],
|
27
|
+
attrs['thr'],
|
28
|
+
attrs['prob'],
|
29
|
+
Hash[attrs.fetch('results', {}).map do |return_val, child_node|
|
30
|
+
[return_val, nodify(child_node)]
|
31
|
+
end]
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tree_thinking/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tree_thinking"
|
8
|
+
spec.version = TreeThinking::VERSION
|
9
|
+
spec.authors = ["Greggory Rothmeier"]
|
10
|
+
spec.email = ["greggroth@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Language-agnostic binary tree representation parsing and executation}
|
13
|
+
spec.description = %q{Language-agnostic binary tree representation parsing and executation}
|
14
|
+
spec.homepage = ""
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tree_thinking
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greggory Rothmeier
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
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: Language-agnostic binary tree representation parsing and executation
|
70
|
+
email:
|
71
|
+
- greggroth@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- Gemfile.lock
|
79
|
+
- README.md
|
80
|
+
- lib/tree_thinking.rb
|
81
|
+
- lib/tree_thinking/binary_tree.rb
|
82
|
+
- lib/tree_thinking/binary_tree_factory.rb
|
83
|
+
- lib/tree_thinking/version.rb
|
84
|
+
- tree_thinking.gemspec
|
85
|
+
homepage: ''
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.5.1
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Language-agnostic binary tree representation parsing and executation
|
109
|
+
test_files: []
|
110
|
+
has_rdoc:
|