Skip to content

Instantly share code, notes, and snippets.

@jonmagic
Created December 1, 2019 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonmagic/f36540424f7618118041411e435a6e72 to your computer and use it in GitHub Desktop.
Save jonmagic/f36540424f7618118041411e435a6e72 to your computer and use it in GitHub Desktop.
class Reputation
class Error < StandardError; end
def initialize(sample_size:, not_spammy_sample_size:)
@sample_size = sample_size
@not_spammy_sample_size = not_spammy_sample_size
end
attr_reader :sample_size
attr_reader :not_spammy_sample_size
def spammy_sample_size
sample_size - not_spammy_sample_size
end
def reputation
calculations[0]
end
def reputation_lower_bound
calculations[2].round(4)
end
def plus_minus
calculations[1]
end
def minimum_reputation
minimum_reputation = reputation - plus_minus
minimum_reputation < 0 ? 0.0 : minimum_reputation
end
def maximum_reputation
maximum_reputation = reputation + plus_minus
maximum_reputation > 1 ? 1.0 : maximum_reputation
end
# Models reputation as the estimated proportion of good items to all items,
# with a 95% confidence interval, using the normal approximation interval.
# It returns two values: the estimated reputation and the interval
# at 95% confidence. See http://bit.ly/2yD5TvJ for more details.
private def calculations
@calculations ||= begin
raise Error.new("sample_size must be ≥ 0") unless sample_size > 0
raise Error.new("not_spammy_sample_size must be ≥ 0") unless not_spammy_sample_size >= 0
raise Error.new("sample_size must be ≥ not_spammy_sample_size") unless sample_size >= not_spammy_sample_size
p_hat = not_spammy_sample_size.to_f / sample_size # p̂ -- estimated proportion
z_score = 1.95996 # z-score for 95% confidence
z_squared = z_score * z_score
plus_minus = z_score * Math.sqrt((p_hat * (1.0 - p_hat)) / sample_size)
lower_bound = ((2 * sample_size * p_hat) + z_squared - (z_score * Math.sqrt(z_squared + (4 * sample_size * p_hat * (1.0 - p_hat))))) / (2 * (sample_size + z_squared))
[p_hat, plus_minus, lower_bound]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment