FEATURE: Weighted reviewable user accuracy (#8156)

* FEATURE: Inaccurate users have negative review accuracy

* FIX: disallow negative reviewable score even if the accuracy would make it negative
This commit is contained in:
Mark VanLandingham 2019-10-04 14:10:56 -05:00 committed by Robin Ward
parent 30087beb72
commit 868303e5d9
2 changed files with 62 additions and 8 deletions

View File

@ -49,7 +49,8 @@ class ReviewableScore < ActiveRecord::Base
# 1.0 + trust_level + user_accuracy_bonus
# (trust_level is 5 for staff)
def self.user_flag_score(user)
1.0 + (user.staff? ? 5.0 : user.trust_level.to_f) + user_accuracy_bonus(user)
score = 1.0 + (user.staff? ? 5.0 : user.trust_level.to_f) + user_accuracy_bonus(user)
score >= 0 ? score : 0
end
# A user's accuracy bonus is:
@ -68,8 +69,22 @@ class ReviewableScore < ActiveRecord::Base
total = (agreed + disagreed).to_f
return 0.0 if total <= 5
accuracy_axis = 0.7
(agreed / total) * 5.0
percent_correct = agreed / total
positive_accuracy = percent_correct >= accuracy_axis
bottom = positive_accuracy ? accuracy_axis : 0.0
top = positive_accuracy ? 1.0 : accuracy_axis
absolute_distance = positive_accuracy ?
percent_correct - bottom :
top - percent_correct
axis_distance_multiplier = 1.0 / (top - bottom)
positivity_multiplier = positive_accuracy ? 1.0 : -1.0
absolute_distance * axis_distance_multiplier * positivity_multiplier * (Math.log(total, 4) * 5.0)
end
def reviewable_conversation

View File

@ -102,16 +102,48 @@ RSpec.describe ReviewableScore, type: :model do
expect(ReviewableScore.user_accuracy_bonus(user)).to eq(0.0)
end
it "returns (agreed_flags / total) * 5.0" do
user_stat.flags_agreed = 4
user_stat.flags_disagreed = 2
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(3.33)
it "returns the users weighted accuracy bonus" do
user_stat.flags_agreed = 10
user_stat.flags_disagreed = 42
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(-10.34)
user_stat.flags_agreed = 2
user_stat.flags_disagreed = 12
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(-7.58)
user_stat.flags_agreed = 1
user_stat.flags_disagreed = 6
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(-5.59)
user_stat.flags_agreed = 2
user_stat.flags_disagreed = 4
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(-3.39)
user_stat.flags_agreed = 7
user_stat.flags_disagreed = 3
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(0)
user_stat.flags_agreed = 14
user_stat.flags_disagreed = 6
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(0)
# Ignored flags don't count
user_stat.flags_agreed = 121
user_stat.flags_disagreed = 44
user_stat.flags_ignored = 4
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(3.66)
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(2.04)
user_stat.flags_agreed = 9
user_stat.flags_disagreed = 2
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(3.40)
user_stat.flags_agreed = 25
user_stat.flags_disagreed = 4
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(6.56)
user_stat.flags_agreed = 120
user_stat.flags_disagreed = 12
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(12.27)
end
end
@ -138,7 +170,14 @@ RSpec.describe ReviewableScore, type: :model do
user_stat.flags_agreed = 12
user_stat.flags_disagreed = 2
user_stat.flags_ignored = 2
expect(ReviewableScore.user_flag_score(user).floor(2)).to eq(7.28)
expect(ReviewableScore.user_flag_score(user).floor(2)).to eq(7.98)
end
it 'return 0 if the accuracy_bonus would make the score negative' do
user.trust_level = 3
user_stat.flags_agreed = 0
user_stat.flags_disagreed = 1000
expect(ReviewableScore.user_flag_score(user)).to eq(0)
end
end
end