2013年3月15日金曜日

rubyからr言語を使って、キャンペーン前後で売上に変化があったか判断する

同一期間ではないので、対応のない場合のt検定を行います。
rubyからR言語を使うには、rsrubyというライブラリを使う。

まずはRのインストール
$ brew install R

で、rのpathを設定します。
$ export R_HOME=/Library/Frameworks/R.framework/Resources

次にrsrubyのインストール
$ gem install rsruby -- --with-R-include=/Library/Frameworks/R.framework/Headers --with-R-lib=/Library/Frameworks/R.framework/Libraries

で、準備は完了。

今回はこんな感じの想定です。
・送料無料キャンペーン(今まで送料無料ではなかった部分の売上が増える=平均単価が減少する仮説)
・送料無料キャンペーンをやっていなかった、去年の売上と今年の売上を比較
・月初から今日までの期間を考える


以下がコード

まずはヒストリカルグラフで確認
  1. require 'rsruby'  
  2.   
  3. r = RSRuby::instance  
  4. x = Order.where("created_at between ? and ?" , Time.now.beginning_of_month, Time.now).map(&:price).(&:to_f)  
  5. y = Order.where("created_at between ? and ?" , Time.now.beginning_of_month - 1.years, Time.now - 1.years).map(&:price).(&:to_f)  
  6.   
  7. r.eval_R(<<-RCOMMAND)  
  8.   
  9. hist(#{y.join(",")}, breaks = 5 ,col = "#0000ff40", border = "#0000ff", freq = TRUE)  
  10. hist(#{x.join(",")}, breaks = 5 ,col = "#ff00ff40", border = "#ff00ff", freq = TRUE, add = TRUE)  
  11.   
  12. RCOMMAND  
一応F検定
  1. r.var_test(x, y)  

t検定
  1. r.t_test(x, y, altenative="two.sided")  

するとこんな感じの結果がでます。

 {"statistic"=>{"t"=>1.8121550934930575}, "parameter"=>{"df"=>4.0}, "p.value"=>0.1441855869309796, "conf.int"=>[-14560.490812856453, 69286.49081285646], "estimate"=>{"mean of x"=>32613.0, "mean of y"=>5250.0}, "null.value"=>{"difference in means"=>0.0}, "alternative"=>"two.sided", "method"=>"Welch Two Sample t-test", "data.name"=>"c(63210L, 14385L, 74970L, 5250L, 5250L) and c(5250L, 5250L)"}

2013年3月4日月曜日

ruby2.0 on Rails4.0でABテストができる短縮URLサービスを作った

先日ruby2.0が公開され、Rails4.0がついにbetaとしてgem化されていたので、早速使ってみた。

作ったサービスは、こちら http://url-s.herokuapp.com/

ソースはgithubにあげてあります。

これは2種類以上のURLを登録できる短縮URLサービスです。
外部サービスを利用していてABテストができないときに、2種類のランディングページを用意しておいて、短縮URLでランダムに飛んでもらいテストするという用途を想定しています。

以下ruby2.0とRails4.0を使ってみた感想。

  • 起動早い。2.0のおかげだと思うけど、前の環境には戻りたくない
  • マジックコメントいちいち書かなくていいの最高!
  • strong paramerterでちょいはまり。特にネストしたモデルのを扱うなら、attributesの方のidを許可しないと、updateした時に、新規で作成されてしまうので注意。
  • find_byメソッドのほうが直感的でよい。というかなんでそうじゃなかったの?

結論。 新規でアプリ作る場合、特に躊躇する理由もないので、この組み合わせで積極的に使っていきたい。

2013年1月19日土曜日

railsでorder時に特定IDのデータだけ、前に持ってくる方法

例えば、IDが1〜10のデータがある時に、IDの降順にしようとした時には
  1. Model.order("id desc").all  
などとするが、時々この中の一部(例えばID:3)は先頭に、それ以外はIDの降順にしたいときなどがある。
そんなときは、
  1. Model.order("'id' = CASE WHEN id = 3 THEN 0 ELSE 'id' END").order("id desc").all  
などとすると、できる。

2013年1月10日木曜日

vanityとchankoを使ってRailsで簡単安全にABテストをする

vanityはRailsのABテスト用ライブラリ。導入が一番簡単っぽい。
 元々はテキストとか画像をのABテストを行うためのもののようだが、 chankoという限定公開用のライブラリを使って、機能単位でもABテストができるようにしてみる。

まずはGemfileに
  1. gem 'chanko':git => 'git://github.com/cookpad/chanko.git'  
  2. gem "vanity"  
を記述して、
# bundle install

それぞれに必要な初期設定をする。
# rails generate chanko:install
# rails generate vanity
# rake db:migrate

config/vanity.ymlを作成
  1. development:  
  2.   adapter: active_record  
  3.   active_record_adapter: mysql2  
  4.   host: localhost  
  5.   database: DBNAME  
  6.   user: USERNAME  
  7.   password: PASSWORD  

development.rbに以下を記述
  1. Vanity.playground.collecting = true  

vanityのDashboard用コントローラを作成
  1. class VanityController < ApplicationController  
  2.   include Vanity::Rails::Dashboard  
  3. end   

ルーティングを設定
  1. match '/vanity(/:action(/:id(.:format)))':controller=>:vanity  

測定用のユーザアイデンティティを設定。
  1. class ApplicationController < ActionController::Base  
  2.   use_vanity :current_user  
  3. end  

Railsのルートディレクトリ下にテストと測定用のファイルを作成
#mkdir -p experiments/metrics

postした回数測定用のファイルを作成
experiments/metrics/post.rb
  1. metric "Post" do  
  2.   description "Postした回数"  
  3. end  

コントローラの好きな場所に、 track! :post を入力すれば、その場所がよばれた回数を測定できるようになります。
  1. class PostController < ApplicationController  
  2.   def create  
  3.      track! :post  
  4.        # ...投稿する処理  
  5.      end  
  6.   end  
  7. end  

テスト用ファイルを作成
experiments/post_labels.rb
  1. ab_test "Post labels" do  
  2.   description "テスト"  
  3.   alternatives truefalse  
  4.   metrics :post  
  5. end  

次にchanko用設定
# rails generate chanko sample
  1. module Sample  
  2.   include Chanko::Unit  
  3.   
  4.   active_if do |context, options|  
  5.     ab_test(:price_options)   
  6.   end  
  7.   scope(:controllerdo  
  8.     function(:controller_showdo  
  9.       # controller code here  
  10.     end  
  11.   end  
  12.   scope(:viewdo  
  13.     function(:view_showdo  
  14.       render :partial => "/show"  
  15.     end  
  16.   end  
  17. end  
で、好きな場所にinvoke(:sample, :controller_show) をおいたり、
invoke(:sample, :show) を置けばOK。
chankoの詳しい使い方はこちらを参考に。

どちらが優位かなんてのは、Vanityが表示してくるので、 評価しやすいはず。

production環境でうまく動かなかったので、
そのときはredisによる接続をためしてみるといいかも。
  1. production:  
  2.   adapter: redis  
  3.   host: localhost  



 参考:
http://eccyan.hatenablog.com/entry/2011/12/08/223603
https://github.com/assaf/vanity
http://webandy.com/articles/a-b-testing-with-vanity