Ruby
確率分布
plotly
NArray
numo

Rubyでさまざまな確率分布の乱数を生成してヒストグラムを描いてみた


はじめに

image.png

 さまざまな確率分布に従う乱数を作成して、ヒストグラムを描いてみたくなる日は誰にでもあると思います。

 大丈夫。いつだって、世界の素晴らしいプログラマ達が驚くべきライブラリを作ってくれています。たとえ有名ではないライブラリでも、見つけてちゃんと使ってあげると、魔法のようなことが簡単にできたりします。

 この記事では、素晴らしいRubyのライブラリを2つ紹介します。Numo::GSLFlammarionです。これらを使うことで、驚くほど簡単に乱数を生成してヒストグラムが描出できます。


準備編

インストールは若干面倒なので、飛ばして、最後までいったら戻ってきて見てください。

Numo::GSLとFlammarionをインストールする


Numo::GSLをインストールする

Numo::GSL はGNU Scientific Library (GSL) のバインディングです。Ruby界にはGSLとのバインディングはいろいろありますがNArrayの利用を考えて私はこれを使っています。

 2019/5 現在、Numo::GSLは、GSL2.4以降に対応していません。なので、多くの環境ではソースコードからGSL2.3をインストールする必要があります。そんなわけで少し手間がかかりますがそれだけの価値はあります。下記のような感じでコマンドを打てば大丈夫です。公式サイトのダウンロードページから、gsl-2.3.tar.gz をダウンロードします。

…と思いましたがUbuntuでは sudo apt install libgsl23 するだけで大丈夫なこともあるようだ。

wget http://ftp.jaist.ac.jp/pub/GNU/gsl/gsl-2.3.tar.gz

tar -zxvf gsl-2.3.tar.gz
cd gsl-2.3
./configure
make -j4 # CPUコア数を指定

# checkinstallを使う場合
sudo checkinstall

# インストール場所を自分で指定する場合
# make DESTDIR=/path/you/want/to/install/ install

# Githubからnumo-gslを取得

git clone https://github.com/ruby-numo/numo-gsl
cd numo-gsl
rake build
gem install pkg/numo-gsl-0.1.2.gem # -- --with-gsl-lib=usr/local/lib

# GSLのインストール場所を自分で指定する場合
# gem install pkg/numo-gsl-0.1.2.gem -- --with-gsl-lib=/path/you/want/to/install/usr/local/lib


Flammarionをインストールする

Rubyでグラフを表示する方法はたくさんあります。

しかし!ここではあえて誰も知らないマイナーな方法:Flammarionを使ってplotyを使う をやります。FlammarionはChromeとelectronによるGUIツールキットで面白い機能がたくさんついている素晴らしいツールです。Plotlyによるグラフ表示機能もその一つです。Flammarionについてはまた別の機会にエントリーを書きたいと思います。Flammarionの開発は継続していますが、やや更新が遅れているようです。我こそはと思う人はコントリビューションするとよいと思います。

https://github.com/zach-capalbo/flammarion

gem install flammarion


irb または pry を立ち上げて、FlammarionとNumo::GSLを準備します。

require 'flammarion'

require 'numo/gsl'
f = Flammarion::Engraving.new
r = Numo::GSL::Rng::Rand.new

ここから先は簡単です。


二項分布

a = r.binomial(0.5, 100, 10000).to_a

f.plot(x: a, type: "histogram")

image.png


ポアソン分布

a = r.poisson(3, 10000).to_a

f.plot(x: a, type: "histogram")

image.png


ベルヌーイ分布

a = r.bernoulli(0.3,10000).to_a

f.plot(x: a, type: "histogram",
autobinx: false, xbins: {start:0, end:1.1, size: 0.1})

image.png


指数分布

a = r.exponential(2,10000).to_a

f.plot(x: a, type: "histogram")

image.png


ガンマ分布

a = r.gamma(5,1,10000).to_a

f.plot(x: a, type: "histogram")

image.png


ベータ分布

a = r.beta(0.5,0.5,10000).to_a

f.plot(x: a, type: "histogram")

image.png


正規分布

a = r.gaussian(0.2,10000).to_a

f.plot(x: a, type: "histogram")

image.png

こんな感じで簡単にグラフが描けます。

GSLの関数が使えるので、だいたいの分布のヒストグラムは描けるのではないでしょうか。

Flammarionのテーブル機能を使って、rに登録されたメソッドの一覧を表示してみましょう。

f.table( (r.methods - Object.methods).each_slice(5).to_a)

image.png

このようにいろいろと用意されていることがわかります。

なーんだ、Rubyでも簡単にできるじゃないか。

リファレンスや文献がすくなくて、探すのが大変なんですけどね。

この記事は以上です。