サンプル和の確率分布

サンプル和の確率分布#

// 依存関係のインストール

: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(())
})
N = 5 0.0 100.0 200.0 300.0 400.0 500.0 600.0 700.0 800.0 0 5 10 15 20 25 30 35 40 45 50