No commit activity in last 3 years
No release in over 3 years
Weighted majority voting system for qualitative (categorical) items (i.e.assuming the set of decision has no natural ordering). As a measure of the quality of the consensus/inter-agreement, you can choose between a weighted variant of fleiss Kappa (by default) or the entropy of the vote distribution
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0

Runtime

 Project Readme

Acts_as_Meritocracy¶ ↑

Mixin enabling a weighted majority voting system for any model with qualitative decisions/categories. As measure of consensus/inter-rater agreement, you can choose between a weighted variant of the Fleiss’s Kappa (by default) or the entropy of the distribution of votes. The consensus score is in the interval [0,1]. very high consensus=1 , very low consensus=0

NOTE: this voting system has been developed to take (collective) a decision about items, not rank items (e.g. by popularity). i.e. generally once a certain level of consensus is reached on a given item, a decision is taken and the vote is close.

scenario¶ ↑

You have a set of items and would like to classify them according to n predefined categories. For that you ask the opinion of the public. Since some people are better/more reliable than others, their votes can be weighted so they have more power in the collective decision.

installation¶ ↑

To use it, add it to your Gemfile:

gem 'acts_as_meritocracy'

Usage¶ ↑

class Item < ActiveRecord::Base
  act_as_meritocracy
end

item = Item.create()

#user1 votes for the decision 4,  by default the vote_weight=1
item.submit_vote(user1, 4)

# user2 votes for the decision 1 with a vote_weight=2. A vote_weight=2 means that
# the voter has a vote equal to 2 normal voters (vote_weight=1)
item.submit_vote(user2, 1, 2)

# user1 can change/update her vote
item.submit_vote(user1, 1)

# user3 votes for decision 2
item.submit_vote(user3, 2)

# user4 votes for decision 2
item.submit_vote(user4, 3,5)

# getting the most (weighted) voted decision
# tie management: you can manage tie with 2 methods
#  - best_decision("random") (by default) returns randomly one of the categories having the same highest frequency
#  - best_desion("nodecision") returns nil if a tie is detected
item.best_decision
=>3

# getting the number of votes - with the weight
item.nb_votes(true)
=> 1 + 2 + 1 + 5 = 9

# getting the number of votes - without taking into account the weight
item.nb_votes(false)
=> 1 + 1 + 1 + 1 = 4

# getting the frequency distribution of the decisions [{:decision1=>freq1},{:decision1=>freq2}, ..,].
# the frequency takes into account the vote weight.
item.vote_distribution
=> [ {vote => 1, freq => 3},{vote => 2, freq => 1},{vote => 3,freq => 5} ]

# computing the consensus score based on the vote distribution
# by default I used a variante of the Fleiss Kappa metrics
item.consensus
=> 0.361
# Alternative: computing an entropy-based measure of the consensus
# (A perfect disagreement between 2 categories gives a higher score
# than for 10 categories, less predictable)
item.consensus("entropy")
=>0.063

# retrieving the list of votes {decision, vote_weight).
# so item.votes.where(:vote=>1) retrieves the list of votes having decision=1
item.votes
=> [Vote1<>.,Vote2<>., .., Voten<>. ]

# getting all the items voted by user1
item.voted_by?(user1)
=> yes

# getting all the items voted by user1
Item.voted_by(user1)
=>[item]