Elixir に Statistics という統計のライブラリがあるので試してみました。2項分布と正規分布という有名な確率分布を計算して、Livebook 上の VegaLite で描画してみる試みです。
Statistics
確率変数については以下の過去記事を参照してください。
Juliaで学ぶ確率変数(1) - 確率変数の定義
当然、この分野では Python や Julia の充実には、まだまだ届いていない感じです。
Elixir and Machine Learning: Nx v0.1 released!
関連記事
VegaLite で埼玉県を切る( Elixir, Livebook) - Qiita
Vega-Lite の View Composition (Elixir, Livebook) - Qiita
VegaLite の基礎 (Elixir, Livebook) -Qiita
Livebook 事始め (Elixir) - Qiita
まずは必要なインストールを行っておきます。
Mix.install([
{:vega_lite, "~> 0.1.6"},
{:kino_vega_lite, "~> 0.1.4"},
{:jason, "~> 1.2"},
{ :statistics, "~> 0.6.2"}
])
alias VegaLite, as: Vl
1. 2項分布 Statistics.Distributions.Binomial
cdf(n, p) - The cumulative density function (確率密度関数)
pmf(n, p) - The probability mass function (確率関数)
1-1. 2項分布 例題1
左利きの人が1%いる集団から1人選び、右利きか左利きかをみる。それを200回繰り返したときに4人以上が左利きである確率を計算する。
- n = 200
- p = 0.01
とりあえず分布図を描いてみます。
n = 200
p = 0.01
xs = 1..20
ys =
xs
|> Enum.map(&Statistics.Distributions.Binomial.pmf(n, p).(&1))
Vl.new()
|> Vl.data_from_values(x: xs, y: ys)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "x", type: :quantitative )
|> Vl.encode_field(:y, "y", type: :quantitative )
4人の時の値だけを計算させます。
Statistics.Distributions.Binomial.pmf(n, p).(4)
0.09021970192446989
1-2. 2項分布 例題2
ある工場で製造される工業製品には、0.1%の割合で不良品が混ざる。この工業製品1万個の中の不良品の個数をXであらわす。1万個の製品は独立に製造されたと考えるとき、Xの平均と分散を求めよ。
- n = 10000
- p = 0.001
分布図を描きます。
n = 10000
p = 0.001
xs = 1..30
ys =
xs
|> Enum.map(&Statistics.Distributions.Binomial.pmf(n, p).(&1))
Vl.new()
|> Vl.data_from_values(x: xs, y: ys)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "x", type: :quantitative )
|> Vl.encode_field(:y, "y", type: :quantitative )
平均値 = n * p、と 分散 = n * p * (1-p) を求めます。
mean = n*p
var = n*p*(1-p)
[mean, var]
[10.0, 9.99]
2. 正規分布 Statistics.Distributions.Normal
- cdf(mu, sigma) - The cumulative density function(確率密度関数)
- pdf(mu, sigma) - Probability density function(確率密度関数)
日本の成人男性の平均身長 μ=171cm、標準偏差 σ=6cmとする。
正規分布に従うと仮定した場合、日本中からランダムに1人選ばれた成人男性の身長が165cm以上171cm以下である確率は何%か?
- μ = 171
- σ = 6
分布図を描きます。
mu = 171
sigma = 6
xs = 150..200
ys =
xs
|> Enum.map(&Statistics.Distributions.Normal.pdf(mu, sigma).(&1))
Vl.new()
|> Vl.data_from_values(x: xs, y: ys)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "x", type: :quantitative )
|> Vl.encode_field(:y, "y", type: :quantitative )
165cm以上171cm以下である確率は、x=171 と x=165 の間の面積となるから、単に引き算を行えばよい。
mu = 171
sigma = 6
Statistics.Distributions.Normal.cdf(mu, sigma).(171) -
Statistics.Distributions.Normal.cdf(mu, sigma).(165)
0.3413447366676363
今回は以上です。