lib/hiccup/inferable/scorer.rb
module Hiccup
module Inferable
class Scorer
def initialize(options={})
@verbose = options.fetch(:verbose, false)
end
def pick_best_guess(guesses, dates)
scored_guesses = guesses \
.map { |guess| [guess, score_guess(guess, dates)] } \
.sort_by { |(guess, score)| -score.to_f }
if @verbose
puts "\nGUESSES FOR #{dates}:"
scored_guesses.each do |(guess, score)|
puts " (%.3f p/%.3f b/%.3f c/%.3f) #{guess.humanize}" % [
score.to_f,
score.prediction_rate,
score.brick_penalty,
score.complexity_penalty]
end
puts ""
end
scored_guesses.first
end
def score_guess(guess, input_dates)
predicted_dates = guess.occurrences_between(guess.start_date, guess.end_date)
# prediction_rate is the percent of input dates predicted
predictions = (predicted_dates & input_dates).length
prediction_rate = Float(predictions) / Float(input_dates.length)
# bricks are dates predicted by this guess but not in the input
bricks = (predicted_dates - input_dates).length
# brick_rate is the percent of bricks to predictions
# A brick_rate >= 1 means that this guess bricks more than it predicts
brick_rate = Float(bricks) / Float(input_dates.length)
# complexity measures how many rules are necesary
# to describe the pattern
complexity = complexity_of(guess)
# complexity_rate is the number of rules per inputs
complexity_rate = Float(complexity) / Float(input_dates.length)
Score.new(prediction_rate, brick_rate, complexity_rate)
end
def complexity_of(schedule)
return schedule.weekly_pattern.length if schedule.weekly?
return schedule.monthly_pattern.length if schedule.monthly?
1
end
end
end
end