bandit

Bandit is a multi-armed bandit optimization framework for Rails. It provides an alternative to A/B testing in Rails. For background and a comparison with A/B testing, see the whybandit.rdoc document or the blog post here.

Installation

First, add the following to your Gemfile in your Rails 3 app:

gem 'bandit'

Then, run the following:

bundle install
rails generate bandit:install

You can then edit the bandit.yml file in your config directory to set your storage and player parameters. Redis, memcache, and memory storage options are available. Memory storage should only be used for testing.

See the file players.rdoc for information about available players.

Configuration

To set up an experiment, add it either somewhere in your code or in the bandit initializer. Creating an experiment is simple:

Bandit::Experiment.create(:click_test) { |exp|
  exp.alternatives = [ 20, 30, 40 ]
  exp.title = "Click Test"
  exp.description = "A test of clicks on purchase page with varying link sizes."
}

View

To get an alternative (per viewer, based on cookies):

<%= bandit_choose :click_test %>

For instance, in a link:

<%= link_to "new purchase", new_purchase_path, :style => "font-size: #{bandit_choose(:click_test)}px;" %>

You can force a particular alternative by adding a query parameter named “bandit_<experiment name>” and setting it’s value to the alternative you want. For instance, given the above experiment in the configuration example:

http://<yourhost>/<path>?bandit_click_test=40

will then force the alternative to be “40”.

Controller

To track a conversion in your controller:

bandit_convert! :click_test

You can also request a choice in the conroller:

redirect_to bandit_choose(:some_url_test)

Dashboard

rails generate bandit:dashboard

Then, add the following to your config/routes.rb file:

resources :bandit

To see a dashboard with relevant information, go to:

http://<yourhost>/bandit

Tests

To run tests:

rake test_memory
rake test_memcache
rake test_redis

To produce fake data for the past week, first create an experiment definition. Then, run the following rake task:

rake bandit:populate_data[<experiment_name>]

For instance, to generate a week’s worth of fake data for the click_test above:

rake bandit:populate_data[click_test]

Fault Tolerance

If the storage mechanism fails, then Bandit will automatically switch to in memory storage. It will then check every 5 minutes after that to see if the original storage mechanism is back up. If you have distributed front ends then each front end will continue to optimize (based on the in memory storage), but this optimization will be inefficient compared to shared storage among all front ends.