class Ai4r::Classifiers::Hyperpipes

Introduction

A fast classifier algorithm, created by Lucio de Souza Coelho and Len Trigg.

Attributes

data_set[R]
pipes[R]

Public Instance Methods

build(data_set) click to toggle source

Build a new Hyperpipes classifier. You must provide a DataSet instance as parameter. The last attribute of each item is considered as the item class.

# File lib/ai4r/classifiers/hyperpipes.rb, line 30
def build(data_set)
  data_set.check_not_empty
  @data_set = data_set
  @domains = data_set.build_domains
  
  @pipes = {}
  @domains.last.each {|cat| @pipes[cat] = build_pipe(@data_set)}
  @data_set.data_items.each {|item| update_pipe(@pipes[item.last], item) }
  
  return self
end
eval(data) click to toggle source

You can evaluate new data, predicting its class. e.g.

classifier.eval(['New York',  '<30', 'F'])  # => 'Y'
# File lib/ai4r/classifiers/hyperpipes.rb, line 45
def eval(data)
  votes = Hash.new {0}
  @pipes.each do |category, pipe|
    pipe.each_with_index do |bounds, i|
      if data[i].is_a? Numeric
        votes[category]+=1 if data[i]>=bounds[:min] && data[i]<=bounds[:max]
      else
        votes[category]+=1 if bounds[data[i]]
      end
    end
  end
  return votes.to_a.max {|x, y| x.last <=> y.last}.first
end
get_rules() click to toggle source

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 == '[30-50)' then marketing_target = 'N'
        elsif age_range == '[50-80]' then marketing_target = 'N'
        end

It is a nice way to inspect induction results, and also to execute them:

marketing_target = nil
eval classifier.get_rules   
puts marketing_target
  # =>  'Y'
# File lib/ai4r/classifiers/hyperpipes.rb, line 73
def get_rules
  rules = []
  rules << "votes = Hash.new {0}"
  data = @data_set.data_items.first
  labels = @data_set.data_labels.collect {|l| l.to_s}
  @pipes.each do |category, pipe|
    pipe.each_with_index do |bounds, i|
      rule = "votes['#{category}'] += 1 "
      if data[i].is_a? Numeric
        rule += "if #{labels[i]} >= #{bounds[:min]} && #{labels[i]} <= #{bounds[:max]}"
      else
        rule += "if #{bounds.inspect}[#{labels[i]}]"
      end
      rules << rule
    end
  end
  rules << "#{labels.last} = votes.to_a.max {|x, y| x.last <=> y.last}.first"
  return rules.join("\n")
end

Protected Instance Methods

build_pipe(data_set) click to toggle source
# File lib/ai4r/classifiers/hyperpipes.rb, line 95
def build_pipe(data_set)
  data_set.data_items.first[0...-1].collect do |att|
    if att.is_a? Numeric
      {:min=>1.0/0, :max=>-1.0/0}
    else
      Hash.new(false)
    end
  end
end
update_pipe(pipe, data_item) click to toggle source
# File lib/ai4r/classifiers/hyperpipes.rb, line 105
def update_pipe(pipe, data_item)
  data_item[0...-1].each_with_index do |att, i|
    if att.is_a? Numeric
      pipe[i][:min] = att if att < pipe[i][:min]
      pipe[i][:max] = att if att > pipe[i][:max]
    else
      pipe[i][att] = true
    end  
  end
end