wilson_score 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be14e070c2299eb4ca4bfb98fff17bc037778702
4
- data.tar.gz: 811d3aed20e01c0f4498c5ef40ac7129f8322eff
3
+ metadata.gz: 5d7bb501c73ead396229401fe42913d871b40415
4
+ data.tar.gz: 28ec167d67257eddf27488f0372fe26374e54f90
5
5
  SHA512:
6
- metadata.gz: 640f472abf05bd6f9acc79ee4644136387346a15d409c60d4c0dd5f739da5aaef2e4178bcf79d954822c5e4477676c577eaccde796b8b76f37ea5ade87440925
7
- data.tar.gz: ee62a52fc1f1049a4c3c2659afa4621fd651ed2b923c16b4c4d26fea556f753b286e2466f3446d2a7b02c8e459284a8ac6e5f7c1b6c58ec25132d3d3fb2be74a
6
+ metadata.gz: a7df05093b79ad6080ec347db2f93aaca8f6cccb982dfabc7492e5c90dea6a8cd5c172731ff14c437224389eb82a2e61915a4a87cf3dd57b8911932c3f3ec8f7
7
+ data.tar.gz: b34ed9eec15dea13d48f523d91d5e4db1af62cdae38cf417f6dba92c971d4b673e6702decf21c56427e6206fa329b1f65daf7949b08f4b81fa15c09809980c3b
data/README.md CHANGED
@@ -9,13 +9,25 @@ Inspired by [How Not To Sort By Average Rating](http://www.evanmiller.org/how-no
9
9
  3 positive ratings out of 5 with 95% confidence
10
10
 
11
11
  ```ruby
12
- WilsonScore.interval(3, 5, 0.95)
12
+ WilsonScore.lower_bound(3, 5)
13
13
  ```
14
14
 
15
- [Continuity correction](http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval_with_continuity_correction) can improve the score, especially for a small number of samples (n < 30). Set the last paramter to true to use it.
15
+ [Continuity correction](http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval_with_continuity_correction) can improve the score, especially for a small number of samples (n < 30). As of version 0.1.0, it is enabled by default. To disable continuity correction, use:
16
16
 
17
17
  ```ruby
18
- WilsonScore.interval(3, 5, 0.95, true)
18
+ WilsonScore.lower_bound(3, 5, correction: false)
19
+ ```
20
+
21
+ The default confidence level is 95%. To change this, use:
22
+
23
+ ```ruby
24
+ WilsonScore.lower_bound(3, 5, confidence: 0.99)
25
+ ```
26
+
27
+ To get the full interval, use:
28
+
29
+ ```ruby
30
+ WilsonScore.interval(3, 5)
19
31
  ```
20
32
 
21
33
  ## Star Ratings
@@ -28,16 +40,10 @@ A product has two ratings - one 4 star and one 5 star.
28
40
  average_rating = 4.5
29
41
  total_ratings = 2
30
42
  rating_range = 1..5 # 1 to 5 stars
31
- confidence = 0.95 # 95%
32
43
 
33
- interval = WilsonScore.rating_interval(average_rating, total_ratings, rating_range, confidence)
34
- lower_bound = interval.first
44
+ WilsonScore.rating_lower_bound(average_rating, total_ratings, rating_range)
35
45
  ```
36
46
 
37
- Use the lower bound of the interval to sort items.
38
-
39
- Again, you can set the last parameter to `true` for continuity correction.
40
-
41
47
  ## Installation
42
48
 
43
49
  Add this line to your application's Gemfile:
@@ -3,7 +3,12 @@ require "wilson_score/version"
3
3
  module WilsonScore
4
4
 
5
5
  # http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval
6
- def self.interval(k, n, confidence, correction = false)
6
+ def self.interval(k, n, *args)
7
+ args = args.dup
8
+ options = args[-1].is_a?(Hash) ? args.pop : {}
9
+ confidence = args[0] || options[:confidence] || 0.95
10
+ correction = !args[1].nil? ? args[1] : (options.has_key?(:correction) ? options[:correction] : true)
11
+
7
12
  z = pnorm(1 - (1 - confidence) / 2.0)
8
13
  phat = k / n.to_f
9
14
  z2 = z**2
@@ -12,10 +17,9 @@ module WilsonScore
12
17
  b = 2*n*phat + z2
13
18
  c = z * Math.sqrt(z2 - 1.0/n + 4*n*phat*(1 - phat) + (4*phat - 2)) + 1
14
19
  d = z * Math.sqrt(z2 - 1.0/n + 4*n*phat*(1 - phat) - (4*phat - 2)) + 1
15
- # hack for phat = 0 or 1
16
- lower = phat == 0 ? 0 : (b - c) / a
17
- upper = phat == 1 ? 1 : (b + d) / a
18
- ([0, lower].max)..([1, upper].min)
20
+ lower = phat == 0 ? 0 : [0, (b - c) / a].max
21
+ upper = phat == 1 ? 1 : [1, (b + d) / a].min
22
+ lower..upper
19
23
  else
20
24
  a = 1 + z2 / n
21
25
  b = phat + z2 / (2 * n)
@@ -24,7 +28,16 @@ module WilsonScore
24
28
  end
25
29
  end
26
30
 
27
- def self.rating_interval(avg, n, score_range, confidence, correction = false)
31
+ def self.lower_bound(k, n, options = {})
32
+ interval(k, n, options).first
33
+ end
34
+
35
+ def self.rating_interval(avg, n, score_range, *args)
36
+ args = args.dup
37
+ options = args[-1].is_a?(Hash) ? args.pop : {}
38
+ confidence = args[0] || options[:confidence] || 0.95
39
+ correction = !args[1].nil? ? args[1] : (options.has_key?(:correction) ? options[:correction] : true)
40
+
28
41
  min = score_range.first
29
42
  max = score_range.last
30
43
  range = max - min
@@ -32,6 +45,10 @@ module WilsonScore
32
45
  (min + range * interval.first)..(min + range * interval.last)
33
46
  end
34
47
 
48
+ def self.rating_lower_bound(avg, n, score_range, options = {})
49
+ rating_interval(avg, n, score_range, options).first
50
+ end
51
+
35
52
  protected
36
53
 
37
54
  # from the statistics2 gem
@@ -1,3 +1,3 @@
1
1
  module WilsonScore
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -3,51 +3,71 @@ require_relative "test_helper"
3
3
  class TestWilsonScore < Minitest::Test
4
4
 
5
5
  def test_wilson_score
6
- interval = WilsonScore.interval(1, 2, 0.95)
6
+ interval = WilsonScore.interval(1, 2, correction: false)
7
7
  assert_in_delta 0.0945, interval.first
8
8
  assert_in_delta 0.9055, interval.last
9
9
  end
10
10
 
11
+ def test_lower_bound
12
+ assert_in_delta 0.0267, WilsonScore.lower_bound(1, 2)
13
+ end
14
+
11
15
  def test_continuity_correction
12
- interval = WilsonScore.interval(1, 2, 0.95, true)
16
+ interval = WilsonScore.interval(1, 2)
13
17
  assert_in_delta 0.0267, interval.first
14
18
  assert_in_delta 0.9733, interval.last
15
19
  end
16
20
 
17
21
  def test_continuity_correction_zero_one
18
- interval = WilsonScore.interval(0, 1, 0.95, true)
22
+ interval = WilsonScore.interval(0, 1)
19
23
  assert_in_delta 0, interval.first
20
24
  assert_in_delta 0.9454, interval.last
21
25
  end
22
26
 
27
+ def test_continuity_correction_zero_ten
28
+ interval = WilsonScore.interval(0, 10)
29
+ assert_in_delta 0, interval.first
30
+ assert_in_delta 0.3445, interval.last
31
+ end
32
+
33
+ def test_continuity_correction_one_ten
34
+ interval = WilsonScore.interval(1, 10)
35
+ assert_in_delta 0.0052, interval.first
36
+ assert_in_delta 0.4588, interval.last
37
+ end
38
+
23
39
  def test_continuity_correction_one_fifty
24
- interval = WilsonScore.interval(1, 50, 0.95, true)
40
+ interval = WilsonScore.interval(1, 50)
25
41
  assert_in_delta 0.0010, interval.first
26
42
  assert_in_delta 0.1201, interval.last
27
43
  end
28
44
 
29
45
  def test_continuity_correction_one_one
30
- interval = WilsonScore.interval(1, 1, 0.95, true)
46
+ interval = WilsonScore.interval(1, 1)
31
47
  assert_in_delta 0.0546, interval.first
32
48
  assert_in_delta 1, interval.last
33
49
  end
34
50
 
35
51
  def test_continuity_correction_one_three
36
- interval = WilsonScore.interval(1, 3, 0.95, true)
52
+ interval = WilsonScore.interval(1, 3)
37
53
  assert_in_delta 0.0176, interval.first
38
54
  assert_in_delta 0.8747, interval.last
39
55
  end
40
56
 
41
57
  def test_rating
42
- interval = WilsonScore.rating_interval(5, 1, 1..5, 0.95)
58
+ interval = WilsonScore.rating_interval(5, 1, 1..5, correction: false)
43
59
  assert_in_delta 1.8262, interval.first
44
60
  assert_in_delta 5, interval.last
45
61
  end
46
62
 
47
63
  def test_rating_advanced
48
- interval = WilsonScore.rating_interval(3.7, 10, 1..5, 0.95)
64
+ interval = WilsonScore.rating_interval(3.7, 10, 1..5, correction: false)
49
65
  assert_in_delta 2.4998, interval.first
50
66
  assert_in_delta 4.5117, interval.last
51
67
  end
52
68
 
69
+ def test_rating_lower_bound
70
+ assert_in_delta 1.8262, WilsonScore.rating_lower_bound(5, 1, 1..5, correction: false)
71
+ end
72
+
53
73
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wilson_score
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-05 00:00:00.000000000 Z
11
+ date: 2014-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: Simple, dependency-free Wilson score
@@ -59,7 +59,7 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
- - .gitignore
62
+ - ".gitignore"
63
63
  - Gemfile
64
64
  - LICENSE.txt
65
65
  - README.md
@@ -79,17 +79,17 @@ require_paths:
79
79
  - lib
80
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - '>='
82
+ - - ">="
83
83
  - !ruby/object:Gem::Version
84
84
  version: '0'
85
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
91
  rubyforge_project:
92
- rubygems_version: 2.0.0
92
+ rubygems_version: 2.2.0
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: Simple, dependency-free Wilson score