サンプル和の確率分布#
// 依存関係のインストール
:dep image = "0.23"
:dep evcxr_image = "1.1"
// プロット用ライブラリ
:dep plotters = { version = "^0.3.5", default_features = false, features = ["evcxr", "all_series", "all_elements"] }
// 乱数
:dep rand = { version = "0.8.5" }
// インポート
use evcxr_image::ImageDisplay;
use image::{GenericImage, imageops::FilterType};
use plotters::prelude::*;
use rand::prelude::*;
// 自作ライブラリ
:dep myml = { path = "../myml/" }
use myml::{utility::linspace, normal::normal};
モデルの推定#
サンプル和に対応する正規分布をプロットする
/// ランダムな変数`n`個を`rep`回サンプリングした和を求める
fn sample_sum(n: usize, rep: usize) -> Vec<f64> {
(0..rep)
.map(|_| {
(0..n)
.map(|_| random::<f64>())
.sum::<f64>()
})
.collect()
}
const REP: usize = 10000;
const N: usize = 5;
// サンプリング
let sums = sample_sum(N, REP);
// 対応する正規分布
let x = linspace(-5.0, 5.0, 1000);
let mu = N as f64 / 2.0;
let sigma = (N as f64 / 12.0).sqrt();
let y = normal(&x, mu, sigma);
let points = x.iter().copied().zip(y.iter().copied()).collect::<Vec<_>>();
evcxr_figure((640, 480), |root| {
root.fill(&WHITE)?;
let mut chart = ChartBuilder::on(&root)
.caption("N = 5", ("Sans", 20).into_font())
.x_label_area_size(50)
.y_label_area_size(50)
.build_cartesian_2d(0..50, 0.0..800.0)?;
chart.configure_mesh()
.draw()?;
// ヒストグラムを描画
let hist = Histogram::vertical(&chart)
.style(BLUE.filled())
.margin(0)
.data(sums.iter().map(|&x| ((x * 10.0) as i32, 1.0)));
chart.draw_series(hist)?;
// モデルを描画(同様にxを10倍する)
chart.draw_series(
LineSeries::new(
points.iter().map(|&(x, y)| ((x * 10.0) as i32, y * 1000.0)),
&RED,
)
)?;
Ok(())
})