Method: Evoc::Evaluate.average_precision
- Defined in:
- lib/evoc/evaluate.rb
.average_precision(recommendation, expected_outcome) ⇒ Float
calculate the average precision of the result based on an expected outcome
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/evoc/evaluate.rb', line 281 def self.average_precision(recommendation,expected_outcome) raise Error.new "#average_precision has been deprecated, use #ap instead" if !expected_outcome.is_a?(Array) then expected_outcome = [expected_outcome] end if (expected_outcome.size > 0) & !recommendation.empty? average_precision = 0 correct_items = [] total_items_considered = [] # sort rules by weight # we first group rules with equal weights # and then sort the groups by weight recommendation.each do |items| if !items.is_a?(Array) then items = [items] end if items.first.class != expected_outcome.first.class raise ArgumentError, "Expected outcome was of type #{expected_outcome.first.class}, while the item in the recommendation was of type #{items.first.class}" end # skip already considered items if (new_items = items - total_items_considered).size > 0 new_items.each {|item| total_items_considered << item} if correct_in_rule = (items & expected_outcome) if correct_in_rule.size > 0 # make sure that the new items havent already been added earlier new_correct = (correct_in_rule - correct_items) # add new items new_correct.each {|item| correct_items << item} change_in_recall = new_correct.size.to_r/expected_outcome.size precision_at_k = correct_items.size.to_r/total_items_considered.size average_precision += (precision_at_k * change_in_recall) end end end end average_precision.to_f else nil end end |