Class: Ai4r::Classifiers::Prism
- Inherits:
-
Classifier
- Object
- Classifier
- Ai4r::Classifiers::Prism
- Defined in:
- lib/ai4r/classifiers/prism.rb
Overview
Introduction
This is an implementation of the PRISM algorithm (Cendrowska, 1987) Given a set of preclassified examples, it builds a set of rules to predict the class of other instaces.
-
Cendrowska (1987). PRISM: An algorithm for inducing modular rules.
International Journal of Man-Machine Studies. 27(4):349-370.
Instance Attribute Summary collapse
-
#data_set ⇒ Object
readonly
Returns the value of attribute data_set.
-
#majority_class ⇒ Object
readonly
Returns the value of attribute majority_class.
-
#rules ⇒ Object
readonly
Returns the value of attribute rules.
Instance Method Summary collapse
-
#build(data_set) ⇒ Object
Build a new Prism classifier.
-
#eval(instace) ⇒ Object
You can evaluate new data, predicting its class.
-
#get_rules ⇒ Object
This method returns the generated rules in ruby code.
-
#initialize ⇒ Prism
constructor
A new instance of Prism.
Methods included from Data::Parameterizable
#get_parameters, included, #set_parameters
Constructor Details
#initialize ⇒ Prism
Returns a new instance of Prism.
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/ai4r/classifiers/prism.rb', line 38 def initialize super() @fallback_class = nil @bin_count = 10 @attr_bins = {} @default_class = nil @tie_break = :first @bin_count = 10 @attr_bins = {} end |
Instance Attribute Details
#data_set ⇒ Object (readonly)
Returns the value of attribute data_set.
29 30 31 |
# File 'lib/ai4r/classifiers/prism.rb', line 29 def data_set @data_set end |
#majority_class ⇒ Object (readonly)
Returns the value of attribute majority_class.
29 30 31 |
# File 'lib/ai4r/classifiers/prism.rb', line 29 def majority_class @majority_class end |
#rules ⇒ Object (readonly)
Returns the value of attribute rules.
29 30 31 |
# File 'lib/ai4r/classifiers/prism.rb', line 29 def rules @rules end |
Instance Method Details
#build(data_set) ⇒ Object
Build a new Prism classifier. You must provide a DataSet instance as parameter. The last attribute of each item is considered as the item class.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ai4r/classifiers/prism.rb', line 55 def build(data_set) data_set.check_not_empty @data_set = data_set freqs = Hash.new(0) @data_set.data_items.each { |item| freqs[item.last] += 1 } @majority_class = freqs.max_by { |_, v| v }&.first @fallback_class = @default_class if @default_class @fallback_class = @majority_class if @fallback_class.nil? domains = @data_set.build_domains @attr_bins = {} domains[0...-1].each_with_index do |domain, i| @attr_bins[@data_set.data_labels[i]] = discretize_range(domain, @bin_count) if domain.is_a?(Array) && domain.length == 2 && domain.all? { |v| v.is_a? Numeric } end instances = @data_set.data_items.collect { |data| data } @rules = [] domains.last.each do |class_value| while class_value?(instances, class_value) rule = build_rule(class_value, instances) @rules << rule instances = instances.reject { |data| matches_conditions(data, rule[:conditions]) } end end self end |
#eval(instace) ⇒ Object
You can evaluate new data, predicting its class. e.g.
classifier.eval(['New York', '<30', 'F']) # => 'Y'
87 88 89 90 91 92 |
# File 'lib/ai4r/classifiers/prism.rb', line 87 def eval(instace) @rules.each do |rule| return rule[:class_value] if matches_conditions(instace, rule[:conditions]) end @default_class || @fallback_class end |
#get_rules ⇒ Object
This method returns the generated rules in ruby code. e.g.
classifier.get_rules
# => if age_range == '<30' then marketing_target = 'Y'
elsif age_range == '>80' then marketing_target = 'Y'
elsif city == 'Chicago' and age_range == '[30-50)' then marketing_target = 'Y'
else marketing_target = 'N'
end
It is a nice way to inspect induction results, and also to execute them:
age_range = '[30-50)'
city = 'New York'
eval(classifier.get_rules)
puts marketing_target
'Y'
111 112 113 114 115 116 117 118 119 |
# File 'lib/ai4r/classifiers/prism.rb', line 111 def get_rules out = "if #{join_terms(@rules.first)} then #{then_clause(@rules.first)}" @rules[1...-1].each do |rule| out += "\nelsif #{join_terms(rule)} then #{then_clause(rule)}" end out += "\nelse #{then_clause(@rules.last)}" if @rules.size > 1 out += "\nend" out end |