split 3.1.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -2
- data/.travis.yml +1 -1
- data/CHANGELOG.md +11 -0
- data/README.md +8 -0
- data/lib/split/alternative.rb +3 -0
- data/lib/split/combined_experiments_helper.rb +8 -1
- data/lib/split/configuration.rb +2 -0
- data/lib/split/experiment.rb +5 -4
- data/lib/split/version.rb +2 -2
- data/spec/alternative_spec.rb +12 -0
- data/spec/combined_experiments_helper_spec.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 861fb73c59529de9a24f3a78ddd0b5cbe257eb8b
|
4
|
+
data.tar.gz: dd67eac616dd9435c3a0ca448de504b3824bccb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d078b157629b473b654b751c18fe11ddae08486f38bce2fef2bdd71b7a8536ce048204adaf9b1e242e6cf76f1c33650db91994e34a23734ecaf4357663b750cf
|
7
|
+
data.tar.gz: aa994978184569f624b9d5bb3503b93b498ef4601bb1989fe2e16eabee07a0450adc9555c02c251d70d9a73dce65e40bac0e05bf071dc8d229e4ab87c0b817ec
|
data/.rubocop.yml
CHANGED
@@ -716,7 +716,7 @@ Style/LineEndConcatenation:
|
|
716
716
|
line end.
|
717
717
|
Enabled: false
|
718
718
|
|
719
|
-
Style/
|
719
|
+
Style/MethodCallWithoutArgsParentheses:
|
720
720
|
Description: 'Do not use parentheses for method calls with no arguments.'
|
721
721
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
|
722
722
|
Enabled: false
|
@@ -816,7 +816,7 @@ Style/OneLineConditional:
|
|
816
816
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator'
|
817
817
|
Enabled: false
|
818
818
|
|
819
|
-
|
819
|
+
Naming/BinaryOperatorParameter:
|
820
820
|
Description: 'When defining binary operators, name the argument other.'
|
821
821
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
|
822
822
|
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 3.2.0 (September 21st, 2017)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Allow configuration of how often winning alternatives are recalculated (@patbl, #501)
|
6
|
+
|
7
|
+
Bugfixes:
|
8
|
+
|
9
|
+
- Avoid z_score numeric exception for conversion rates >1 (@cmantas, #503)
|
10
|
+
- Fix combined experiments (@semanticart, #502)
|
11
|
+
|
1
12
|
## 3.1.1 (August 30th, 2017)
|
2
13
|
|
3
14
|
Bugfixes:
|
data/README.md
CHANGED
@@ -115,6 +115,14 @@ As per this [blog post](http://www.evanmiller.org/how-not-to-run-an-ab-test.html
|
|
115
115
|
|
116
116
|
The second option uses simulations from a beta distribution to determine the probability that the given alternative is the winner compared to all other alternatives. You can view these probabilities by clicking on the drop-down menu labeled "Confidence." This option should be used when the experiment has more than just 1 control and 1 alternative. It can also be used for a simple, 2-alternative A/B test.
|
117
117
|
|
118
|
+
Calculating the beta-distribution simulations for a large number of experiments can be slow, so the results are cached. You can specify how often they should be recalculated (the default is once per day).
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
Split.configure do |config|
|
122
|
+
config.winning_alternative_recalculation_interval = 3600 # 1 hour
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
118
126
|
## Extras
|
119
127
|
|
120
128
|
### Weighted alternatives
|
data/lib/split/alternative.rb
CHANGED
@@ -6,6 +6,7 @@ module Split
|
|
6
6
|
raise(Split::InvalidExperimentsFormatError, 'Unable to find experiment #{metric_descriptor} in configuration') if experiment[:combined_experiments].nil?
|
7
7
|
|
8
8
|
alternative = nil
|
9
|
+
weighted_alternatives = nil
|
9
10
|
experiment[:combined_experiments].each do |combined_experiment|
|
10
11
|
if alternative.nil?
|
11
12
|
if control
|
@@ -15,9 +16,15 @@ module Split
|
|
15
16
|
alternative = ab_test(combined_experiment, normalized_alternatives[0], *normalized_alternatives[1])
|
16
17
|
end
|
17
18
|
else
|
18
|
-
|
19
|
+
weighted_alternatives ||= experiment[:alternatives].each_with_object({}) do |alt, memo|
|
20
|
+
alt = Alternative.new(alt, experiment[:name]).name
|
21
|
+
memo[alt] = (alt == alternative ? 1 : 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
ab_test(combined_experiment, [weighted_alternatives])
|
19
25
|
end
|
20
26
|
end
|
27
|
+
alternative
|
21
28
|
end
|
22
29
|
|
23
30
|
def find_combined_experiment(metric_descriptor)
|
data/lib/split/configuration.rb
CHANGED
@@ -25,6 +25,7 @@ module Split
|
|
25
25
|
attr_accessor :on_before_experiment_delete
|
26
26
|
attr_accessor :include_rails_helper
|
27
27
|
attr_accessor :beta_probability_simulations
|
28
|
+
attr_accessor :winning_alternative_recalculation_interval
|
28
29
|
attr_accessor :redis
|
29
30
|
|
30
31
|
attr_reader :experiments
|
@@ -217,6 +218,7 @@ module Split
|
|
217
218
|
@algorithm = Split::Algorithms::WeightedSample
|
218
219
|
@include_rails_helper = true
|
219
220
|
@beta_probability_simulations = 10000
|
221
|
+
@winning_alternative_recalculation_interval = 60 * 60 * 24 # 1 day
|
220
222
|
@redis = ENV.fetch(ENV.fetch('REDIS_PROVIDER', 'REDIS_URL'), 'redis://localhost:6379')
|
221
223
|
end
|
222
224
|
|
data/lib/split/experiment.rb
CHANGED
@@ -262,10 +262,11 @@ module Split
|
|
262
262
|
end
|
263
263
|
|
264
264
|
def calc_winning_alternatives
|
265
|
-
#
|
266
|
-
|
265
|
+
# Cache the winning alternatives so we recalculate them once per the specified interval.
|
266
|
+
intervals_since_epoch =
|
267
|
+
Time.now.utc.to_i / Split.configuration.winning_alternative_recalculation_interval
|
267
268
|
|
268
|
-
if self.calc_time !=
|
269
|
+
if self.calc_time != intervals_since_epoch
|
269
270
|
if goals.empty?
|
270
271
|
self.estimate_winning_alternative
|
271
272
|
else
|
@@ -274,7 +275,7 @@ module Split
|
|
274
275
|
end
|
275
276
|
end
|
276
277
|
|
277
|
-
self.calc_time =
|
278
|
+
self.calc_time = intervals_since_epoch
|
278
279
|
|
279
280
|
self.save
|
280
281
|
end
|
data/lib/split/version.rb
CHANGED
data/spec/alternative_spec.rb
CHANGED
@@ -273,6 +273,18 @@ describe Split::Alternative do
|
|
273
273
|
expect(control.z_score(goal1)).to eq('N/A')
|
274
274
|
expect(control.z_score(goal2)).to eq('N/A')
|
275
275
|
end
|
276
|
+
|
277
|
+
it "should not blow up for Conversion Rates > 1" do
|
278
|
+
control = experiment.control
|
279
|
+
control.participant_count = 3474
|
280
|
+
control.set_completed_count(4244)
|
281
|
+
|
282
|
+
alternative2.participant_count = 3434
|
283
|
+
alternative2.set_completed_count(4358)
|
284
|
+
|
285
|
+
expect { control.z_score }.not_to raise_error
|
286
|
+
expect { alternative2.z_score }.not_to raise_error
|
287
|
+
end
|
276
288
|
end
|
277
289
|
|
278
290
|
describe "extra_info" do
|
@@ -46,12 +46,12 @@ describe Split::CombinedExperimentsHelper do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
it "uses same
|
49
|
+
it "uses same alternative for all sub experiments and returns the alternative" do
|
50
50
|
allow(self).to receive(:get_alternative) { "test-alt" }
|
51
51
|
expect(self).to receive(:ab_test).with(:exp_1_click, {"control"=>0.5}, {"test-alt"=>0.5}) { "test-alt" }
|
52
|
-
expect(self).to receive(:ab_test).with(:exp_1_scroll, [{"test-alt" => 1}]
|
52
|
+
expect(self).to receive(:ab_test).with(:exp_1_scroll, [{"control" => 0, "test-alt" => 1}])
|
53
53
|
|
54
|
-
ab_combined_test('combined_exp_1')
|
54
|
+
expect(ab_combined_test('combined_exp_1')).to eq('test-alt')
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: split
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -265,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
265
265
|
version: 2.0.0
|
266
266
|
requirements: []
|
267
267
|
rubyforge_project: split
|
268
|
-
rubygems_version: 2.6.
|
268
|
+
rubygems_version: 2.6.4
|
269
269
|
signing_key:
|
270
270
|
specification_version: 4
|
271
271
|
summary: Rack based split testing framework
|