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:
parent
30087beb72
commit
868303e5d9
|
@ -49,7 +49,8 @@ class ReviewableScore < ActiveRecord::Base
|
||||||
# 1.0 + trust_level + user_accuracy_bonus
|
# 1.0 + trust_level + user_accuracy_bonus
|
||||||
# (trust_level is 5 for staff)
|
# (trust_level is 5 for staff)
|
||||||
def self.user_flag_score(user)
|
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
|
end
|
||||||
|
|
||||||
# A user's accuracy bonus is:
|
# A user's accuracy bonus is:
|
||||||
|
@ -68,8 +69,22 @@ class ReviewableScore < ActiveRecord::Base
|
||||||
|
|
||||||
total = (agreed + disagreed).to_f
|
total = (agreed + disagreed).to_f
|
||||||
return 0.0 if total <= 5
|
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
|
end
|
||||||
|
|
||||||
def reviewable_conversation
|
def reviewable_conversation
|
||||||
|
|
|
@ -102,16 +102,48 @@ RSpec.describe ReviewableScore, type: :model do
|
||||||
expect(ReviewableScore.user_accuracy_bonus(user)).to eq(0.0)
|
expect(ReviewableScore.user_accuracy_bonus(user)).to eq(0.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns (agreed_flags / total) * 5.0" do
|
it "returns the users weighted accuracy bonus" do
|
||||||
user_stat.flags_agreed = 4
|
user_stat.flags_agreed = 10
|
||||||
user_stat.flags_disagreed = 2
|
user_stat.flags_disagreed = 42
|
||||||
expect(ReviewableScore.user_accuracy_bonus(user).floor(2)).to eq(3.33)
|
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
|
# Ignored flags don't count
|
||||||
user_stat.flags_agreed = 121
|
user_stat.flags_agreed = 121
|
||||||
user_stat.flags_disagreed = 44
|
user_stat.flags_disagreed = 44
|
||||||
user_stat.flags_ignored = 4
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -138,7 +170,14 @@ RSpec.describe ReviewableScore, type: :model do
|
||||||
user_stat.flags_agreed = 12
|
user_stat.flags_agreed = 12
|
||||||
user_stat.flags_disagreed = 2
|
user_stat.flags_disagreed = 2
|
||||||
user_stat.flags_ignored = 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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue