mmac 0.0.1

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.
@@ -0,0 +1,18 @@
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
+ test/file
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'pry'
4
+ gem 'ruby-progressbar'
5
+ # Specify your gem's dependencies in mmac.gemspec
6
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Thanh Nguyen
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.
@@ -0,0 +1,29 @@
1
+ # Mmac
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mmac'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mmac
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ require "mmac/version"
2
+ require "mmac/framework"
3
+
4
+ module Mmac
5
+
6
+ end
File without changes
@@ -0,0 +1,180 @@
1
+ require File.dirname( __FILE__ ) + "/rule"
2
+ require 'ruby-progressbar'
3
+ module Mmac
4
+ #
5
+ # Main Manager for MMac (contains all options, rules, ...)
6
+ #
7
+ #
8
+ class Framework
9
+ #
10
+ # @return Array of data
11
+ #
12
+ attr_accessor :data
13
+ #
14
+ # @return number of data column except Label
15
+ #
16
+ attr_accessor :attrCount
17
+ #
18
+ # @return minSupp
19
+ #
20
+ attr_accessor :minSupp
21
+ #
22
+ # @return minConf
23
+ #
24
+ attr_accessor :minConf
25
+ #
26
+ # @return Array of Filter rules
27
+ #
28
+ attr_accessor :filters
29
+ #
30
+ # @return Array of Filter rules
31
+ #
32
+ attr_accessor :filtersPrint
33
+
34
+ def initialize inputFile, minSupp, minConf
35
+ @inputFile = inputFile
36
+ @data = []
37
+ @rules = []
38
+ @filters = []
39
+ @filtersPrint = []
40
+ @minSupp = minSupp
41
+ @minConf = minConf
42
+ @level = 0
43
+
44
+ puts ("MIN_SUPP: #{minSupp} - MIN_CONF: #{minConf}")
45
+ puts 'Input from file...'
46
+ parse_data(inputFile)
47
+ @attrCount = @data.first.conditions.count
48
+ puts ("Number of data: " + "#{@data.count}")
49
+ puts ("Number of attr: " + "#{@attrCount}")
50
+ end
51
+
52
+ def run
53
+ puts 'Learning...'
54
+ self.normalize
55
+ puts ("Total rules: " + "#{@filters.count}")
56
+ puts 'Done!'
57
+ # Write to Filter file
58
+ filtersPrint = @filters.map{|p| p.clone}
59
+ filtersPrint.each do |filter|
60
+ hash = Hash[filter.conditions]
61
+ filter.conditions = (0..(@attrCount-1)).map{|index| hash[index] || ""}
62
+ end
63
+ File.open(File.dirname(@inputFile) + '/filter.txt', 'w') {|f| f.write(filtersPrint.map{|p| p.conditions.join(",") + "," + p.labels}.join("\n"))}
64
+ end
65
+
66
+ def parse_data inputFile
67
+ line_array = File.readlines(inputFile)
68
+ line_array.each do |line|
69
+ *conditions, label = line.strip.split(',')
70
+ @data << Rule.new(Array[(0...conditions.size).zip conditions].flatten(1), label)
71
+ end
72
+ end
73
+
74
+ def normalize
75
+ # Apriori
76
+ filterSet = []
77
+ blackList = []
78
+ dataCount = @data.count
79
+ @level = @level + 1
80
+ puts ("Level " + "#{@level}")
81
+
82
+ 1.upto(attrCount).flat_map do |n|
83
+ rules = []
84
+ filterCount = filterSet.count
85
+ @data.each do |data|
86
+ conditions = data.conditions
87
+ label = data.labels
88
+
89
+ # All combinations with n attrs
90
+ combinations = conditions.combination(n)
91
+
92
+ bList = blackList.map {|b| b.conditions if b.labels == label}.compact
93
+ rules += combinations.select{|c| !c.contain_any_in?(bList)}.map{|c| Rule.new(c, label)} # Remove all combinations that in blacklist
94
+ sleep 0.001
95
+ end
96
+
97
+ # collect conditions without dup
98
+ conRules = rules.map{|r| r.conditions}.uniq
99
+ # break if have 0 rules
100
+ break if conRules.count == 0
101
+
102
+ # Log using progressbar
103
+ progressbar = ProgressBar.create(:title => "N = #{n}", :starting_at => 0, :total => conRules.count, :length => 100)
104
+
105
+ conRules.each do |c|
106
+ # increase
107
+ progressbar.increment
108
+
109
+ arr = rules.select{|r| r.conditions == c}
110
+ actOccr = data.count{|d| (c - d.conditions).empty?}
111
+
112
+ set = arr.map{|a| a.labels}.uniq
113
+ set.each do |s|
114
+ suppCount = arr.count{|a| a.labels == s}
115
+ # Calculate sup and conf
116
+ supp = suppCount.fdiv(dataCount)
117
+ conf = suppCount.fdiv(actOccr)
118
+
119
+ if supp >= minSupp && conf >= minConf
120
+ filterSet << Rule.new(c, s, supp, conf, actOccr)
121
+ elsif supp < minSupp
122
+ blackList << Rule.new(c, s)
123
+ end
124
+ end
125
+
126
+ sleep 0.03
127
+ end
128
+ # break if all new combinations is < minSupp and minConf
129
+ break if filterSet.count == filterCount
130
+ sleep 0.05
131
+ end
132
+
133
+ originalOrder = filterSet.clone
134
+ filterSet = filterSet.sort_by{|s| [-s.conf, -s.supp, -s.actOccr, s.conditions.count, originalOrder.index(s)]}
135
+ @filters += filterSet
136
+ filterSet.each do |filter|
137
+ # Remove data that contain filter create T'
138
+ @data -= @data.select{|data| data.labels == filter.labels && (filter.conditions - data.conditions).empty?}
139
+ end
140
+
141
+ # Log Number of rule in level
142
+ puts ("Number of rules: " + "#{filterSet.count}")
143
+ # recursive until Data empty
144
+ if !@data.empty? && !filterSet.empty?
145
+ self.normalize
146
+ end
147
+
148
+ end
149
+
150
+ def set_label sample_file
151
+ test = []
152
+ line_array = File.readlines(sample_file)
153
+ line_array.each do |line|
154
+ conditions = line.strip.split(',')
155
+ rule = Rule.new(Array[(0...conditions.size).zip conditions].flatten(1), "")
156
+ # set label for test data
157
+ @filters.each do |filter|
158
+ if (filter.conditions - rule.conditions).empty?
159
+ rule.labels = filter.labels
160
+ break
161
+ end
162
+ end
163
+ test << rule
164
+ end
165
+ File.open(File.dirname(sample_file) + '/testOut.txt', 'w') {|f| f.write(test.map{|p| p.conditions.map{|c| c[1]}.join(",") + "," + p.labels}.join("\n"))}
166
+ end
167
+
168
+ end
169
+ end
170
+
171
+ class Array
172
+ def contain_any_in?(arrayOfOther)
173
+ arrayOfOther.each do |p|
174
+ if (p - self).empty?
175
+ return true
176
+ end
177
+ end
178
+ return false
179
+ end
180
+ end
@@ -0,0 +1,47 @@
1
+ module Mmac
2
+ #
3
+ # Main Data/Rule for MMac (in here is mushroom, ...)
4
+ #
5
+ #
6
+ class Rule
7
+ #
8
+ # @return Array of conditions
9
+ #
10
+ attr_accessor :conditions
11
+ #
12
+ # @return array of labels: result of these conditions
13
+ #
14
+ attr_accessor :labels
15
+ #
16
+ # @return Supp of rule
17
+ #
18
+ attr_accessor :supp
19
+ #
20
+ # @return Conf of rule
21
+ #
22
+ attr_accessor :conf
23
+ #
24
+ # @return actOccr
25
+ #
26
+ attr_accessor :actOccr
27
+
28
+ def initialize (conditions, labels, *option)
29
+ @conditions = conditions
30
+ @labels = labels
31
+ if !option.empty?
32
+ @supp = option[0]
33
+ @conf = option[1]
34
+ @actOccr = option[2]
35
+ end
36
+ end
37
+
38
+ def ==(other)
39
+ self.conditions == other.conditions && self.labels == other.labels
40
+ end
41
+
42
+ def isParent?(other)
43
+ (self.conditions - other.conditions).empty? && self.labels == other.labels
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Mmac
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mmac/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "mmac"
8
+ gem.version = Mmac::VERSION
9
+ gem.authors = ["Thanh Nguyen"]
10
+ gem.email = ["congthanh991@gmail.com"]
11
+ gem.description = ["MMAC Project"]
12
+ gem.summary = ["MMAC Library"]
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_dependency 'pry'
20
+ gem.add_dependency 'ruby-progressbar'
21
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require_relative '../lib/mmac'
5
+
6
+ puts 'Run program...'
7
+ MIN_SUPP = 0.2
8
+ MIN_CONF = 0.4
9
+ framework = Mmac::Framework.new(File.dirname( __FILE__ ) + '/file/data.txt', MIN_SUPP, MIN_CONF)
10
+ framework.run
11
+
12
+ puts 'Run Data Test'
13
+ framework.set_label(File.dirname( __FILE__ ) + '/file/test.txt')
14
+
15
+ f1 = IO.readlines(File.dirname( __FILE__ ) + "/file/testOut.txt").map(&:chomp)
16
+ f2 = IO.readlines(File.dirname( __FILE__ ) + "/file/data.txt" ).map(&:chomp)
17
+
18
+ diff = f1 - f2
19
+ puts ("Number of diff: #{diff.count}")
20
+ puts ("Percent of success test: #{((1 - diff.count.fdiv(f1.count))*100).round(2)}%")
21
+
22
+ File.open(File.dirname( __FILE__ ) + "/file/diff.txt","w"){ |f| f.write(diff.join("\n")) }
23
+
24
+ puts 'Done!'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mmac
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thanh Nguyen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: pry
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: ruby-progressbar
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ! '["MMAC Project"]'
47
+ email:
48
+ - congthanh991@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - lib/mmac.rb
59
+ - lib/mmac/cache/filter.txt
60
+ - lib/mmac/framework.rb
61
+ - lib/mmac/rule.rb
62
+ - lib/mmac/version.rb
63
+ - mmac.gemspec
64
+ - test/file/data.txt
65
+ - test/file/diff.txt
66
+ - test/file/domain.txt
67
+ - test/file/filter.txt
68
+ - test/file/test.txt
69
+ - test/file/testOut.txt
70
+ - test/test.rb
71
+ homepage: ''
72
+ licenses: []
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 1.8.24
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: ! '["MMAC Library"]'
95
+ test_files:
96
+ - test/file/data.txt
97
+ - test/file/diff.txt
98
+ - test/file/domain.txt
99
+ - test/file/filter.txt
100
+ - test/file/test.txt
101
+ - test/file/testOut.txt
102
+ - test/test.rb
103
+ has_rdoc: