14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
# File 'lib/hiccup/inferable.rb', line 14
def infer(dates, options={})
allow_null_schedules = options.fetch(:allow_null_schedules, false)
verbosity = options.fetch(:verbosity, (options[:verbose] ? 1 : 0))
dates = (dates)
enumerator = DatesEnumerator.new(dates)
guesser = Guesser.new(self, {verbose: verbosity >= 2})
schedules = []
confidences = []
high_confidence_threshold = 0.6
min_confidence_threshold = 0.35
last_confident_schedule = nil
iterations_since_last_confident_schedule = 0
until enumerator.done?
date = enumerator.next
guesser << date
confidence = guesser.confidence.to_f
confidences << confidence
predicted = guesser.predicted?(date)
confident = !(confidences.length >= 3 && (
(confidences[-1] < high_confidence_threshold &&
confidences[-2] < high_confidence_threshold &&
confidences[-1] < confidences[-2] &&
confidences[-2] < confidences[-3]) ||
(confidences[-1] < min_confidence_threshold &&
confidences[-2] < min_confidence_threshold)))
if predicted && confidence >= min_confidence_threshold
iterations_since_last_confident_schedule = 0
last_confident_schedule = guesser.schedule
else
iterations_since_last_confident_schedule += 1
end
rewind_by = iterations_since_last_confident_schedule == guesser.count ? iterations_since_last_confident_schedule - 1 : iterations_since_last_confident_schedule
if verbosity >= 1
output = " #{enumerator.index.to_s.rjust(3)} #{date}"
output << " #{"[#{guesser.count}]".rjust(5)} => "
output << "~#{(guesser.confidence.to_f * 100).to_i.to_s.rjust(2, "0")} @ "
output << guesser.schedule.humanize.ljust(130)
output << " :( move back #{rewind_by}" unless confident
puts output
end
unless confident
if last_confident_schedule
schedules << last_confident_schedule
elsif allow_null_schedules
guesser.dates.take(guesser.count - rewind_by).each do |date|
schedules << self.new(:kind => :never, :start_date => date)
end
end
enumerator.rewind_by(rewind_by)
guesser.restart!
confidences = []
iterations_since_last_confident_schedule = 0
last_confident_schedule = nil
end
end
if last_confident_schedule
schedules << last_confident_schedule
elsif allow_null_schedules
guesser.dates.each do |date|
schedules << self.new(:kind => :never, :start_date => date)
end
end
schedules
end
|