wilson_score 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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