<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>正規分布 on Marketechlabo</title><link>https://www.marketechlabo.com/tags/normal-distribution/</link><description>Recent content in 正規分布 on Marketechlabo</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Wed, 10 Apr 2019 00:00:00 +0900</lastBuildDate><atom:link href="https://www.marketechlabo.com/tags/normal-distribution/index.xml" rel="self" type="application/rss+xml"/><item><title>Javascriptで正規分布の実装まとめ（乱数、累積分布関数など）</title><link>https://www.marketechlabo.com/statistics-analysis/normal-distribution-javascript/</link><pubDate>Wed, 10 Apr 2019 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/statistics-analysis/normal-distribution-javascript/</guid><description>
&lt;p&gt;Javascriptで正規分布の乱数発生（rnorm）、確率密度関数（dnorm）、累積分布関数（pnorm）、累積分布の逆関数（qnorm）を実装する。すべて標準正規分布を想定。
Javascriptに限らず使えるアルゴリズムだが、日本語でまとまっている情報があまりないのと、ブラウザ上でA/Bテストなど有意性をみる検定などできたら面白いということでJSでやってみる。&lt;/p&gt;
&lt;p&gt;なお、実務で手軽に使いたい場合は &lt;a href="https://github.com/stdlib-js/stats-base-dists-normal"&gt;stdlib-js&lt;/a&gt; や &lt;a href="https://jstat.github.io/"&gt;jStat&lt;/a&gt; といったライブラリも検討するとよい。本記事はアルゴリズムの中身を理解する目的で、ライブラリを使わずスクラッチで実装する。&lt;/p&gt;
&lt;h2 id="正規乱数の生成rnorm"&gt;正規乱数の生成（rnorm）&lt;/h2&gt;
&lt;p&gt;1行でBox-Muller法で。&lt;/p&gt;
&lt;h3 id="box-muller法とは"&gt;Box-Muller法とは？&lt;/h3&gt;
&lt;p&gt;$$X_1, X_2 \stackrel{i.i.d.}{\sim} {\rm Unif} (0, 1) $$
とするとき
$$Y_1 = \sqrt{-2 \log{X_1}} \cos{2 \pi X_2} $$
$$Y_2 = \sqrt{-2 \log{X_1}} \sin{2 \pi X_2} $$
で生成される
$$Y_1, Y_2 \stackrel{i.i.d.}{\sim} {\rm N} (0, 1) $$
というもの。
今回は1個の正規乱数でいいので、$Y_1$か$Y_2$の一方を採用すればいい。&lt;/p&gt;
&lt;h3 id="javascriptで実装"&gt;Javascriptで実装&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rnorm&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;sqrt&lt;/span&gt;(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;())) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;cos&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;PI&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;後ろの係数は&lt;code&gt;Math.cos()&lt;/code&gt;でも&lt;code&gt;Math.sin()&lt;/code&gt;でもどちらでもいい。Javascriptの&lt;code&gt;Math.random()&lt;/code&gt;は戻り値の区間が[0,1)なので、$log {0}$で発散しないように&lt;code&gt;1-Math.random()&lt;/code&gt;としている。&lt;/p&gt;
&lt;h2 id="確率密度関数dnorm"&gt;確率密度関数（dnorm）&lt;/h2&gt;
&lt;p&gt;$$Z(x) = \frac{ e^{ -\frac{x^2}{2}} }{\sqrt{2 \pi}} $$
そのまんま&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dnorm&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;exp&lt;/span&gt;(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;sqrt&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;PI&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="累積分布関数pnorm"&gt;累積分布関数（pnorm）&lt;/h2&gt;
&lt;p&gt;Abramowitz and Stegun, Handbook of Mathematical Functions (1964)から。
&lt;a href="https://personal.math.ubc.ca/~cbm/aands/"&gt;https://personal.math.ubc.ca/~cbm/aands/&lt;/a&gt;
26.2が正規分布の累積分布関数の項目。
実際はC. Hastings, Jr., Approximations for Digital Computers (1955)に基づいているとのこと。
26.2.17の
$$P(x) = 1 - Z(x) \left( b_1 t + b_2 t^2 + b_3 t^3 + b_4 t^4 + b_5 t^5 \right) + \epsilon(x) $$
$$t = \frac{1}{1+px}, \quad Z(x) = \frac{ e^{ -\frac{x^2}{2}} }{\sqrt{2 \pi}} $$
$$|\epsilon(x)| \lt 7.5 \times 10^{-8} $$
$$p = .23164 19 $$
$$b_1 = .31938 1530 $$
$$b_2 = -.35656 3782 $$
$$b_3 = 1.78147 7937 $$
$$b_4 = -1.82125 5978 $$
$$b_5 = 1.33027 4429 $$
をそのまま実装&lt;/p&gt;</description></item></channel></rss>