Rubyで分散を求める

Enumerableモジュールに追加する。(と、Array, Dir, File, Hash, IO, Range, Stringなどがインクルードしてるので、それらのオブジェクトで使える)

module Enumerable

    def sum
      inject(0){ |accum, i| accum + i }
    end

    def mean
      sum / length.to_f
    end

    def variance
      m = mean
      sum = inject(0){ |accum, i| accum + ( i - m ) ** 2 }
      sum / (length - 1).to_f
    end

    def standard_deviation
      return Math::sqrt(variance)
    end
end 

参考:How can I do standard deviation in Ruby? - Stack Overflow

実行

pry(main)> a = 
=> 
pry(main)> (0..99).each do |i|
pry(main)*   a[i] = rand(100)
pry(main)* end  
=> 0..99
pry(main)> a
=> [85,
 42,
 12,
 :
 0,
 61]
pry(main)> a.sum
=> 5011
pry(main)> a.mean
=> 50.11
pry(main)> a.variance
=> 999.61404040404
pry(main)> a.standard_deviation
=> 31.616673455694862

実行2(正規分布乱数)

ボックス=ミュラー法を使うと平均0, 標準偏差1の正規分布乱数を発生できる。ので、この乱数を元に平均m, 標準偏差sdの正規分布の乱数が生成できる。
参考:

n個の正規分布乱数を生成するメソッドbox_muller_s_method

def box_muller_s_method(m, sd, mrand = [], n)
  srand
  (0..(n - 1).to_i).map do |i|
    mrand[i] = m + sd * (Math::sqrt(-2 * Math::log(rand)) * Math::sin(2 * Math::PI * rand))
  end
end

box_muller_s_methodを使ってstandard_deviationメソッドの確認。

pry(main)> b = 
=> 
pry(main)> box_muller_s_method(50, 25, b, 100)
=> [9.056138861433922,
 49.49541365976993,
 76.88970439479608,
 :
 14.827272039422489,
 55.93021717456249]
pry(main)> b.size
=> 100
pry(main)> b.sum
=> 4944.478430698326
pry(main)> b.mean
=> 49.44478430698326
pry(main)> b.variance
=> 715.5954394141993
pry(main)> b.standard_deviation
=> 26.7506156828997