4199 lines
210 KiB
HTML
4199 lines
210 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>simple_statistics.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>simple_statistics.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/* global module */</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<h1 id="simple-statistics">simple-statistics</h1>
|
||
<p>A simple, literate statistics system. The code below uses the
|
||
<a href="http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth">Javascript module pattern</a>,
|
||
eventually assigning <code>simple-statistics</code> to <code>ss</code> in browsers or the
|
||
<code>exports</code> object for node.js</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
|
||
<span class="hljs-keyword">var</span> ss = {};
|
||
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> module !== <span class="hljs-string">'undefined'</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<p>Assign the <code>ss</code> object to exports, so that you can require
|
||
it in <a href="http://nodejs.org/">node.js</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> module.exports = ss;
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
<p>Otherwise, in a browser, we assign <code>ss</code> to the window object,
|
||
so you can simply refer to it as <code>ss</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.ss = ss;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-5">¶</a>
|
||
</div>
|
||
<h1 id="-linear-regression-http-en-wikipedia-org-wiki-linear_regression-"><a href="http://en.wikipedia.org/wiki/Linear_regression">Linear Regression</a></h1>
|
||
<p><a href="http://en.wikipedia.org/wiki/Simple_linear_regression">Simple linear regression</a>
|
||
is a simple way to find a fitted line
|
||
between a set of coordinates.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">linear_regression</span><span class="hljs-params">()</span> {</span>
|
||
<span class="hljs-keyword">var</span> linreg = {},
|
||
data = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-6">¶</a>
|
||
</div>
|
||
<p>Assign data to the model. Data is assumed to be an array.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> linreg.data = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span> {</span>
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">arguments</span>.length) <span class="hljs-keyword">return</span> data;
|
||
data = x.slice();
|
||
<span class="hljs-keyword">return</span> linreg;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-7">¶</a>
|
||
</div>
|
||
<p>Calculate the slope and y-intercept of the regression line
|
||
by calculating the least sum of squares</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> linreg.mb = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
|
||
<span class="hljs-keyword">var</span> m, b;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-8">¶</a>
|
||
</div>
|
||
<p>Store data length in a local variable to reduce
|
||
repeated object property lookups</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> data_length = data.length;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-9">¶</a>
|
||
</div>
|
||
<p>if there’s only one point, arbitrarily choose a slope of 0
|
||
and a y-intercept of whatever the y of the initial point is</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (data_length === <span class="hljs-number">1</span>) {
|
||
m = <span class="hljs-number">0</span>;
|
||
b = data[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>];
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-10">¶</a>
|
||
</div>
|
||
<p>Initialize our sums and scope the <code>m</code> and <code>b</code>
|
||
variables that define the line.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sum_x = <span class="hljs-number">0</span>, sum_y = <span class="hljs-number">0</span>,
|
||
sum_xx = <span class="hljs-number">0</span>, sum_xy = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-11">¶</a>
|
||
</div>
|
||
<p>Use local variables to grab point values
|
||
with minimal object property lookups</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> point, x, y;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-12">¶</a>
|
||
</div>
|
||
<p>Gather the sum of all x values, the sum of all
|
||
y values, and the sum of x^2 and (x*y) for each
|
||
value.</p>
|
||
<p>In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < data_length; i++) {
|
||
point = data[i];
|
||
x = point[<span class="hljs-number">0</span>];
|
||
y = point[<span class="hljs-number">1</span>];
|
||
|
||
sum_x += x;
|
||
sum_y += y;
|
||
|
||
sum_xx += x * x;
|
||
sum_xy += x * y;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-13">¶</a>
|
||
</div>
|
||
<p><code>m</code> is the slope of the regression line</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> m = ((data_length * sum_xy) - (sum_x * sum_y)) /
|
||
((data_length * sum_xx) - (sum_x * sum_x));</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-14">¶</a>
|
||
</div>
|
||
<p><code>b</code> is the y-intercept of the line.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> b = (sum_y / data_length) - ((m * sum_x) / data_length);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-15">¶</a>
|
||
</div>
|
||
<p>Return both values as an object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> { m: m, b: b };
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-16">¶</a>
|
||
</div>
|
||
<p>a shortcut for simply getting the slope of the regression line</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> linreg.m = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
|
||
<span class="hljs-keyword">return</span> linreg.mb().m;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-17">¶</a>
|
||
</div>
|
||
<p>a shortcut for simply getting the y-intercept of the regression
|
||
line.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> linreg.b = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
|
||
<span class="hljs-keyword">return</span> linreg.mb().b;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-18">¶</a>
|
||
</div>
|
||
<h2 id="fitting-the-regression-line">Fitting The Regression Line</h2>
|
||
<p>This is called after <code>.data()</code> and returns the
|
||
equation <code>y = f(x)</code> which gives the position
|
||
of the regression line at each point in <code>x</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> linreg.line = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-19">¶</a>
|
||
</div>
|
||
<p>Get the slope, <code>m</code>, and y-intercept, <code>b</code>, of the line.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> mb = linreg.mb(),
|
||
m = mb.m,
|
||
b = mb.b;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-20">¶</a>
|
||
</div>
|
||
<p>Return a function that computes a <code>y</code> value for each
|
||
x value it is given, based on the values of <code>b</code> and <code>a</code>
|
||
that we just computed.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span> {</span>
|
||
<span class="hljs-keyword">return</span> b + (m * x);
|
||
};
|
||
};
|
||
|
||
<span class="hljs-keyword">return</span> linreg;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-21">¶</a>
|
||
</div>
|
||
<h1 id="-r-squared-http-en-wikipedia-org-wiki-coefficient_of_determination-"><a href="http://en.wikipedia.org/wiki/Coefficient_of_determination">R Squared</a></h1>
|
||
<p>The r-squared value of data compared with a function <code>f</code>
|
||
is the sum of the squared differences between the prediction
|
||
and the actual value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">r_squared</span><span class="hljs-params">(data, f)</span> {</span>
|
||
<span class="hljs-keyword">if</span> (data.length < <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-22">¶</a>
|
||
</div>
|
||
<p>Compute the average y value for the actual
|
||
data set in order to compute the
|
||
<em>total sum of squares</em></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sum = <span class="hljs-number">0</span>, average;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < data.length; i++) {
|
||
sum += data[i][<span class="hljs-number">1</span>];
|
||
}
|
||
average = sum / data.length;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-23">¶</a>
|
||
</div>
|
||
<p>Compute the total sum of squares - the
|
||
squared difference between each point
|
||
and the average of all points.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sum_of_squares = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j < data.length; j++) {
|
||
sum_of_squares += <span class="hljs-built_in">Math</span>.pow(average - data[j][<span class="hljs-number">1</span>], <span class="hljs-number">2</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-24">¶</a>
|
||
</div>
|
||
<p>Finally estimate the error: the squared
|
||
difference between the estimate and the actual data
|
||
value at each point.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> err = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k = <span class="hljs-number">0</span>; k < data.length; k++) {
|
||
err += <span class="hljs-built_in">Math</span>.pow(data[k][<span class="hljs-number">1</span>] - f(data[k][<span class="hljs-number">0</span>]), <span class="hljs-number">2</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-25">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-25">¶</a>
|
||
</div>
|
||
<p>As the error grows larger, its ratio to the
|
||
sum of squares increases and the r squared
|
||
value grows lower.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span> - (err / sum_of_squares);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-26">¶</a>
|
||
</div>
|
||
<h1 id="-bayesian-classifier-http-en-wikipedia-org-wiki-naive_bayes_classifier-"><a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier">Bayesian Classifier</a></h1>
|
||
<p>This is a naïve bayesian classifier that takes
|
||
singly-nested objects.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bayesian</span><span class="hljs-params">()</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-27">¶</a>
|
||
</div>
|
||
<p>The <code>bayes_model</code> object is what will be exposed
|
||
by this closure, with all of its extended methods, and will
|
||
have access to all scope variables, like <code>total_count</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> bayes_model = {},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-28">¶</a>
|
||
</div>
|
||
<p>The number of items that are currently
|
||
classified in the model</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> total_count = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-29">¶</a>
|
||
</div>
|
||
<p>Every item classified in the model</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> data = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-30">¶</a>
|
||
</div>
|
||
<h2 id="train">Train</h2>
|
||
<p>Train the classifier with a new item, which has a single
|
||
dimension of Javascript literal keys and values.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> bayes_model.train = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(item, category)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-31">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-31">¶</a>
|
||
</div>
|
||
<p>If the data object doesn’t have any values
|
||
for this category, create a new object for it.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!data[category]) data[category] = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-32">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-32">¶</a>
|
||
</div>
|
||
<p>Iterate through each key in the item.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k <span class="hljs-keyword">in</span> item) {
|
||
<span class="hljs-keyword">var</span> v = item[k];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-33">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-33">¶</a>
|
||
</div>
|
||
<p>Initialize the nested object <code>data[category][k][item[k]]</code>
|
||
with an object of keys that equal 0.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (data[category][k] === <span class="hljs-literal">undefined</span>) data[category][k] = {};
|
||
<span class="hljs-keyword">if</span> (data[category][k][v] === <span class="hljs-literal">undefined</span>) data[category][k][v] = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-34">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-34">¶</a>
|
||
</div>
|
||
<p>And increment the key for this key/value combination.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> data[category][k][item[k]]++;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-35">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-35">¶</a>
|
||
</div>
|
||
<p>Increment the number of items classified</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> total_count++;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-36">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-36">¶</a>
|
||
</div>
|
||
<h2 id="score">Score</h2>
|
||
<p>Generate a score of how well this item matches all
|
||
possible categories based on its attributes</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> bayes_model.score = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(item)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-37">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-37">¶</a>
|
||
</div>
|
||
<p>Initialize an empty array of odds per category.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> odds = {}, category;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-38">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-38">¶</a>
|
||
</div>
|
||
<p>Iterate through each key in the item,
|
||
then iterate through each category that has been used
|
||
in previous calls to <code>.train()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k <span class="hljs-keyword">in</span> item) {
|
||
<span class="hljs-keyword">var</span> v = item[k];
|
||
<span class="hljs-keyword">for</span> (category <span class="hljs-keyword">in</span> data) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-39">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-39">¶</a>
|
||
</div>
|
||
<p>Create an empty object for storing key - value combinations
|
||
for this category.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (odds[category] === <span class="hljs-literal">undefined</span>) odds[category] = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-40">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-40">¶</a>
|
||
</div>
|
||
<p>If this item doesn’t even have a property, it counts for nothing,
|
||
but if it does have the property that we’re looking for from
|
||
the item to categorize, it counts based on how popular it is
|
||
versus the whole population.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (data[category][k]) {
|
||
odds[category][k + <span class="hljs-string">'_'</span> + v] = (data[category][k][v] || <span class="hljs-number">0</span>) / total_count;
|
||
} <span class="hljs-keyword">else</span> {
|
||
odds[category][k + <span class="hljs-string">'_'</span> + v] = <span class="hljs-number">0</span>;
|
||
}
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-41">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-41">¶</a>
|
||
</div>
|
||
<p>Set up a new object that will contain sums of these odds by category</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> odds_sums = {};
|
||
|
||
<span class="hljs-keyword">for</span> (category <span class="hljs-keyword">in</span> odds) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-42">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-42">¶</a>
|
||
</div>
|
||
<p>Tally all of the odds for each category-combination pair -
|
||
the non-existence of a category does not add anything to the
|
||
score.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> combination <span class="hljs-keyword">in</span> odds[category]) {
|
||
<span class="hljs-keyword">if</span> (odds_sums[category] === <span class="hljs-literal">undefined</span>) odds_sums[category] = <span class="hljs-number">0</span>;
|
||
odds_sums[category] += odds[category][combination];
|
||
}
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> odds_sums;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-43">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-43">¶</a>
|
||
</div>
|
||
<p>Return the completed model.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> bayes_model;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-44">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-44">¶</a>
|
||
</div>
|
||
<h1 id="sum">sum</h1>
|
||
<p>is simply the result of adding all numbers
|
||
together, starting from zero.</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span><span class="hljs-params">(x)</span> {</span>
|
||
<span class="hljs-keyword">var</span> value = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {
|
||
value += x[i];
|
||
}
|
||
<span class="hljs-keyword">return</span> value;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-45">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-45">¶</a>
|
||
</div>
|
||
<h1 id="mean">mean</h1>
|
||
<p>is the sum over the number of values</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mean</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-46">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-46">¶</a>
|
||
</div>
|
||
<p>The mean of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">return</span> sum(x) / x.length;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-47">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-47">¶</a>
|
||
</div>
|
||
<h1 id="geometric-mean">geometric mean</h1>
|
||
<p>a mean function that is more useful for numbers in different
|
||
ranges.</p>
|
||
<p>this is the nth root of the input numbers multiplied by each other</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">geometric_mean</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-48">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-48">¶</a>
|
||
</div>
|
||
<p>The mean of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-49">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-49">¶</a>
|
||
</div>
|
||
<p>the starting value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> value = <span class="hljs-number">1</span>;
|
||
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-50">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-50">¶</a>
|
||
</div>
|
||
<p>the geometric mean is only valid for positive numbers</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x[i] <= <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-51">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-51">¶</a>
|
||
</div>
|
||
<p>repeatedly multiply the value by each number</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> value *= x[i];
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.pow(value, <span class="hljs-number">1</span> / x.length);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-52">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-52">¶</a>
|
||
</div>
|
||
<h1 id="harmonic-mean">harmonic mean</h1>
|
||
<p>a mean function typically used to find the average of rates</p>
|
||
<p>this is the reciprocal of the arithmetic mean of the reciprocals
|
||
of the input numbers</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">harmonic_mean</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-53">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-53">¶</a>
|
||
</div>
|
||
<p>The mean of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> reciprocal_sum = <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-54">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-54">¶</a>
|
||
</div>
|
||
<p>the harmonic mean is only valid for positive numbers</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x[i] <= <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
reciprocal_sum += <span class="hljs-number">1</span> / x[i];
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-55">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-55">¶</a>
|
||
</div>
|
||
<p>divide n by the the reciprocal sum</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> x.length / reciprocal_sum;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-56">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-56">¶</a>
|
||
</div>
|
||
<h1 id="min">min</h1>
|
||
<p>This is simply the minimum number in the set.</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">min</span><span class="hljs-params">(x)</span> {</span>
|
||
<span class="hljs-keyword">var</span> value;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-57">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-57">¶</a>
|
||
</div>
|
||
<p>On the first iteration of this loop, min is
|
||
undefined and is thus made the minimum element in the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x[i] < value || value === <span class="hljs-literal">undefined</span>) value = x[i];
|
||
}
|
||
<span class="hljs-keyword">return</span> value;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-58">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-58">¶</a>
|
||
</div>
|
||
<h1 id="max">max</h1>
|
||
<p>This is simply the maximum number in the set.</p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">max</span><span class="hljs-params">(x)</span> {</span>
|
||
<span class="hljs-keyword">var</span> value;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-59">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-59">¶</a>
|
||
</div>
|
||
<p>On the first iteration of this loop, max is
|
||
undefined and is thus made the maximum element in the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x[i] > value || value === <span class="hljs-literal">undefined</span>) value = x[i];
|
||
}
|
||
<span class="hljs-keyword">return</span> value;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-60">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-60">¶</a>
|
||
</div>
|
||
<h1 id="-variance-http-en-wikipedia-org-wiki-variance-"><a href="http://en.wikipedia.org/wiki/Variance">variance</a></h1>
|
||
<p>is the sum of squared deviations from the mean</p>
|
||
<p>depends on <code>mean()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">variance</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-61">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-61">¶</a>
|
||
</div>
|
||
<p>The variance of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> mean_value = mean(x),
|
||
deviations = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-62">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-62">¶</a>
|
||
</div>
|
||
<p>Make a list of squared deviations from the mean.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {
|
||
deviations.push(<span class="hljs-built_in">Math</span>.pow(x[i] - mean_value, <span class="hljs-number">2</span>));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-63">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-63">¶</a>
|
||
</div>
|
||
<p>Find the mean value of that list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> mean(deviations);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-64">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-64">¶</a>
|
||
</div>
|
||
<h1 id="-standard-deviation-http-en-wikipedia-org-wiki-standard_deviation-"><a href="http://en.wikipedia.org/wiki/Standard_deviation">standard deviation</a></h1>
|
||
<p>is just the square root of the variance.</p>
|
||
<p>depends on <code>variance()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">standard_deviation</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-65">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-65">¶</a>
|
||
</div>
|
||
<p>The standard deviation of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.sqrt(variance(x));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-66">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-66">¶</a>
|
||
</div>
|
||
<p>The sum of deviations to the Nth power.
|
||
When n=2 it’s the sum of squared deviations.
|
||
When n=3 it’s the sum of cubed deviations.</p>
|
||
<p>depends on <code>mean()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum_nth_power_deviations</span><span class="hljs-params">(x, n)</span> {</span>
|
||
<span class="hljs-keyword">var</span> mean_value = mean(x),
|
||
sum = <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {
|
||
sum += <span class="hljs-built_in">Math</span>.pow(x[i] - mean_value, n);
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> sum;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-67">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-67">¶</a>
|
||
</div>
|
||
<h1 id="-variance-http-en-wikipedia-org-wiki-variance-"><a href="http://en.wikipedia.org/wiki/Variance">variance</a></h1>
|
||
<p>is the sum of squared deviations from the mean</p>
|
||
<p>depends on <code>sum_nth_power_deviations</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample_variance</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-68">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-68">¶</a>
|
||
</div>
|
||
<p>The variance of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length <= <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> sum_squared_deviations_value = sum_nth_power_deviations(x, <span class="hljs-number">2</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-69">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-69">¶</a>
|
||
</div>
|
||
<p>Find the mean value of that list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sum_squared_deviations_value / (x.length - <span class="hljs-number">1</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-70">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-70">¶</a>
|
||
</div>
|
||
<h1 id="-standard-deviation-http-en-wikipedia-org-wiki-standard_deviation-"><a href="http://en.wikipedia.org/wiki/Standard_deviation">standard deviation</a></h1>
|
||
<p>is just the square root of the variance.</p>
|
||
<p>depends on <code>sample_variance()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample_standard_deviation</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-71">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-71">¶</a>
|
||
</div>
|
||
<p>The standard deviation of no numbers is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length <= <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.sqrt(sample_variance(x));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-72">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-72">¶</a>
|
||
</div>
|
||
<h1 id="-covariance-http-en-wikipedia-org-wiki-covariance-"><a href="http://en.wikipedia.org/wiki/Covariance">covariance</a></h1>
|
||
<p>sample covariance of two datasets:
|
||
how much do the two datasets move together?
|
||
x and y are two datasets, represented as arrays of numbers.</p>
|
||
<p>depends on <code>mean()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample_covariance</span><span class="hljs-params">(x, y)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-73">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-73">¶</a>
|
||
</div>
|
||
<p>The two datasets must have the same length which must be more than 1</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length <= <span class="hljs-number">1</span> || x.length != y.length){
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-74">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-74">¶</a>
|
||
</div>
|
||
<p>determine the mean of each dataset so that we can judge each
|
||
value of the dataset fairly as the difference from the mean. this
|
||
way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance
|
||
does not suffer because of the difference in absolute values</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> xmean = mean(x),
|
||
ymean = mean(y),
|
||
sum = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-75">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-75">¶</a>
|
||
</div>
|
||
<p>for each pair of values, the covariance increases when their
|
||
difference from the mean is associated - if both are well above
|
||
or if both are well below
|
||
the mean, the covariance increases significantly.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++){
|
||
sum += (x[i] - xmean) * (y[i] - ymean);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-76">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-76">¶</a>
|
||
</div>
|
||
<p>the covariance is weighted by the length of the datasets.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sum / (x.length - <span class="hljs-number">1</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-77">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-77">¶</a>
|
||
</div>
|
||
<h1 id="-correlation-http-en-wikipedia-org-wiki-correlation_and_dependence-"><a href="http://en.wikipedia.org/wiki/Correlation_and_dependence">correlation</a></h1>
|
||
<p>Gets a measure of how correlated two datasets are, between -1 and 1</p>
|
||
<p>depends on <code>sample_standard_deviation()</code> and <code>sample_covariance()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample_correlation</span><span class="hljs-params">(x, y)</span> {</span>
|
||
<span class="hljs-keyword">var</span> cov = sample_covariance(x, y),
|
||
xstd = sample_standard_deviation(x),
|
||
ystd = sample_standard_deviation(y);
|
||
|
||
<span class="hljs-keyword">if</span> (cov === <span class="hljs-literal">null</span> || xstd === <span class="hljs-literal">null</span> || ystd === <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> cov / xstd / ystd;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-78">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-78">¶</a>
|
||
</div>
|
||
<h1 id="-median-http-en-wikipedia-org-wiki-median-"><a href="http://en.wikipedia.org/wiki/Median">median</a></h1>
|
||
<p>The middle number of a list. This is often a good indicator of ‘the middle’
|
||
when there are outliers that skew the <code>mean()</code> value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">median</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-79">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-79">¶</a>
|
||
</div>
|
||
<p>The median of an empty list is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-80">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-80">¶</a>
|
||
</div>
|
||
<p>Sorting the array makes it easy to find the center, but
|
||
use <code>.slice()</code> to ensure the original array <code>x</code> is not modified</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sorted = x.slice().sort(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(a, b)</span> {</span> <span class="hljs-keyword">return</span> a - b; });</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-81">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-81">¶</a>
|
||
</div>
|
||
<p>If the length of the list is odd, it’s the central number</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (sorted.length % <span class="hljs-number">2</span> === <span class="hljs-number">1</span>) {
|
||
<span class="hljs-keyword">return</span> sorted[(sorted.length - <span class="hljs-number">1</span>) / <span class="hljs-number">2</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-82">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-82">¶</a>
|
||
</div>
|
||
<p>Otherwise, the median is the average of the two numbers
|
||
at the center of the list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">var</span> a = sorted[(sorted.length / <span class="hljs-number">2</span>) - <span class="hljs-number">1</span>];
|
||
<span class="hljs-keyword">var</span> b = sorted[(sorted.length / <span class="hljs-number">2</span>)];
|
||
<span class="hljs-keyword">return</span> (a + b) / <span class="hljs-number">2</span>;
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-83">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-83">¶</a>
|
||
</div>
|
||
<h1 id="-mode-http-bit-ly-w5k4yt-"><a href="http://bit.ly/W5K4Yt">mode</a></h1>
|
||
<p>The mode is the number that appears in a list the highest number of times.
|
||
There can be multiple modes in a list: in the event of a tie, this
|
||
algorithm will return the most recently seen mode.</p>
|
||
<p>This implementation is inspired by <a href="https://github.com/jasondavies/science.js/blob/master/src/stats/mode.js">science.js</a></p>
|
||
<p>This runs on <code>O(n)</code>, linear time in respect to the array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mode</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-84">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-84">¶</a>
|
||
</div>
|
||
<p>Handle edge cases:
|
||
The median of an empty list is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (x.length === <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> x[<span class="hljs-number">0</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-85">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-85">¶</a>
|
||
</div>
|
||
<p>Sorting the array lets us iterate through it below and be sure
|
||
that every time we see a new number it’s new and we’ll never
|
||
see the same number twice</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sorted = x.slice().sort(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(a, b)</span> {</span> <span class="hljs-keyword">return</span> a - b; });</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-86">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-86">¶</a>
|
||
</div>
|
||
<p>This assumes it is dealing with an array of size > 1, since size
|
||
0 and 1 are handled immediately. Hence it starts at index 1 in the
|
||
array.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> last = sorted[<span class="hljs-number">0</span>],</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-87">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-87">¶</a>
|
||
</div>
|
||
<p>store the mode as we find new modes</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> value,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-88">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-88">¶</a>
|
||
</div>
|
||
<p>store how many times we’ve seen the mode</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> max_seen = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-89">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-89">¶</a>
|
||
</div>
|
||
<p>how many times the current candidate for the mode
|
||
has been seen</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> seen_this = <span class="hljs-number">1</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-90">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-90">¶</a>
|
||
</div>
|
||
<p>end at sorted.length + 1 to fix the case in which the mode is
|
||
the highest number that occurs in the sequence. the last iteration
|
||
compares sorted[i], which is undefined, to the highest number
|
||
in the series</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">1</span>; i < sorted.length + <span class="hljs-number">1</span>; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-91">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-91">¶</a>
|
||
</div>
|
||
<p>we’re seeing a new number pass by</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (sorted[i] !== last) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-92">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-92">¶</a>
|
||
</div>
|
||
<p>the last number is the new mode since we saw it more
|
||
often than the old one</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (seen_this > max_seen) {
|
||
max_seen = seen_this;
|
||
value = last;
|
||
}
|
||
seen_this = <span class="hljs-number">1</span>;
|
||
last = sorted[i];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-93">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-93">¶</a>
|
||
</div>
|
||
<p>if this isn’t a new number, it’s one more occurrence of
|
||
the potential mode</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> { seen_this++; }
|
||
}
|
||
<span class="hljs-keyword">return</span> value;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-94">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-94">¶</a>
|
||
</div>
|
||
<h1 id="-t-test-http-en-wikipedia-org-wiki-student-s_t-test-"><a href="http://en.wikipedia.org/wiki/Student's_t-test">t-test</a></h1>
|
||
<p>This is to compute a one-sample t-test, comparing the mean
|
||
of a sample to a known value, x.</p>
|
||
<p>in this case, we’re trying to determine whether the
|
||
population mean is equal to the value that we know, which is <code>x</code>
|
||
here. usually the results here are used to look up a
|
||
<a href="http://en.wikipedia.org/wiki/P-value">p-value</a>, which, for
|
||
a certain level of significance, will let you determine that the
|
||
null hypothesis can or cannot be rejected.</p>
|
||
<p>Depends on <code>standard_deviation()</code> and <code>mean()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">t_test</span><span class="hljs-params">(sample, x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-95">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-95">¶</a>
|
||
</div>
|
||
<p>The mean of the sample</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sample_mean = mean(sample);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-96">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-96">¶</a>
|
||
</div>
|
||
<p>The standard deviation of the sample</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sd = standard_deviation(sample);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-97">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-97">¶</a>
|
||
</div>
|
||
<p>Square root the length of the sample</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> rootN = <span class="hljs-built_in">Math</span>.sqrt(sample.length);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-98">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-98">¶</a>
|
||
</div>
|
||
<p>Compute the known value against the sample,
|
||
returning the t value</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> (sample_mean - x) / (sd / rootN);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-99">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-99">¶</a>
|
||
</div>
|
||
<h1 id="-2-sample-t-test-http-en-wikipedia-org-wiki-student-s_t-test-"><a href="http://en.wikipedia.org/wiki/Student's_t-test">2-sample t-test</a></h1>
|
||
<p>This is to compute two sample t-test.
|
||
Tests whether “mean(X)-mean(Y) = difference”, (
|
||
in the most common case, we often have <code>difference == 0</code> to test if two samples
|
||
are likely to be taken from populations with the same mean value) with
|
||
no prior knowledge on standard deviations of both samples
|
||
other than the fact that they have the same standard deviation.</p>
|
||
<p>Usually the results here are used to look up a
|
||
<a href="http://en.wikipedia.org/wiki/P-value">p-value</a>, which, for
|
||
a certain level of significance, will let you determine that the
|
||
null hypothesis can or cannot be rejected.</p>
|
||
<p><code>diff</code> can be omitted if it equals 0.</p>
|
||
<p><a href="http://www.monarchlab.org/Lab/Research/Stats/2SampleT.aspx">This is used to confirm or deny</a>
|
||
a null hypothesis that the two populations that have been sampled into
|
||
<code>sample_x</code> and <code>sample_y</code> are equal to each other.</p>
|
||
<p>Depends on <code>sample_variance()</code> and <code>mean()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">t_test_two_sample</span><span class="hljs-params">(sample_x, sample_y, difference)</span> {</span>
|
||
<span class="hljs-keyword">var</span> n = sample_x.length,
|
||
m = sample_y.length;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-100">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-100">¶</a>
|
||
</div>
|
||
<p>If either sample doesn’t actually have any values, we can’t
|
||
compute this at all, so we return <code>null</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!n || !m) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span> ;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-101">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-101">¶</a>
|
||
</div>
|
||
<p>default difference (mu) is zero</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!difference) difference = <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-keyword">var</span> meanX = mean(sample_x),
|
||
meanY = mean(sample_y);
|
||
|
||
<span class="hljs-keyword">var</span> weightedVariance = ((n - <span class="hljs-number">1</span>) * sample_variance(sample_x) +
|
||
(m - <span class="hljs-number">1</span>) * sample_variance(sample_y)) / (n + m - <span class="hljs-number">2</span>);
|
||
|
||
<span class="hljs-keyword">return</span> (meanX - meanY - difference) /
|
||
<span class="hljs-built_in">Math</span>.sqrt(weightedVariance * (<span class="hljs-number">1</span> / n + <span class="hljs-number">1</span> / m));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-102">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-102">¶</a>
|
||
</div>
|
||
<h1 id="chunk">chunk</h1>
|
||
<p>Split an array into chunks of a specified size. This function
|
||
has the same behavior as <a href="http://php.net/manual/en/function.array-chunk.php">PHP’s array_chunk</a>
|
||
function, and thus will insert smaller-sized chunks at the end if
|
||
the input size is not divisible by the chunk size.</p>
|
||
<p><code>sample</code> is expected to be an array, and <code>chunkSize</code> a number.
|
||
The <code>sample</code> array can contain any kind of data.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">chunk</span><span class="hljs-params">(sample, chunkSize)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-103">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-103">¶</a>
|
||
</div>
|
||
<p>a list of result chunks, as arrays in an array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> output = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-104">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-104">¶</a>
|
||
</div>
|
||
<p><code>chunkSize</code> must be zero or higher - otherwise the loop below,
|
||
in which we call <code>start += chunkSize</code>, will loop infinitely.
|
||
So, we’ll detect and return null in that case to indicate
|
||
invalid input.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (chunkSize <= <span class="hljs-number">0</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-105">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-105">¶</a>
|
||
</div>
|
||
<p><code>start</code> is the index at which <code>.slice</code> will start selecting
|
||
new array elements</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> start = <span class="hljs-number">0</span>; start < sample.length; start += chunkSize) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-106">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-106">¶</a>
|
||
</div>
|
||
<p>for each chunk, slice that part of the array and add it
|
||
to the output. The <code>.slice</code> function does not change
|
||
the original array.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> output.push(sample.slice(start, start + chunkSize));
|
||
}
|
||
<span class="hljs-keyword">return</span> output;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-107">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-107">¶</a>
|
||
</div>
|
||
<h1 id="shuffle_in_place">shuffle_in_place</h1>
|
||
<p>A <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle</a>
|
||
in-place - which means that it will change the order of the original
|
||
array by reference.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">shuffle_in_place</span><span class="hljs-params">(sample, randomSource)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-108">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-108">¶</a>
|
||
</div>
|
||
<p>a custom random number source can be provided if you want to use
|
||
a fixed seed or another random number generator, like
|
||
<a href="https://www.npmjs.org/package/random-js">random-js</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> randomSource = randomSource || <span class="hljs-built_in">Math</span>.random;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-109">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-109">¶</a>
|
||
</div>
|
||
<p>store the current length of the sample to determine
|
||
when no elements remain to shuffle.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> length = sample.length;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-110">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-110">¶</a>
|
||
</div>
|
||
<p>temporary is used to hold an item when it is being
|
||
swapped between indices.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> temporary;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-111">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-111">¶</a>
|
||
</div>
|
||
<p>The index to swap at each stage.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> index;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-112">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-112">¶</a>
|
||
</div>
|
||
<p>While there are still items to shuffle</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (length > <span class="hljs-number">0</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-113">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-113">¶</a>
|
||
</div>
|
||
<p>chose a random index within the subset of the array
|
||
that is not yet shuffled</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> index = <span class="hljs-built_in">Math</span>.floor(randomSource() * length--);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-114">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-114">¶</a>
|
||
</div>
|
||
<p>store the value that we’ll move temporarily</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> temporary = sample[length];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-115">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-115">¶</a>
|
||
</div>
|
||
<p>swap the value at <code>sample[length]</code> with <code>sample[index]</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> sample[length] = sample[index];
|
||
sample[index] = temporary;
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> sample;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-116">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-116">¶</a>
|
||
</div>
|
||
<h1 id="shuffle">shuffle</h1>
|
||
<p>A <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle</a>
|
||
is a fast way to create a random permutation of a finite set.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">shuffle</span><span class="hljs-params">(sample, randomSource)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-117">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-117">¶</a>
|
||
</div>
|
||
<p>slice the original array so that it is not modified</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> sample = sample.slice();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-118">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-118">¶</a>
|
||
</div>
|
||
<p>and then shuffle that shallow-copied array, in place</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> shuffle_in_place(sample.slice(), randomSource);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-119">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-119">¶</a>
|
||
</div>
|
||
<h1 id="sample">sample</h1>
|
||
<p>Create a <a href="http://en.wikipedia.org/wiki/Simple_random_sample">simple random sample</a>
|
||
from a given array of <code>n</code> elements.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample</span><span class="hljs-params">(array, n, randomSource)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-120">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-120">¶</a>
|
||
</div>
|
||
<p>shuffle the original array using a fisher-yates shuffle</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> shuffled = shuffle(array, randomSource);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-121">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-121">¶</a>
|
||
</div>
|
||
<p>and then return a subset of it - the first <code>n</code> elements.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> shuffled.slice(<span class="hljs-number">0</span>, n);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-122">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-122">¶</a>
|
||
</div>
|
||
<h1 id="quantile">quantile</h1>
|
||
<p>This is a population quantile, since we assume to know the entire
|
||
dataset in this library. Thus I’m trying to follow the
|
||
<a href="http://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population">Quantiles of a Population</a>
|
||
algorithm from wikipedia.</p>
|
||
<p>Sample is a one-dimensional array of numbers,
|
||
and p is either a decimal number from 0 to 1 or an array of decimal
|
||
numbers from 0 to 1.
|
||
In terms of a k/q quantile, p = k/q - it’s just dealing with fractions or dealing
|
||
with decimal values.
|
||
When p is an array, the result of the function is also an array containing the appropriate
|
||
quantiles in input order</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">quantile</span><span class="hljs-params">(sample, p)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-123">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-123">¶</a>
|
||
</div>
|
||
<p>We can’t derive quantiles from an empty list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (sample.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-124">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-124">¶</a>
|
||
</div>
|
||
<p>Sort a copy of the array. We’ll need a sorted array to index
|
||
the values in sorted order.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sorted = sample.slice().sort(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(a, b)</span> {</span> <span class="hljs-keyword">return</span> a - b; });
|
||
|
||
<span class="hljs-keyword">if</span> (p.length) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-125">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-125">¶</a>
|
||
</div>
|
||
<p>Initialize the result array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> results = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-126">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-126">¶</a>
|
||
</div>
|
||
<p>For each requested quantile</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < p.length; i++) {
|
||
results[i] = quantile_sorted(sorted, p[i]);
|
||
}
|
||
<span class="hljs-keyword">return</span> results;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">return</span> quantile_sorted(sorted, p);
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-127">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-127">¶</a>
|
||
</div>
|
||
<h1 id="quantile">quantile</h1>
|
||
<p>This is the internal implementation of quantiles: when you know
|
||
that the order is sorted, you don’t need to re-sort it, and the computations
|
||
are much faster.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">quantile_sorted</span><span class="hljs-params">(sample, p)</span> {</span>
|
||
<span class="hljs-keyword">var</span> idx = (sample.length) * p;
|
||
<span class="hljs-keyword">if</span> (p < <span class="hljs-number">0</span> || p > <span class="hljs-number">1</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (p === <span class="hljs-number">1</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-128">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-128">¶</a>
|
||
</div>
|
||
<p>If p is 1, directly return the last element</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sample[sample.length - <span class="hljs-number">1</span>];
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (p === <span class="hljs-number">0</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-129">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-129">¶</a>
|
||
</div>
|
||
<p>If p is 0, directly return the first element</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sample[<span class="hljs-number">0</span>];
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (idx % <span class="hljs-number">1</span> !== <span class="hljs-number">0</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-130">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-130">¶</a>
|
||
</div>
|
||
<p>If p is not integer, return the next element in array</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sample[<span class="hljs-built_in">Math</span>.ceil(idx) - <span class="hljs-number">1</span>];
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (sample.length % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-131">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-131">¶</a>
|
||
</div>
|
||
<p>If the list has even-length, we’ll take the average of this number
|
||
and the next value, if there is one</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> (sample[idx - <span class="hljs-number">1</span>] + sample[idx]) / <span class="hljs-number">2</span>;
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-132">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-132">¶</a>
|
||
</div>
|
||
<p>Finally, in the simple case of an integer value
|
||
with an odd-length list, return the sample value at the index.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> sample[idx];
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-133">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-133">¶</a>
|
||
</div>
|
||
<h1 id="-interquartile-range-http-en-wikipedia-org-wiki-interquartile_range-"><a href="http://en.wikipedia.org/wiki/Interquartile_range">Interquartile range</a></h1>
|
||
<p>A measure of statistical dispersion, or how scattered, spread, or
|
||
concentrated a distribution is. It’s computed as the difference between
|
||
the third quartile and first quartile.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">iqr</span><span class="hljs-params">(sample)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-134">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-134">¶</a>
|
||
</div>
|
||
<p>We can’t derive quantiles from an empty list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (sample.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-135">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-135">¶</a>
|
||
</div>
|
||
<p>Interquartile range is the span between the upper quartile,
|
||
at <code>0.75</code>, and lower quartile, <code>0.25</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> quantile(sample, <span class="hljs-number">0.75</span>) - quantile(sample, <span class="hljs-number">0.25</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-136">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-136">¶</a>
|
||
</div>
|
||
<h1 id="-median-absolute-deviation-http-en-wikipedia-org-wiki-median_absolute_deviation-"><a href="http://en.wikipedia.org/wiki/Median_absolute_deviation">Median Absolute Deviation</a></h1>
|
||
<p>The Median Absolute Deviation (MAD) is a robust measure of statistical
|
||
dispersion. It is more resilient to outliers than the standard deviation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mad</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-137">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-137">¶</a>
|
||
</div>
|
||
<p>The mad of nothing is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!x || x.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> median_value = median(x),
|
||
median_absolute_deviations = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-138">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-138">¶</a>
|
||
</div>
|
||
<p>Make a list of absolute deviations from the median</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < x.length; i++) {
|
||
median_absolute_deviations.push(<span class="hljs-built_in">Math</span>.abs(x[i] - median_value));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-139">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-139">¶</a>
|
||
</div>
|
||
<p>Find the median value of that list</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> median(median_absolute_deviations);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-140">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-140">¶</a>
|
||
</div>
|
||
<h2 id="compute-matrices-for-jenks">Compute Matrices for Jenks</h2>
|
||
<p>Compute the matrices required for Jenks breaks. These matrices
|
||
can be used for any classing of data with <code>classes <= n_classes</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">jenksMatrices</span><span class="hljs-params">(data, n_classes)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-141">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-141">¶</a>
|
||
</div>
|
||
<p>in the original implementation, these matrices are referred to
|
||
as <code>LC</code> and <code>OP</code></p>
|
||
<ul>
|
||
<li>lower_class_limits (LC): optimal lower class limits</li>
|
||
<li>variance_combinations (OP): optimal variance combinations for all classes</li>
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> lower_class_limits = [],
|
||
variance_combinations = [],</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-142">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-142">¶</a>
|
||
</div>
|
||
<p>loop counters</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> i, j,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-143">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-143">¶</a>
|
||
</div>
|
||
<p>the variance, as computed at each step in the calculation</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> variance = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-144">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-144">¶</a>
|
||
</div>
|
||
<p>Initialize and fill each matrix with zeroes</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < data.length + <span class="hljs-number">1</span>; i++) {
|
||
<span class="hljs-keyword">var</span> tmp1 = [], tmp2 = [];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-145">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-145">¶</a>
|
||
</div>
|
||
<p>despite these arrays having the same values, we need
|
||
to keep them separate so that changing one does not change
|
||
the other</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (j = <span class="hljs-number">0</span>; j < n_classes + <span class="hljs-number">1</span>; j++) {
|
||
tmp1.push(<span class="hljs-number">0</span>);
|
||
tmp2.push(<span class="hljs-number">0</span>);
|
||
}
|
||
lower_class_limits.push(tmp1);
|
||
variance_combinations.push(tmp2);
|
||
}
|
||
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>; i < n_classes + <span class="hljs-number">1</span>; i++) {
|
||
lower_class_limits[<span class="hljs-number">1</span>][i] = <span class="hljs-number">1</span>;
|
||
variance_combinations[<span class="hljs-number">1</span>][i] = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-146">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-146">¶</a>
|
||
</div>
|
||
<p>in the original implementation, 9999999 is used but
|
||
since Javascript has <code>Infinity</code>, we use that.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (j = <span class="hljs-number">2</span>; j < data.length + <span class="hljs-number">1</span>; j++) {
|
||
variance_combinations[j][i] = <span class="hljs-literal">Infinity</span>;
|
||
}
|
||
}
|
||
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> l = <span class="hljs-number">2</span>; l < data.length + <span class="hljs-number">1</span>; l++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-147">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-147">¶</a>
|
||
</div>
|
||
<p><code>SZ</code> originally. this is the sum of the values seen thus
|
||
far when calculating variance.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> sum = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-148">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-148">¶</a>
|
||
</div>
|
||
<p><code>ZSQ</code> originally. the sum of squares of values seen
|
||
thus far</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> sum_squares = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-149">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-149">¶</a>
|
||
</div>
|
||
<p><code>WT</code> originally. This is the number of</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> w = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-150">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-150">¶</a>
|
||
</div>
|
||
<p><code>IV</code> originally</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> i4 = <span class="hljs-number">0</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-151">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-151">¶</a>
|
||
</div>
|
||
<p>in several instances, you could say <code>Math.pow(x, 2)</code>
|
||
instead of <code>x * x</code>, but this is slower in some browsers
|
||
introduces an unnecessary concept.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> m = <span class="hljs-number">1</span>; m < l + <span class="hljs-number">1</span>; m++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-152">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-152">¶</a>
|
||
</div>
|
||
<p><code>III</code> originally</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> lower_class_limit = l - m + <span class="hljs-number">1</span>,
|
||
val = data[lower_class_limit - <span class="hljs-number">1</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-153">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-153">¶</a>
|
||
</div>
|
||
<p>here we’re estimating variance for each potential classing
|
||
of the data, for each potential number of classes. <code>w</code>
|
||
is the number of data points considered so far.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> w++;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-154">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-154">¶</a>
|
||
</div>
|
||
<p>increase the current sum and sum-of-squares</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> sum += val;
|
||
sum_squares += val * val;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-155">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-155">¶</a>
|
||
</div>
|
||
<p>the variance at this point in the sequence is the difference
|
||
between the sum of squares and the total x 2, over the number
|
||
of samples.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> variance = sum_squares - (sum * sum) / w;
|
||
|
||
i4 = lower_class_limit - <span class="hljs-number">1</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (i4 !== <span class="hljs-number">0</span>) {
|
||
<span class="hljs-keyword">for</span> (j = <span class="hljs-number">2</span>; j < n_classes + <span class="hljs-number">1</span>; j++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-156">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-156">¶</a>
|
||
</div>
|
||
<p>if adding this element to an existing class
|
||
will increase its variance beyond the limit, break
|
||
the class at this point, setting the <code>lower_class_limit</code>
|
||
at this point.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (variance_combinations[l][j] >=
|
||
(variance + variance_combinations[i4][j - <span class="hljs-number">1</span>])) {
|
||
lower_class_limits[l][j] = lower_class_limit;
|
||
variance_combinations[l][j] = variance +
|
||
variance_combinations[i4][j - <span class="hljs-number">1</span>];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
lower_class_limits[l][<span class="hljs-number">1</span>] = <span class="hljs-number">1</span>;
|
||
variance_combinations[l][<span class="hljs-number">1</span>] = variance;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-157">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-157">¶</a>
|
||
</div>
|
||
<p>return the two matrices. for just providing breaks, only
|
||
<code>lower_class_limits</code> is needed, but variances can be useful to
|
||
evaluate goodness of fit.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> {
|
||
lower_class_limits: lower_class_limits,
|
||
variance_combinations: variance_combinations
|
||
};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-158">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-158">¶</a>
|
||
</div>
|
||
<h2 id="pull-breaks-values-for-jenks">Pull Breaks Values for Jenks</h2>
|
||
<p>the second part of the jenks recipe: take the calculated matrices
|
||
and derive an array of n breaks.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">jenksBreaks</span><span class="hljs-params">(data, lower_class_limits, n_classes)</span> {</span>
|
||
|
||
<span class="hljs-keyword">var</span> k = data.length - <span class="hljs-number">1</span>,
|
||
kclass = [],
|
||
countNum = n_classes;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-159">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-159">¶</a>
|
||
</div>
|
||
<p>the calculation of classes will never include the upper and
|
||
lower bounds, so we need to explicitly set them</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> kclass[n_classes] = data[data.length - <span class="hljs-number">1</span>];
|
||
kclass[<span class="hljs-number">0</span>] = data[<span class="hljs-number">0</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-160">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-160">¶</a>
|
||
</div>
|
||
<p>the lower_class_limits matrix is used as indices into itself
|
||
here: the <code>k</code> variable is reused in each iteration.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (countNum > <span class="hljs-number">1</span>) {
|
||
kclass[countNum - <span class="hljs-number">1</span>] = data[lower_class_limits[k][countNum] - <span class="hljs-number">2</span>];
|
||
k = lower_class_limits[k][countNum] - <span class="hljs-number">1</span>;
|
||
countNum--;
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> kclass;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-161">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-161">¶</a>
|
||
</div>
|
||
<h1 id="-jenks-natural-breaks-optimization-http-en-wikipedia-org-wiki-jenks_natural_breaks_optimization-"><a href="http://en.wikipedia.org/wiki/Jenks_natural_breaks_optimization">Jenks natural breaks optimization</a></h1>
|
||
<p>Implementations: <a href="http://danieljlewis.org/files/2010/06/Jenks.pdf">1</a> (python),
|
||
<a href="https://github.com/vvoovv/djeo-jenks/blob/master/main.js">2</a> (buggy),
|
||
<a href="https://github.com/simogeo/geostats/blob/master/lib/geostats.js#L407">3</a> (works)</p>
|
||
<p>Depends on <code>jenksBreaks()</code> and <code>jenksMatrices()</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">jenks</span><span class="hljs-params">(data, n_classes)</span> {</span>
|
||
|
||
<span class="hljs-keyword">if</span> (n_classes > data.length) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-162">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-162">¶</a>
|
||
</div>
|
||
<p>sort data in numerical order, since this is expected
|
||
by the matrices function</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> data = data.slice().sort(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(a, b)</span> {</span> <span class="hljs-keyword">return</span> a - b; });</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-163">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-163">¶</a>
|
||
</div>
|
||
<p>get our basic matrices</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> matrices = jenksMatrices(data, n_classes),</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-164">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-164">¶</a>
|
||
</div>
|
||
<p>we only need lower class limits here</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> lower_class_limits = matrices.lower_class_limits;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-165">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-165">¶</a>
|
||
</div>
|
||
<p>extract n_classes out of the computed matrices</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> jenksBreaks(data, lower_class_limits, n_classes);
|
||
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-166">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-166">¶</a>
|
||
</div>
|
||
<h1 id="-skewness-http-en-wikipedia-org-wiki-skewness-"><a href="http://en.wikipedia.org/wiki/Skewness">Skewness</a></h1>
|
||
<p>A measure of the extent to which a probability distribution of a
|
||
real-valued random variable “leans” to one side of the mean.
|
||
The skewness value can be positive or negative, or even undefined.</p>
|
||
<p>Implementation is based on the adjusted Fisher-Pearson standardized
|
||
moment coefficient, which is the version found in Excel and several
|
||
statistical packages including Minitab, SAS and SPSS.</p>
|
||
<p>Depends on <code>sum_nth_power_deviations()</code> and <code>sample_standard_deviation</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sample_skewness</span><span class="hljs-params">(x)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-167">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-167">¶</a>
|
||
</div>
|
||
<p>The skewness of less than three arguments is null</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x.length < <span class="hljs-number">3</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
|
||
<span class="hljs-keyword">var</span> n = x.length,
|
||
cubed_s = <span class="hljs-built_in">Math</span>.pow(sample_standard_deviation(x), <span class="hljs-number">3</span>),
|
||
sum_cubed_deviations = sum_nth_power_deviations(x, <span class="hljs-number">3</span>);
|
||
|
||
<span class="hljs-keyword">return</span> n * sum_cubed_deviations / ((n - <span class="hljs-number">1</span>) * (n - <span class="hljs-number">2</span>) * cubed_s);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-168">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-168">¶</a>
|
||
</div>
|
||
<h1 id="standard-normal-table">Standard Normal Table</h1>
|
||
<p>A standard normal table, also called the unit normal table or Z table,
|
||
is a mathematical table for the values of Φ (phi), which are the values of
|
||
the cumulative distribution function of the normal distribution.
|
||
It is used to find the probability that a statistic is observed below,
|
||
above, or between values on the standard normal distribution, and by
|
||
extension, any normal distribution.</p>
|
||
<p>The probabilities are taken from <a href="http://en.wikipedia.org/wiki/Standard_normal_table">http://en.wikipedia.org/wiki/Standard_normal_table</a>
|
||
The table used is the cumulative, and not cumulative from 0 to mean
|
||
(even though the latter has 5 digits precision, instead of 4).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> standard_normal_table = [
|
||
<span class="hljs-comment">/* z 0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 */</span>
|
||
<span class="hljs-comment">/* 0.0 */</span>
|
||
<span class="hljs-number">0.5000</span>, <span class="hljs-number">0.5040</span>, <span class="hljs-number">0.5080</span>, <span class="hljs-number">0.5120</span>, <span class="hljs-number">0.5160</span>, <span class="hljs-number">0.5199</span>, <span class="hljs-number">0.5239</span>, <span class="hljs-number">0.5279</span>, <span class="hljs-number">0.5319</span>, <span class="hljs-number">0.5359</span>,
|
||
<span class="hljs-comment">/* 0.1 */</span>
|
||
<span class="hljs-number">0.5398</span>, <span class="hljs-number">0.5438</span>, <span class="hljs-number">0.5478</span>, <span class="hljs-number">0.5517</span>, <span class="hljs-number">0.5557</span>, <span class="hljs-number">0.5596</span>, <span class="hljs-number">0.5636</span>, <span class="hljs-number">0.5675</span>, <span class="hljs-number">0.5714</span>, <span class="hljs-number">0.5753</span>,
|
||
<span class="hljs-comment">/* 0.2 */</span>
|
||
<span class="hljs-number">0.5793</span>, <span class="hljs-number">0.5832</span>, <span class="hljs-number">0.5871</span>, <span class="hljs-number">0.5910</span>, <span class="hljs-number">0.5948</span>, <span class="hljs-number">0.5987</span>, <span class="hljs-number">0.6026</span>, <span class="hljs-number">0.6064</span>, <span class="hljs-number">0.6103</span>, <span class="hljs-number">0.6141</span>,
|
||
<span class="hljs-comment">/* 0.3 */</span>
|
||
<span class="hljs-number">0.6179</span>, <span class="hljs-number">0.6217</span>, <span class="hljs-number">0.6255</span>, <span class="hljs-number">0.6293</span>, <span class="hljs-number">0.6331</span>, <span class="hljs-number">0.6368</span>, <span class="hljs-number">0.6406</span>, <span class="hljs-number">0.6443</span>, <span class="hljs-number">0.6480</span>, <span class="hljs-number">0.6517</span>,
|
||
<span class="hljs-comment">/* 0.4 */</span>
|
||
<span class="hljs-number">0.6554</span>, <span class="hljs-number">0.6591</span>, <span class="hljs-number">0.6628</span>, <span class="hljs-number">0.6664</span>, <span class="hljs-number">0.6700</span>, <span class="hljs-number">0.6736</span>, <span class="hljs-number">0.6772</span>, <span class="hljs-number">0.6808</span>, <span class="hljs-number">0.6844</span>, <span class="hljs-number">0.6879</span>,
|
||
<span class="hljs-comment">/* 0.5 */</span>
|
||
<span class="hljs-number">0.6915</span>, <span class="hljs-number">0.6950</span>, <span class="hljs-number">0.6985</span>, <span class="hljs-number">0.7019</span>, <span class="hljs-number">0.7054</span>, <span class="hljs-number">0.7088</span>, <span class="hljs-number">0.7123</span>, <span class="hljs-number">0.7157</span>, <span class="hljs-number">0.7190</span>, <span class="hljs-number">0.7224</span>,
|
||
<span class="hljs-comment">/* 0.6 */</span>
|
||
<span class="hljs-number">0.7257</span>, <span class="hljs-number">0.7291</span>, <span class="hljs-number">0.7324</span>, <span class="hljs-number">0.7357</span>, <span class="hljs-number">0.7389</span>, <span class="hljs-number">0.7422</span>, <span class="hljs-number">0.7454</span>, <span class="hljs-number">0.7486</span>, <span class="hljs-number">0.7517</span>, <span class="hljs-number">0.7549</span>,
|
||
<span class="hljs-comment">/* 0.7 */</span>
|
||
<span class="hljs-number">0.7580</span>, <span class="hljs-number">0.7611</span>, <span class="hljs-number">0.7642</span>, <span class="hljs-number">0.7673</span>, <span class="hljs-number">0.7704</span>, <span class="hljs-number">0.7734</span>, <span class="hljs-number">0.7764</span>, <span class="hljs-number">0.7794</span>, <span class="hljs-number">0.7823</span>, <span class="hljs-number">0.7852</span>,
|
||
<span class="hljs-comment">/* 0.8 */</span>
|
||
<span class="hljs-number">0.7881</span>, <span class="hljs-number">0.7910</span>, <span class="hljs-number">0.7939</span>, <span class="hljs-number">0.7967</span>, <span class="hljs-number">0.7995</span>, <span class="hljs-number">0.8023</span>, <span class="hljs-number">0.8051</span>, <span class="hljs-number">0.8078</span>, <span class="hljs-number">0.8106</span>, <span class="hljs-number">0.8133</span>,
|
||
<span class="hljs-comment">/* 0.9 */</span>
|
||
<span class="hljs-number">0.8159</span>, <span class="hljs-number">0.8186</span>, <span class="hljs-number">0.8212</span>, <span class="hljs-number">0.8238</span>, <span class="hljs-number">0.8264</span>, <span class="hljs-number">0.8289</span>, <span class="hljs-number">0.8315</span>, <span class="hljs-number">0.8340</span>, <span class="hljs-number">0.8365</span>, <span class="hljs-number">0.8389</span>,
|
||
<span class="hljs-comment">/* 1.0 */</span>
|
||
<span class="hljs-number">0.8413</span>, <span class="hljs-number">0.8438</span>, <span class="hljs-number">0.8461</span>, <span class="hljs-number">0.8485</span>, <span class="hljs-number">0.8508</span>, <span class="hljs-number">0.8531</span>, <span class="hljs-number">0.8554</span>, <span class="hljs-number">0.8577</span>, <span class="hljs-number">0.8599</span>, <span class="hljs-number">0.8621</span>,
|
||
<span class="hljs-comment">/* 1.1 */</span>
|
||
<span class="hljs-number">0.8643</span>, <span class="hljs-number">0.8665</span>, <span class="hljs-number">0.8686</span>, <span class="hljs-number">0.8708</span>, <span class="hljs-number">0.8729</span>, <span class="hljs-number">0.8749</span>, <span class="hljs-number">0.8770</span>, <span class="hljs-number">0.8790</span>, <span class="hljs-number">0.8810</span>, <span class="hljs-number">0.8830</span>,
|
||
<span class="hljs-comment">/* 1.2 */</span>
|
||
<span class="hljs-number">0.8849</span>, <span class="hljs-number">0.8869</span>, <span class="hljs-number">0.8888</span>, <span class="hljs-number">0.8907</span>, <span class="hljs-number">0.8925</span>, <span class="hljs-number">0.8944</span>, <span class="hljs-number">0.8962</span>, <span class="hljs-number">0.8980</span>, <span class="hljs-number">0.8997</span>, <span class="hljs-number">0.9015</span>,
|
||
<span class="hljs-comment">/* 1.3 */</span>
|
||
<span class="hljs-number">0.9032</span>, <span class="hljs-number">0.9049</span>, <span class="hljs-number">0.9066</span>, <span class="hljs-number">0.9082</span>, <span class="hljs-number">0.9099</span>, <span class="hljs-number">0.9115</span>, <span class="hljs-number">0.9131</span>, <span class="hljs-number">0.9147</span>, <span class="hljs-number">0.9162</span>, <span class="hljs-number">0.9177</span>,
|
||
<span class="hljs-comment">/* 1.4 */</span>
|
||
<span class="hljs-number">0.9192</span>, <span class="hljs-number">0.9207</span>, <span class="hljs-number">0.9222</span>, <span class="hljs-number">0.9236</span>, <span class="hljs-number">0.9251</span>, <span class="hljs-number">0.9265</span>, <span class="hljs-number">0.9279</span>, <span class="hljs-number">0.9292</span>, <span class="hljs-number">0.9306</span>, <span class="hljs-number">0.9319</span>,
|
||
<span class="hljs-comment">/* 1.5 */</span>
|
||
<span class="hljs-number">0.9332</span>, <span class="hljs-number">0.9345</span>, <span class="hljs-number">0.9357</span>, <span class="hljs-number">0.9370</span>, <span class="hljs-number">0.9382</span>, <span class="hljs-number">0.9394</span>, <span class="hljs-number">0.9406</span>, <span class="hljs-number">0.9418</span>, <span class="hljs-number">0.9429</span>, <span class="hljs-number">0.9441</span>,
|
||
<span class="hljs-comment">/* 1.6 */</span>
|
||
<span class="hljs-number">0.9452</span>, <span class="hljs-number">0.9463</span>, <span class="hljs-number">0.9474</span>, <span class="hljs-number">0.9484</span>, <span class="hljs-number">0.9495</span>, <span class="hljs-number">0.9505</span>, <span class="hljs-number">0.9515</span>, <span class="hljs-number">0.9525</span>, <span class="hljs-number">0.9535</span>, <span class="hljs-number">0.9545</span>,
|
||
<span class="hljs-comment">/* 1.7 */</span>
|
||
<span class="hljs-number">0.9554</span>, <span class="hljs-number">0.9564</span>, <span class="hljs-number">0.9573</span>, <span class="hljs-number">0.9582</span>, <span class="hljs-number">0.9591</span>, <span class="hljs-number">0.9599</span>, <span class="hljs-number">0.9608</span>, <span class="hljs-number">0.9616</span>, <span class="hljs-number">0.9625</span>, <span class="hljs-number">0.9633</span>,
|
||
<span class="hljs-comment">/* 1.8 */</span>
|
||
<span class="hljs-number">0.9641</span>, <span class="hljs-number">0.9649</span>, <span class="hljs-number">0.9656</span>, <span class="hljs-number">0.9664</span>, <span class="hljs-number">0.9671</span>, <span class="hljs-number">0.9678</span>, <span class="hljs-number">0.9686</span>, <span class="hljs-number">0.9693</span>, <span class="hljs-number">0.9699</span>, <span class="hljs-number">0.9706</span>,
|
||
<span class="hljs-comment">/* 1.9 */</span>
|
||
<span class="hljs-number">0.9713</span>, <span class="hljs-number">0.9719</span>, <span class="hljs-number">0.9726</span>, <span class="hljs-number">0.9732</span>, <span class="hljs-number">0.9738</span>, <span class="hljs-number">0.9744</span>, <span class="hljs-number">0.9750</span>, <span class="hljs-number">0.9756</span>, <span class="hljs-number">0.9761</span>, <span class="hljs-number">0.9767</span>,
|
||
<span class="hljs-comment">/* 2.0 */</span>
|
||
<span class="hljs-number">0.9772</span>, <span class="hljs-number">0.9778</span>, <span class="hljs-number">0.9783</span>, <span class="hljs-number">0.9788</span>, <span class="hljs-number">0.9793</span>, <span class="hljs-number">0.9798</span>, <span class="hljs-number">0.9803</span>, <span class="hljs-number">0.9808</span>, <span class="hljs-number">0.9812</span>, <span class="hljs-number">0.9817</span>,
|
||
<span class="hljs-comment">/* 2.1 */</span>
|
||
<span class="hljs-number">0.9821</span>, <span class="hljs-number">0.9826</span>, <span class="hljs-number">0.9830</span>, <span class="hljs-number">0.9834</span>, <span class="hljs-number">0.9838</span>, <span class="hljs-number">0.9842</span>, <span class="hljs-number">0.9846</span>, <span class="hljs-number">0.9850</span>, <span class="hljs-number">0.9854</span>, <span class="hljs-number">0.9857</span>,
|
||
<span class="hljs-comment">/* 2.2 */</span>
|
||
<span class="hljs-number">0.9861</span>, <span class="hljs-number">0.9864</span>, <span class="hljs-number">0.9868</span>, <span class="hljs-number">0.9871</span>, <span class="hljs-number">0.9875</span>, <span class="hljs-number">0.9878</span>, <span class="hljs-number">0.9881</span>, <span class="hljs-number">0.9884</span>, <span class="hljs-number">0.9887</span>, <span class="hljs-number">0.9890</span>,
|
||
<span class="hljs-comment">/* 2.3 */</span>
|
||
<span class="hljs-number">0.9893</span>, <span class="hljs-number">0.9896</span>, <span class="hljs-number">0.9898</span>, <span class="hljs-number">0.9901</span>, <span class="hljs-number">0.9904</span>, <span class="hljs-number">0.9906</span>, <span class="hljs-number">0.9909</span>, <span class="hljs-number">0.9911</span>, <span class="hljs-number">0.9913</span>, <span class="hljs-number">0.9916</span>,
|
||
<span class="hljs-comment">/* 2.4 */</span>
|
||
<span class="hljs-number">0.9918</span>, <span class="hljs-number">0.9920</span>, <span class="hljs-number">0.9922</span>, <span class="hljs-number">0.9925</span>, <span class="hljs-number">0.9927</span>, <span class="hljs-number">0.9929</span>, <span class="hljs-number">0.9931</span>, <span class="hljs-number">0.9932</span>, <span class="hljs-number">0.9934</span>, <span class="hljs-number">0.9936</span>,
|
||
<span class="hljs-comment">/* 2.5 */</span>
|
||
<span class="hljs-number">0.9938</span>, <span class="hljs-number">0.9940</span>, <span class="hljs-number">0.9941</span>, <span class="hljs-number">0.9943</span>, <span class="hljs-number">0.9945</span>, <span class="hljs-number">0.9946</span>, <span class="hljs-number">0.9948</span>, <span class="hljs-number">0.9949</span>, <span class="hljs-number">0.9951</span>, <span class="hljs-number">0.9952</span>,
|
||
<span class="hljs-comment">/* 2.6 */</span>
|
||
<span class="hljs-number">0.9953</span>, <span class="hljs-number">0.9955</span>, <span class="hljs-number">0.9956</span>, <span class="hljs-number">0.9957</span>, <span class="hljs-number">0.9959</span>, <span class="hljs-number">0.9960</span>, <span class="hljs-number">0.9961</span>, <span class="hljs-number">0.9962</span>, <span class="hljs-number">0.9963</span>, <span class="hljs-number">0.9964</span>,
|
||
<span class="hljs-comment">/* 2.7 */</span>
|
||
<span class="hljs-number">0.9965</span>, <span class="hljs-number">0.9966</span>, <span class="hljs-number">0.9967</span>, <span class="hljs-number">0.9968</span>, <span class="hljs-number">0.9969</span>, <span class="hljs-number">0.9970</span>, <span class="hljs-number">0.9971</span>, <span class="hljs-number">0.9972</span>, <span class="hljs-number">0.9973</span>, <span class="hljs-number">0.9974</span>,
|
||
<span class="hljs-comment">/* 2.8 */</span>
|
||
<span class="hljs-number">0.9974</span>, <span class="hljs-number">0.9975</span>, <span class="hljs-number">0.9976</span>, <span class="hljs-number">0.9977</span>, <span class="hljs-number">0.9977</span>, <span class="hljs-number">0.9978</span>, <span class="hljs-number">0.9979</span>, <span class="hljs-number">0.9979</span>, <span class="hljs-number">0.9980</span>, <span class="hljs-number">0.9981</span>,
|
||
<span class="hljs-comment">/* 2.9 */</span>
|
||
<span class="hljs-number">0.9981</span>, <span class="hljs-number">0.9982</span>, <span class="hljs-number">0.9982</span>, <span class="hljs-number">0.9983</span>, <span class="hljs-number">0.9984</span>, <span class="hljs-number">0.9984</span>, <span class="hljs-number">0.9985</span>, <span class="hljs-number">0.9985</span>, <span class="hljs-number">0.9986</span>, <span class="hljs-number">0.9986</span>,
|
||
<span class="hljs-comment">/* 3.0 */</span>
|
||
<span class="hljs-number">0.9987</span>, <span class="hljs-number">0.9987</span>, <span class="hljs-number">0.9987</span>, <span class="hljs-number">0.9988</span>, <span class="hljs-number">0.9988</span>, <span class="hljs-number">0.9989</span>, <span class="hljs-number">0.9989</span>, <span class="hljs-number">0.9989</span>, <span class="hljs-number">0.9990</span>, <span class="hljs-number">0.9990</span>
|
||
];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-169">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-169">¶</a>
|
||
</div>
|
||
<h1 id="-cumulative-standard-normal-probability-http-en-wikipedia-org-wiki-standard_normal_table-"><a href="http://en.wikipedia.org/wiki/Standard_normal_table">Cumulative Standard Normal Probability</a></h1>
|
||
<p>Since probability tables cannot be
|
||
printed for every normal distribution, as there are an infinite variety
|
||
of normal distributions, it is common practice to convert a normal to a
|
||
standard normal and then use the standard normal table to find probabilities</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cumulative_std_normal_probability</span><span class="hljs-params">(z)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-170">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-170">¶</a>
|
||
</div>
|
||
<p>Calculate the position of this value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> absZ = <span class="hljs-built_in">Math</span>.abs(z),</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-171">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-171">¶</a>
|
||
</div>
|
||
<p>Each row begins with a different
|
||
significant digit: 0.5, 0.6, 0.7, and so on. So the row is simply
|
||
this value’s significant digit: 0.567 will be in row 0, so row=0,
|
||
0.643 will be in row 1, so row=10.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> row = <span class="hljs-built_in">Math</span>.floor(absZ * <span class="hljs-number">10</span>),
|
||
column = <span class="hljs-number">10</span> * (<span class="hljs-built_in">Math</span>.floor(absZ * <span class="hljs-number">100</span>) / <span class="hljs-number">10</span> - <span class="hljs-built_in">Math</span>.floor(absZ * <span class="hljs-number">100</span> / <span class="hljs-number">10</span>)),
|
||
index = <span class="hljs-built_in">Math</span>.min((row * <span class="hljs-number">10</span>) + column, standard_normal_table.length - <span class="hljs-number">1</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-172">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-172">¶</a>
|
||
</div>
|
||
<p>The index we calculate must be in the table as a positive value,
|
||
but we still pay attention to whether the input is positive
|
||
or negative, and flip the output value as a last step.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (z >= <span class="hljs-number">0</span>) {
|
||
<span class="hljs-keyword">return</span> standard_normal_table[index];
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-173">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-173">¶</a>
|
||
</div>
|
||
<p>due to floating-point arithmetic, values in the table with
|
||
4 significant figures can nevertheless end up as repeating
|
||
fractions when they’re computed here.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> +(<span class="hljs-number">1</span> - standard_normal_table[index]).toFixed(<span class="hljs-number">4</span>);
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-174">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-174">¶</a>
|
||
</div>
|
||
<h1 id="-z-score-or-standard-score-http-en-wikipedia-org-wiki-standard_score-"><a href="http://en.wikipedia.org/wiki/Standard_score">Z-Score, or Standard Score</a></h1>
|
||
<p>The standard score is the number of standard deviations an observation
|
||
or datum is above or below the mean. Thus, a positive standard score
|
||
represents a datum above the mean, while a negative standard score
|
||
represents a datum below the mean. It is a dimensionless quantity
|
||
obtained by subtracting the population mean from an individual raw
|
||
score and then dividing the difference by the population standard
|
||
deviation.</p>
|
||
<p>The z-score is only defined if one knows the population parameters;
|
||
if one only has a sample set, then the analogous computation with
|
||
sample mean and sample standard deviation yields the
|
||
Student’s t-statistic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">z_score</span><span class="hljs-params">(x, mean, standard_deviation)</span> {</span>
|
||
<span class="hljs-keyword">return</span> (x - mean) / standard_deviation;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-175">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-175">¶</a>
|
||
</div>
|
||
<p>We use <code>ε</code>, epsilon, as a stopping criterion when we want to iterate
|
||
until we’re “close enough”.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> epsilon = <span class="hljs-number">0.0001</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-176">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-176">¶</a>
|
||
</div>
|
||
<h1 id="-factorial-https-en-wikipedia-org-wiki-factorial-"><a href="https://en.wikipedia.org/wiki/Factorial">Factorial</a></h1>
|
||
<p>A factorial, usually written n!, is the product of all positive
|
||
integers less than or equal to n. Often factorial is implemented
|
||
recursively, but this iterative approach is significantly faster
|
||
and simpler.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">factorial</span><span class="hljs-params">(n)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-177">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-177">¶</a>
|
||
</div>
|
||
<p>factorial is mathematically undefined for negative numbers</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (n < <span class="hljs-number">0</span> ) { <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-178">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-178">¶</a>
|
||
</div>
|
||
<p>typically you’ll expand the factorial function going down, like
|
||
5! = 5 <em> 4 </em> 3 <em> 2 </em> 1. This is going in the opposite direction,
|
||
counting from 2 up to the number in question, and since anything
|
||
multiplied by 1 is itself, the loop only needs to start at 2.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> accumulator = <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">2</span>; i <= n; i++) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-179">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-179">¶</a>
|
||
</div>
|
||
<p>for each number up to and including the number <code>n</code>, multiply
|
||
the accumulator my that number.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> accumulator *= i;
|
||
}
|
||
<span class="hljs-keyword">return</span> accumulator;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-180">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-180">¶</a>
|
||
</div>
|
||
<h1 id="bernoulli-distribution">Bernoulli Distribution</h1>
|
||
<p>The <a href="http://en.wikipedia.org/wiki/Bernoulli_distribution">Bernoulli distribution</a>
|
||
is the probability discrete
|
||
distribution of a random variable which takes value 1 with success
|
||
probability <code>p</code> and value 0 with failure
|
||
probability <code>q</code> = 1 - <code>p</code>. It can be used, for example, to represent the
|
||
toss of a coin, where “1” is defined to mean “heads” and “0” is defined
|
||
to mean “tails” (or vice versa). It is
|
||
a special case of a Binomial Distribution
|
||
where <code>n</code> = 1.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bernoulli_distribution</span><span class="hljs-params">(p)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-181">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-181">¶</a>
|
||
</div>
|
||
<p>Check that <code>p</code> is a valid probability (0 ≤ p ≤ 1)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (p < <span class="hljs-number">0</span> || p > <span class="hljs-number">1</span> ) { <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }
|
||
|
||
<span class="hljs-keyword">return</span> binomial_distribution(<span class="hljs-number">1</span>, p);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-182">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-182">¶</a>
|
||
</div>
|
||
<h1 id="binomial-distribution">Binomial Distribution</h1>
|
||
<p>The <a href="http://en.wikipedia.org/wiki/Binomial_distribution">Binomial Distribution</a> is the discrete probability
|
||
distribution of the number of successes in a sequence of n independent yes/no experiments, each of which yields
|
||
success with probability <code>probability</code>. Such a success/failure experiment is also called a Bernoulli experiment or
|
||
Bernoulli trial; when trials = 1, the Binomial Distribution is a Bernoulli Distribution.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">binomial_distribution</span><span class="hljs-params">(trials, probability)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-183">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-183">¶</a>
|
||
</div>
|
||
<p>Check that <code>p</code> is a valid probability (0 ≤ p ≤ 1),
|
||
that <code>n</code> is an integer, strictly positive.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (probability < <span class="hljs-number">0</span> || probability > <span class="hljs-number">1</span> ||
|
||
trials <= <span class="hljs-number">0</span> || trials % <span class="hljs-number">1</span> !== <span class="hljs-number">0</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-184">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-184">¶</a>
|
||
</div>
|
||
<p>a <a href="https://en.wikipedia.org/wiki/Probability_mass_function">probability mass function</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">probability_mass</span><span class="hljs-params">(x, trials, probability)</span> {</span>
|
||
<span class="hljs-keyword">return</span> factorial(trials) /
|
||
(factorial(x) * factorial(trials - x)) *
|
||
(<span class="hljs-built_in">Math</span>.pow(probability, x) * <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">1</span> - probability, trials - x));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-185">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-185">¶</a>
|
||
</div>
|
||
<p>We initialize <code>x</code>, the random variable, and <code>accumulator</code>, an accumulator
|
||
for the cumulative distribution function to 0. <code>distribution_functions</code>
|
||
is the object we’ll return with the <code>probability_of_x</code> and the
|
||
<code>cumulative_probability_of_x</code>, as well as the calculated mean &
|
||
variance. We iterate until the <code>cumulative_probability_of_x</code> is
|
||
within <code>epsilon</code> of 1.0.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>,
|
||
cumulative_probability = <span class="hljs-number">0</span>,
|
||
cells = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-186">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-186">¶</a>
|
||
</div>
|
||
<p>This algorithm iterates through each potential outcome,
|
||
until the <code>cumulative_probability</code> is very close to 1, at
|
||
which point we’ve defined the vast majority of outcomes</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">do</span> {
|
||
cells[x] = probability_mass(x, trials, probability);
|
||
cumulative_probability += cells[x];
|
||
x++;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-187">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-187">¶</a>
|
||
</div>
|
||
<p>when the cumulative_probability is nearly 1, we’ve calculated
|
||
the useful range of this distribution</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">while</span> (cumulative_probability < <span class="hljs-number">1</span> - epsilon);
|
||
|
||
<span class="hljs-keyword">return</span> cells;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-188">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-188">¶</a>
|
||
</div>
|
||
<h1 id="poisson-distribution">Poisson Distribution</h1>
|
||
<p>The <a href="http://en.wikipedia.org/wiki/Poisson_distribution">Poisson Distribution</a>
|
||
is a discrete probability distribution that expresses the probability
|
||
of a given number of events occurring in a fixed interval of time
|
||
and/or space if these events occur with a known average rate and
|
||
independently of the time since the last event.</p>
|
||
<p>The Poisson Distribution is characterized by the strictly positive
|
||
mean arrival or occurrence rate, <code>λ</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">poisson_distribution</span><span class="hljs-params">(lambda)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-189">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-189">¶</a>
|
||
</div>
|
||
<p>Check that lambda is strictly positive</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (lambda <= <span class="hljs-number">0</span>) { <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-190">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-190">¶</a>
|
||
</div>
|
||
<p>our current place in the distribution</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-191">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-191">¶</a>
|
||
</div>
|
||
<p>and we keep track of the current cumulative probability, in
|
||
order to know when to stop calculating chances.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> cumulative_probability = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-192">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-192">¶</a>
|
||
</div>
|
||
<p>the calculated cells to be returned</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> cells = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-193">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-193">¶</a>
|
||
</div>
|
||
<p>a <a href="https://en.wikipedia.org/wiki/Probability_mass_function">probability mass function</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">probability_mass</span><span class="hljs-params">(x, lambda)</span> {</span>
|
||
<span class="hljs-keyword">return</span> (<span class="hljs-built_in">Math</span>.pow(<span class="hljs-built_in">Math</span>.E, -lambda) * <span class="hljs-built_in">Math</span>.pow(lambda, x)) /
|
||
factorial(x);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-194">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-194">¶</a>
|
||
</div>
|
||
<p>This algorithm iterates through each potential outcome,
|
||
until the <code>cumulative_probability</code> is very close to 1, at
|
||
which point we’ve defined the vast majority of outcomes</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">do</span> {
|
||
cells[x] = probability_mass(x, lambda);
|
||
cumulative_probability += cells[x];
|
||
x++;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-195">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-195">¶</a>
|
||
</div>
|
||
<p>when the cumulative_probability is nearly 1, we’ve calculated
|
||
the useful range of this distribution</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">while</span> (cumulative_probability < <span class="hljs-number">1</span> - epsilon);
|
||
|
||
<span class="hljs-keyword">return</span> cells;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-196">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-196">¶</a>
|
||
</div>
|
||
<h1 id="percentage-points-of-the-2-chi-squared-distribution">Percentage Points of the χ2 (Chi-Squared) Distribution</h1>
|
||
<p>The <a href="http://en.wikipedia.org/wiki/Chi-squared_distribution">χ2 (Chi-Squared) Distribution</a> is used in the common
|
||
chi-squared tests for goodness of fit of an observed distribution to a theoretical one, the independence of two
|
||
criteria of classification of qualitative data, and in confidence interval estimation for a population standard
|
||
deviation of a normal distribution from a sample standard deviation.</p>
|
||
<p>Values from Appendix 1, Table III of William W. Hines & Douglas C. Montgomery, “Probability and Statistics in
|
||
Engineering and Management Science”, Wiley (1980).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> chi_squared_distribution_table = {
|
||
<span class="hljs-number">1</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.00</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.00</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">0.00</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">0.00</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">0.02</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">0.45</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">2.71</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">3.84</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">5.02</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">6.63</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">7.88</span> },
|
||
<span class="hljs-number">2</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.01</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.02</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">0.05</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">0.10</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">0.21</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">1.39</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">4.61</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">5.99</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">7.38</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">9.21</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">10.60</span> },
|
||
<span class="hljs-number">3</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.07</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.11</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">0.22</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">0.35</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">0.58</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">2.37</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">6.25</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">7.81</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">9.35</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">11.34</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">12.84</span> },
|
||
<span class="hljs-number">4</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.21</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.30</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">0.48</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">0.71</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">1.06</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">3.36</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">7.78</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">9.49</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">11.14</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">13.28</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">14.86</span> },
|
||
<span class="hljs-number">5</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.41</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.55</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">0.83</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">1.15</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">1.61</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">4.35</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">9.24</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">11.07</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">12.83</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">15.09</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">16.75</span> },
|
||
<span class="hljs-number">6</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.68</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">0.87</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">1.24</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">1.64</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">2.20</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">5.35</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">10.65</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">12.59</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">14.45</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">16.81</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">18.55</span> },
|
||
<span class="hljs-number">7</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">0.99</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">1.25</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">1.69</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">2.17</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">2.83</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">6.35</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">12.02</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">14.07</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">16.01</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">18.48</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">20.28</span> },
|
||
<span class="hljs-number">8</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">1.34</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">1.65</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">2.18</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">2.73</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">3.49</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">7.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">13.36</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">15.51</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">17.53</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">20.09</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">21.96</span> },
|
||
<span class="hljs-number">9</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">1.73</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">2.09</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">2.70</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">3.33</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">4.17</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">8.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">14.68</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">16.92</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">19.02</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">21.67</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">23.59</span> },
|
||
<span class="hljs-number">10</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">2.16</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">2.56</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">3.25</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">3.94</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">4.87</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">9.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">15.99</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">18.31</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">20.48</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">23.21</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">25.19</span> },
|
||
<span class="hljs-number">11</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">2.60</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">3.05</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">3.82</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">4.57</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">5.58</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">10.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">17.28</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">19.68</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">21.92</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">24.72</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">26.76</span> },
|
||
<span class="hljs-number">12</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">3.07</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">3.57</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">4.40</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">5.23</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">6.30</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">11.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">18.55</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">21.03</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">23.34</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">26.22</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">28.30</span> },
|
||
<span class="hljs-number">13</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">3.57</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">4.11</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">5.01</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">5.89</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">7.04</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">12.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">19.81</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">22.36</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">24.74</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">27.69</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">29.82</span> },
|
||
<span class="hljs-number">14</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">4.07</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">4.66</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">5.63</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">6.57</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">7.79</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">13.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">21.06</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">23.68</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">26.12</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">29.14</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">31.32</span> },
|
||
<span class="hljs-number">15</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">4.60</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">5.23</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">6.27</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">7.26</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">8.55</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">14.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">22.31</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">25.00</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">27.49</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">30.58</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">32.80</span> },
|
||
<span class="hljs-number">16</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">5.14</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">5.81</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">6.91</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">7.96</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">9.31</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">15.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">23.54</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">26.30</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">28.85</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">32.00</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">34.27</span> },
|
||
<span class="hljs-number">17</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">5.70</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">6.41</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">7.56</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">8.67</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">10.09</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">16.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">24.77</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">27.59</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">30.19</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">33.41</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">35.72</span> },
|
||
<span class="hljs-number">18</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">6.26</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">7.01</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">8.23</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">9.39</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">10.87</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">17.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">25.99</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">28.87</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">31.53</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">34.81</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">37.16</span> },
|
||
<span class="hljs-number">19</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">6.84</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">7.63</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">8.91</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">10.12</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">11.65</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">18.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">27.20</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">30.14</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">32.85</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">36.19</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">38.58</span> },
|
||
<span class="hljs-number">20</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">7.43</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">8.26</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">9.59</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">10.85</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">12.44</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">19.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">28.41</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">31.41</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">34.17</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">37.57</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">40.00</span> },
|
||
<span class="hljs-number">21</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">8.03</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">8.90</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">10.28</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">11.59</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">13.24</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">20.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">29.62</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">32.67</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">35.48</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">38.93</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">41.40</span> },
|
||
<span class="hljs-number">22</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">8.64</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">9.54</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">10.98</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">12.34</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">14.04</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">21.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">30.81</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">33.92</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">36.78</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">40.29</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">42.80</span> },
|
||
<span class="hljs-number">23</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">9.26</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">10.20</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">11.69</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">13.09</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">14.85</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">22.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">32.01</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">35.17</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">38.08</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">41.64</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">44.18</span> },
|
||
<span class="hljs-number">24</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">9.89</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">10.86</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">12.40</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">13.85</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">15.66</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">23.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">33.20</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">36.42</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">39.36</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">42.98</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">45.56</span> },
|
||
<span class="hljs-number">25</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">10.52</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">11.52</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">13.12</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">14.61</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">16.47</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">24.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">34.28</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">37.65</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">40.65</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">44.31</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">46.93</span> },
|
||
<span class="hljs-number">26</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">11.16</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">12.20</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">13.84</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">15.38</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">17.29</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">25.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">35.56</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">38.89</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">41.92</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">45.64</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">48.29</span> },
|
||
<span class="hljs-number">27</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">11.81</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">12.88</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">14.57</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">16.15</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">18.11</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">26.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">36.74</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">40.11</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">43.19</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">46.96</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">49.65</span> },
|
||
<span class="hljs-number">28</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">12.46</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">13.57</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">15.31</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">16.93</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">18.94</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">27.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">37.92</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">41.34</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">44.46</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">48.28</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">50.99</span> },
|
||
<span class="hljs-number">29</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">13.12</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">14.26</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">16.05</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">17.71</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">19.77</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">28.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">39.09</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">42.56</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">45.72</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">49.59</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">52.34</span> },
|
||
<span class="hljs-number">30</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">13.79</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">14.95</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">16.79</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">18.49</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">20.60</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">29.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">40.26</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">43.77</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">46.98</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">50.89</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">53.67</span> },
|
||
<span class="hljs-number">40</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">20.71</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">22.16</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">24.43</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">26.51</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">29.05</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">39.34</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">51.81</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">55.76</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">59.34</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">63.69</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">66.77</span> },
|
||
<span class="hljs-number">50</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">27.99</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">29.71</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">32.36</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">34.76</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">37.69</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">49.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">63.17</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">67.50</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">71.42</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">76.15</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">79.49</span> },
|
||
<span class="hljs-number">60</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">35.53</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">37.48</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">40.48</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">43.19</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">46.46</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">59.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">74.40</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">79.08</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">83.30</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">88.38</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">91.95</span> },
|
||
<span class="hljs-number">70</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">43.28</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">45.44</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">48.76</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">51.74</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">55.33</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">69.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">85.53</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">90.53</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">95.02</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">100.42</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">104.22</span> },
|
||
<span class="hljs-number">80</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">51.17</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">53.54</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">57.15</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">60.39</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">64.28</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">79.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">96.58</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">101.88</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">106.63</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">112.33</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">116.32</span> },
|
||
<span class="hljs-number">90</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">59.20</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">61.75</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">65.65</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">69.13</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">73.29</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">89.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">107.57</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">113.14</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">118.14</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">124.12</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">128.30</span> },
|
||
<span class="hljs-number">100</span>: { <span class="hljs-number">0.995</span>: <span class="hljs-number">67.33</span>, <span class="hljs-number">0.99</span>: <span class="hljs-number">70.06</span>, <span class="hljs-number">0.975</span>: <span class="hljs-number">74.22</span>, <span class="hljs-number">0.95</span>: <span class="hljs-number">77.93</span>, <span class="hljs-number">0.9</span>: <span class="hljs-number">82.36</span>, <span class="hljs-number">0.5</span>: <span class="hljs-number">99.33</span>, <span class="hljs-number">0.1</span>: <span class="hljs-number">118.50</span>, <span class="hljs-number">0.05</span>: <span class="hljs-number">124.34</span>, <span class="hljs-number">0.025</span>: <span class="hljs-number">129.56</span>, <span class="hljs-number">0.01</span>: <span class="hljs-number">135.81</span>, <span class="hljs-number">0.005</span>: <span class="hljs-number">140.17</span> }
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-197">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-197">¶</a>
|
||
</div>
|
||
<h1 id="-2-chi-squared-goodness-of-fit-test">χ2 (Chi-Squared) Goodness-of-Fit Test</h1>
|
||
<p>The <a href="http://en.wikipedia.org/wiki/Goodness_of_fit#Pearson.27s_chi-squared_test">χ2 (Chi-Squared) Goodness-of-Fit Test</a>
|
||
uses a measure of goodness of fit which is the sum of differences between observed and expected outcome frequencies
|
||
(that is, counts of observations), each squared and divided by the number of observations expected given the
|
||
hypothesized distribution. The resulting χ2 statistic, <code>chi_squared</code>, can be compared to the chi-squared distribution
|
||
to determine the goodness of fit. In order to determine the degrees of freedom of the chi-squared distribution, one
|
||
takes the total number of observed frequencies and subtracts the number of estimated parameters. The test statistic
|
||
follows, approximately, a chi-square distribution with (k − c) degrees of freedom where <code>k</code> is the number of non-empty
|
||
cells and <code>c</code> is the number of estimated parameters for the distribution.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">chi_squared_goodness_of_fit</span><span class="hljs-params">(data, distribution_type, significance)</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-198">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-198">¶</a>
|
||
</div>
|
||
<p>Estimate from the sample data, a weighted mean.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> input_mean = mean(data),</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-199">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-199">¶</a>
|
||
</div>
|
||
<p>Calculated value of the χ2 statistic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> chi_squared = <span class="hljs-number">0</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-200">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-200">¶</a>
|
||
</div>
|
||
<p>Degrees of freedom, calculated as (number of class intervals -
|
||
number of hypothesized distribution parameters estimated - 1)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> degrees_of_freedom,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-201">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-201">¶</a>
|
||
</div>
|
||
<p>Number of hypothesized distribution parameters estimated, expected to be supplied in the distribution test.
|
||
Lose one degree of freedom for estimating <code>lambda</code> from the sample data.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> c = <span class="hljs-number">1</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-202">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-202">¶</a>
|
||
</div>
|
||
<p>The hypothesized distribution.
|
||
Generate the hypothesized distribution.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> hypothesized_distribution = distribution_type(input_mean),
|
||
observed_frequencies = [],
|
||
expected_frequencies = [],
|
||
k;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-203">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-203">¶</a>
|
||
</div>
|
||
<p>Create an array holding a histogram from the sample data, of
|
||
the form <code>{ value: numberOfOcurrences }</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < data.length; i++) {
|
||
<span class="hljs-keyword">if</span> (observed_frequencies[data[i]] === <span class="hljs-literal">undefined</span>) {
|
||
observed_frequencies[data[i]] = <span class="hljs-number">0</span>;
|
||
}
|
||
observed_frequencies[data[i]]++;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-204">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-204">¶</a>
|
||
</div>
|
||
<p>The histogram we created might be sparse - there might be gaps
|
||
between values. So we iterate through the histogram, making
|
||
sure that instead of undefined, gaps have 0 values.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < observed_frequencies.length; i++) {
|
||
<span class="hljs-keyword">if</span> (observed_frequencies[i] === <span class="hljs-literal">undefined</span>) {
|
||
observed_frequencies[i] = <span class="hljs-number">0</span>;
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-205">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-205">¶</a>
|
||
</div>
|
||
<p>Create an array holding a histogram of expected data given the
|
||
sample size and hypothesized distribution.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (k <span class="hljs-keyword">in</span> hypothesized_distribution) {
|
||
<span class="hljs-keyword">if</span> (k <span class="hljs-keyword">in</span> observed_frequencies) {
|
||
expected_frequencies[k] = hypothesized_distribution[k] * data.length;
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-206">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-206">¶</a>
|
||
</div>
|
||
<p>Working backward through the expected frequencies, collapse classes
|
||
if less than three observations are expected for a class.
|
||
This transformation is applied to the observed frequencies as well.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (k = expected_frequencies.length - <span class="hljs-number">1</span>; k >= <span class="hljs-number">0</span>; k--) {
|
||
<span class="hljs-keyword">if</span> (expected_frequencies[k] < <span class="hljs-number">3</span>) {
|
||
expected_frequencies[k - <span class="hljs-number">1</span>] += expected_frequencies[k];
|
||
expected_frequencies.pop();
|
||
|
||
observed_frequencies[k - <span class="hljs-number">1</span>] += observed_frequencies[k];
|
||
observed_frequencies.pop();
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-207">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-207">¶</a>
|
||
</div>
|
||
<p>Iterate through the squared differences between observed & expected
|
||
frequencies, accumulating the <code>chi_squared</code> statistic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (k = <span class="hljs-number">0</span>; k < observed_frequencies.length; k++) {
|
||
chi_squared += <span class="hljs-built_in">Math</span>.pow(
|
||
observed_frequencies[k] - expected_frequencies[k], <span class="hljs-number">2</span>) /
|
||
expected_frequencies[k];
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-208">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-208">¶</a>
|
||
</div>
|
||
<p>Calculate degrees of freedom for this test and look it up in the
|
||
<code>chi_squared_distribution_table</code> in order to
|
||
accept or reject the goodness-of-fit of the hypothesized distribution.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> degrees_of_freedom = observed_frequencies.length - c - <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">return</span> chi_squared_distribution_table[degrees_of_freedom][significance] < chi_squared;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-209">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-209">¶</a>
|
||
</div>
|
||
<h1 id="mixin">Mixin</h1>
|
||
<p>Mixin simple_statistics to a single Array instance if provided
|
||
or the Array native object if not. This is an optional
|
||
feature that lets you treat simple_statistics as a native feature
|
||
of Javascript.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mixin</span><span class="hljs-params">(array)</span> {</span>
|
||
<span class="hljs-keyword">var</span> support = !!(<span class="hljs-built_in">Object</span>.defineProperty && <span class="hljs-built_in">Object</span>.defineProperties);
|
||
<span class="hljs-keyword">if</span> (!support) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'without defineProperty, simple-statistics cannot be mixed in'</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-210">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-210">¶</a>
|
||
</div>
|
||
<p>only methods which work on basic arrays in a single step
|
||
are supported</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> arrayMethods = [<span class="hljs-string">'median'</span>, <span class="hljs-string">'standard_deviation'</span>, <span class="hljs-string">'sum'</span>,
|
||
<span class="hljs-string">'sample_skewness'</span>,
|
||
<span class="hljs-string">'mean'</span>, <span class="hljs-string">'min'</span>, <span class="hljs-string">'max'</span>, <span class="hljs-string">'quantile'</span>, <span class="hljs-string">'geometric_mean'</span>,
|
||
<span class="hljs-string">'harmonic_mean'</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-211">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-211">¶</a>
|
||
</div>
|
||
<p>create a closure with a method name so that a reference
|
||
like <code>arrayMethods[i]</code> doesn’t follow the loop increment</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">wrap</span><span class="hljs-params">(method)</span> {</span>
|
||
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-212">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-212">¶</a>
|
||
</div>
|
||
<p>cast any arguments into an array, since they’re
|
||
natively objects</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> args = <span class="hljs-built_in">Array</span>.prototype.slice.apply(<span class="hljs-built_in">arguments</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-213">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-213">¶</a>
|
||
</div>
|
||
<p>make the first argument the array itself</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> args.unshift(<span class="hljs-keyword">this</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-214">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-214">¶</a>
|
||
</div>
|
||
<p>return the result of the ss method</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> ss[method].apply(ss, args);
|
||
};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-215">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-215">¶</a>
|
||
</div>
|
||
<p>select object to extend</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> extending;
|
||
<span class="hljs-keyword">if</span> (array) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-216">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-216">¶</a>
|
||
</div>
|
||
<p>create a shallow copy of the array so that our internal
|
||
operations do not change it by reference</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> extending = array.slice();
|
||
} <span class="hljs-keyword">else</span> {
|
||
extending = <span class="hljs-built_in">Array</span>.prototype;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-217">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-217">¶</a>
|
||
</div>
|
||
<p>for each array function, define a function that gets
|
||
the array as the first argument.
|
||
We use <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty">defineProperty</a>
|
||
because it allows these properties to be non-enumerable:
|
||
<code>for (var in x)</code> loops will not run into problems with this
|
||
implementation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < arrayMethods.length; i++) {
|
||
<span class="hljs-built_in">Object</span>.defineProperty(extending, arrayMethods[i], {
|
||
value: wrap(arrayMethods[i]),
|
||
configurable: <span class="hljs-literal">true</span>,
|
||
enumerable: <span class="hljs-literal">false</span>,
|
||
writable: <span class="hljs-literal">true</span>
|
||
});
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> extending;
|
||
}
|
||
|
||
ss.linear_regression = linear_regression;
|
||
ss.standard_deviation = standard_deviation;
|
||
ss.r_squared = r_squared;
|
||
ss.median = median;
|
||
ss.mean = mean;
|
||
ss.mode = mode;
|
||
ss.min = min;
|
||
ss.max = max;
|
||
ss.sum = sum;
|
||
ss.quantile = quantile;
|
||
ss.quantile_sorted = quantile_sorted;
|
||
ss.iqr = iqr;
|
||
ss.mad = mad;
|
||
|
||
ss.chunk = chunk;
|
||
ss.shuffle = shuffle;
|
||
ss.shuffle_in_place = shuffle_in_place;
|
||
|
||
ss.sample = sample;
|
||
|
||
ss.sample_covariance = sample_covariance;
|
||
ss.sample_correlation = sample_correlation;
|
||
ss.sample_variance = sample_variance;
|
||
ss.sample_standard_deviation = sample_standard_deviation;
|
||
ss.sample_skewness = sample_skewness;
|
||
|
||
ss.geometric_mean = geometric_mean;
|
||
ss.harmonic_mean = harmonic_mean;
|
||
ss.variance = variance;
|
||
ss.t_test = t_test;
|
||
ss.t_test_two_sample = t_test_two_sample;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-218">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-218">¶</a>
|
||
</div>
|
||
<p>jenks</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> ss.jenksMatrices = jenksMatrices;
|
||
ss.jenksBreaks = jenksBreaks;
|
||
ss.jenks = jenks;
|
||
|
||
ss.bayesian = bayesian;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-219">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-219">¶</a>
|
||
</div>
|
||
<p>Distribution-related methods</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> ss.epsilon = epsilon; <span class="hljs-comment">// We make ε available to the test suite.</span>
|
||
ss.factorial = factorial;
|
||
ss.bernoulli_distribution = bernoulli_distribution;
|
||
ss.binomial_distribution = binomial_distribution;
|
||
ss.poisson_distribution = poisson_distribution;
|
||
ss.chi_squared_goodness_of_fit = chi_squared_goodness_of_fit;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-220">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-220">¶</a>
|
||
</div>
|
||
<p>Normal distribution</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> ss.z_score = z_score;
|
||
ss.cumulative_std_normal_probability = cumulative_std_normal_probability;
|
||
ss.standard_normal_table = standard_normal_table;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-221">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-221">¶</a>
|
||
</div>
|
||
<p>Alias this into its common name</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> ss.average = mean;
|
||
ss.interquartile_range = iqr;
|
||
ss.mixin = mixin;
|
||
ss.median_absolute_deviation = mad;
|
||
|
||
})(<span class="hljs-keyword">this</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|