UNPKG

statistical-js

Version:
1,631 lines (1,417 loc) 52.4 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("statistical", [], factory); else if(typeof exports === 'object') exports["statistical"] = factory(); else root["statistical"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _hook = __webpack_require__(2); var _hook2 = _interopRequireDefault(_hook); var _cacheManager = __webpack_require__(3); var _cacheManager2 = _interopRequireDefault(_cacheManager); var _validator = __webpack_require__(4); var _validator2 = _interopRequireDefault(_validator); var _StatisticalMethod = __webpack_require__(5); var _StatisticalMethod2 = _interopRequireDefault(_StatisticalMethod); var _Perceptron = __webpack_require__(8); var _Perceptron2 = _interopRequireDefault(_Perceptron); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Statistical = function () { /** * Create a new object that provide all method and configuration of the library. */ function Statistical() { _classCallCheck(this, Statistical); this._validator = new _validator2.default(); this._settings = { cache: { enabled: true, rootElementCount: 10, subElementCount: 30 } }; } /** * Return settings used in statistical class. * * @returns {*} */ _createClass(Statistical, [{ key: 'settings', get: function get() { return this._settings; } /** * Allow to updates statistical settings. * * @param {object} options * @param {object} options.cache - options about the cache * @param {boolean} options.cache.enabled - enabled or disabled the cache * @param {number} options.cache.rootElementCount - number of called method cached * @param {number} options.cache.subElementCount - number of result for each called method cached */ , set: function set(options) { this._settings = { cache: { enabled: options.cache.enabled, rootElementCount: options.cache.rootElementCount || this._settings.cache.rootElementCount, subElementCount: options.cache.subElementCount || this._settings.cache.subElementCount } }; _cacheManager2.default.settings = this._settings.cache; } /** * Basics plus advanced statistics are provided in this member. * * @returns {*} */ }, { key: 'methods', get: function get() { return _hook2.default.cache(new _StatisticalMethod2.default(), _cacheManager2.default); } /** * Predictive model are provided in this member. * * @returns {{Perceptron: Perceptron}} */ }, { key: 'ml', get: function get() { return { Perceptron: _Perceptron2.default }; } }]); return Statistical; }(); var statistical = new Statistical(); exports.default = statistical; module.exports = exports['default']; /***/ }, /* 2 */ /***/ function(module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Hook = function () { function Hook() { _classCallCheck(this, Hook); } /** * Create a proxy to wrap a class method and intercept each call. * * @param {object} target * @param {object} cacheManager */ _createClass(Hook, [{ key: 'cache', value: function cache(target, cacheManager) { return new Proxy(target, { get: function get(target, property) { if (property in target && typeof target[property] === 'function') { return function () { var res = void 0; if (cacheManager.settings.enabled) { var cache = cacheManager.find(property, arguments.length <= 0 ? undefined : arguments[0]); if (cache) return cache.result; res = target[property].apply(target, arguments); cacheManager.update(property, { dataSet: arguments.length <= 0 ? undefined : arguments[0], result: res }); } else { res = target[property].apply(target, arguments); } return res; }; } else { return Reflect.get(target, property); } } }); } }]); return Hook; }(); var hook = new Hook(); exports.default = hook; module.exports = exports['default']; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _validator = __webpack_require__(4); var _validator2 = _interopRequireDefault(_validator); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var CacheManager = function () { function CacheManager() { _classCallCheck(this, CacheManager); this._validator = new _validator2.default(); this._cache = {}; this._settings = { enabled: true, rootElementCount: 10, subElementCount: 30 }; } /** * Return CacheManager settings. * * @returns {{maxLength: number}|*} */ _createClass(CacheManager, [{ key: 'update', /** * Update the cache saved with new results. * * @param {string} method * @param {Object} options */ value: function update(method, options) { if (Object.keys(this._cache).length >= this._settings.rootElementCount) delete this._cache[Object.keys(this._cache)[0]]; if (this._cache[method] && this._cache[method].length >= this._settings.subElementCount) this._cache[method].splice(0, 1); this._cache[method] = this._cache[method] || []; this._cache[method].push({ date: new Date().getTime(), dataSet: options.dataSet, result: options.result }); } /** * Find an existing dataSet in the cache and return it. * * @param {String} method * @param {Array} dataSet * @returns {Object} */ }, { key: 'find', value: function find(method, dataSet) { var cache = this._cache[method] || []; var res = null; cache.some(function (v) { if (v.dataSet === dataSet) { res = v; return true; } return false; }); return res; } /** * Reset the cache to be empty. */ }, { key: 'reset', value: function reset() { this._cache = {}; } }, { key: 'settings', get: function get() { return this._settings; } /** * Return the entire cache * * @returns {{}|*} */ , /** * Update existing settings to manage cache. * * @param {*} options */ set: function set(options) { this._settings = { enabled: options.enabled, rootElementCount: options.rootElementCount || this._settings.rootElementCount, subElementCount: options.subElementCount || this._settings.subElementCount }; } }, { key: 'cache', get: function get() { return this._cache; } }]); return CacheManager; }(); var cacheManager = new CacheManager(); exports.default = cacheManager; module.exports = exports['default']; /***/ }, /* 4 */ /***/ function(module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Validator = function () { function Validator() { _classCallCheck(this, Validator); } /** * Valid a value with rules given, if the rules are not respected throw an error. * * @param {string} parameterName * @param {*} value * @param {Array} ruless */ _createClass(Validator, [{ key: 'validate', value: function validate(parameterName, value, rules) { if (typeof value === 'undefined') throw new Error('Missing parameter ' + parameterName); rules.map(function (r) { switch (r) { case 'isArray': if (!Array.isArray(value)) throw new Error('Parameter ' + parameterName + ' must be an array'); break; case 'isNumber': if (typeof value !== 'number') throw new Error('Parameter ' + parameterName + ' must be a number'); break; case 'isString': if (typeof value !== 'string') throw new Error('Parameter ' + parameterName + ' must be a string'); break; case 'isFunction': if (typeof value !== 'function') throw new Error('Parameter ' + parameterName + ' must be a function'); break; case 'length > 0': if (value.length === 0) throw new Error('Parameter ' + parameterName + ' must have more than 0 values'); break; case 'positive': if (value < 0) throw new Error('Parameter ' + parameterName + ' must be positive'); break; case 'strictlyPositive': if (value <= 0) throw new Error('Parameter ' + parameterName + ' must be strictly positive'); break; case 'length =': if (value[0].length !== value[1].length) throw new Error('Parameter ' + parameterName + ' must have the same number of values'); break; default: if (Array.isArray(r)) { var hasOnlyNumbers = !r.map(function (v) { return typeof v === 'number'; }).includes(false); if (hasOnlyNumbers) { if (r.length === 2) { if (value < r[0] || value > r[1]) throw new Error('Parameter ' + parameterName + ' must fall between ' + r[0] + ' and ' + r[1]); } } } else { throw new Error('Rule not implemented : ' + r); } } }); } }]); return Validator; }(); exports.default = Validator; module.exports = exports['default']; /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _validator = __webpack_require__(4); var _validator2 = _interopRequireDefault(_validator); var _epsilon = __webpack_require__(6); var _epsilon2 = _interopRequireDefault(_epsilon); var _chiSquaredTable = __webpack_require__(7); var _chiSquaredTable2 = _interopRequireDefault(_chiSquaredTable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var StatisticalMethod = function () { /** * Create a new object that provide all statistical methods. */ function StatisticalMethod() { _classCallCheck(this, StatisticalMethod); this._validator = new _validator2.default(); this._chiSquaredProbTable = _chiSquaredTable2.default; this._epsilon = _epsilon2.default; } /** * Return table of chi squared prob. * * @returns {*} */ _createClass(StatisticalMethod, [{ key: 'min', /** * Return the smallest value of the sample. * * @param {Array} sample * @returns {number} */ value: function min(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return sample.sort(function (a, b) { return a - b; })[0]; } /** * Return the biggest value of the sample. * * @param {Array} sample * @returns {number} */ }, { key: 'max', value: function max(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return sample.sort(function (a, b) { return a + b; })[0]; } /** * The [Sum](https://en.wikipedia.org/wiki/Sum). * * @param sample * @returns {*} */ }, { key: 'sum', value: function sum(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return sample.reduce(function (accumulator, current) { return accumulator + current; }, 0); } /** * The [Median](https://en.wikipedia.org/wiki/Median). * * @param {Array} sample * @returns {number} */ }, { key: 'median', value: function median(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); var middle = Math.floor(sample.length / 2); var isEven = sample.length % 2 === 0; sample = sample.sort(function (a, b) { return a - b; }); return isEven ? (sample[middle - 1] + sample[middle]) / 2 : sample[middle]; } /** * The [Mode](https://en.wikipedia.org/wiki/Mode). * * @param {Array} sample * @returns {*} */ }, { key: 'mode', value: function mode(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); var counter = {}; var mode = []; var max = 0; sample.map(function (value, index) { if (!(sample[index] in counter)) counter[sample[index]] = 0; counter[sample[index]]++; if (counter[sample[index]] === max) mode.push(sample[index]); if (counter[sample[index]] > max) { max = counter[sample[index]]; mode = [sample[index]]; } }); return mode.length > 1 ? mode : mode[0]; } /** * The [Mean](https://en.wikipedia.org/wiki/Mean). * * @param {Array} sample * @returns {number} */ }, { key: 'mean', value: function mean(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return this.sum(sample) / sample.length; } /** * The [Variance](https://en.wikipedia.org/wiki/Variance). * * @param {Array} sample * @returns {number} */ }, { key: 'variance', value: function variance(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); var avg = this.mean(sample); var n = sample.length; return this.sum(sample.map(function (value) { return Math.pow(value - avg, 2); })) / n; } /** * The [Standard Deviation](https://en.wikipedia.org/wiki/Standard_deviation). * * @param {Array} sample * @returns {number} */ }, { key: 'stdDeviation', value: function stdDeviation(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return Math.sqrt(this.variance(sample)); } /** * The [Quantile](http://en.wikipedia.org/wiki/Quantile). * * @param {Array} sample * @param {number} index * @returns {Array} */ }, { key: 'quantile', value: function quantile(sample, index) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); this._validator.validate('index', index, ['isNumber', [0, 1]]); var sortedSample = sample.sort(function (a, b) { return a - b; }); return sortedSample[Math.ceil(sample.length * index - 1)]; } /** * The [Percentile](https://en.wikipedia.org/wiki/Percentile). * * @param {Array} sample * @param {number} index * @returns {Array} */ }, { key: 'percentile', value: function percentile(sample, index) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); this._validator.validate('index', index, ['isNumber', [0, 100]]); var sortedSample = sample.sort(function (a, b) { return a - b; }); return sortedSample[Math.ceil(index / 100 * sample.length)]; } /** * Return the entire result of descriptives statistics above. * * @param {Array} sample * @returns {{min: number, max: number, sum: *, median: number, mode: *, mean: number, variance: number, stdDeviation: number, quantile: Array}} */ }, { key: 'summary', value: function summary(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return { min: this.min(sample), max: this.max(sample), sum: this.sum(sample), median: this.median(sample), mode: this.mode(sample), mean: this.mean(sample), variance: this.variance(sample), stdDeviation: this.stdDeviation(sample), quantile: { q1: this.quantile(sample, 0.25), q3: this.quantile(sample, 0.75) } }; } /** * The [Factorial](https://en.wikipedia.org/wiki/Factorial). * * @param {number} n * @returns {number} */ }, { key: 'factorial', value: function factorial(n) { this._validator.validate('n', n, ['isNumber', 'positive']); var factorialResult = 1; for (var i = 2; i <= n; i++) { factorialResult *= i; } return factorialResult; } /** * The [Geometric Mean](https://en.wikipedia.org/wiki/Geometric_mean). * * @param {Array} sample * @returns {number} */ }, { key: 'geometricMean', value: function geometricMean(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return Math.pow(sample.reduce(function (accumulator, current) { return accumulator * current; }, 1), 1 / sample.length); } /** * The [Harmonic Mean](https://en.wikipedia.org/wiki/Harmonic_mean). * * @param {Array} sample * @returns {number} */ }, { key: 'harmonicMean', value: function harmonicMean(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return sample.length / sample.reduce(function (accumulator, current) { return accumulator + 1 / current; }, 0); } /** * The [Interquartile range](http://en.wikipedia.org/wiki/Interquartile_range) * * @param sample * @returns {number} */ }, { key: 'interQuartileRange', value: function interQuartileRange(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return this.quantile(sample, 0.75) - this.quantile(sample, 0.25); } /** * The [Variance](https://en.wikipedia.org/wiki/Harmonic_mean). * The [Biais](https://fr.wikipedia.org/wiki/Estimateur_(statistique)#Biais). * * Non biased variance * * @param {Array} sample * @returns {number} */ }, { key: 'sampleVariance', value: function sampleVariance(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); var avg = this.mean(sample); var n = sample.length - 1; return this.sum(sample.map(function (value) { return Math.pow(value - avg, 2); })) / n; } /** * The [Standard Deviation](https://en.wikipedia.org/wiki/Standard_deviation). * The [Biais](https://fr.wikipedia.org/wiki/Estimateur_(statistique)#Biais). * * Non biased std deviation * * @param {Array} sample * @returns {number} */ }, { key: 'sampleStdDeviation', value: function sampleStdDeviation(sample) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); return Math.sqrt(this.sampleVariance(sample)); } /** * The [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets: * * @param {Array} sample1 * @param {Array} sample2 * @returns {number} */ }, { key: 'covariance', value: function covariance(sample1, sample2) { this._validator.validate('sample1', sample1, ['isArray', 'length > 0']); this._validator.validate('sample2', sample2, ['isArray', 'length > 0']); this._validator.validate('sample1 and sample2', [sample1, sample2], ['length =']); var meanX = this.mean(sample1); var meanY = this.mean(sample2); var numerator = sample1.reduce(function (accumulator, current, i) { accumulator += (current - meanX) * (sample2[i] - meanY); return accumulator; }, 0); var besselsCorrection = sample1.length - 1; return numerator / besselsCorrection; } /** * The [Binomial Distribution](http://en.wikipedia.org/wiki/Binomial_distribution). * * @param {number} trials * @param {number} probability * @returns {{}} */ }, { key: 'binomial', value: function binomial(trials, probability) { this._validator.validate('trials', trials, ['isNumber']); this._validator.validate('probability', probability, ['isNumber', [0, 1]]); var x = 0; var cumulativeProbability = 0; var cells = {}; do { cells[x] = this.factorial(trials) / (this.factorial(x) * this.factorial(trials - x)) * (Math.pow(probability, x) * Math.pow(1 - probability, trials - x)); cumulativeProbability += cells[x]; x++; } while (cumulativeProbability < 1 - this._epsilon); return cells; } /** * The [Bernoulli distribution](http://en.wikipedia.org/wiki/Bernoulli_distribution). * * @param {number} p * @returns {Object} */ }, { key: 'bernoulli', value: function bernoulli(p) { this._validator.validate('p', p, ['isNumber', [0, 1]]); return this.binomial(1, p); } /** * The [Poisson Distribution](http://en.wikipedia.org/wiki/Poisson_distribution). * * @param {number} lambda * @returns {{}} */ }, { key: 'poisson', value: function poisson(lambda) { this._validator.validate('lambda', lambda, ['strictlyPositive']); var x = 0; var cumulativeProbability = 0; var cells = {}; do { cells[x] = Math.pow(Math.E, -lambda) * Math.pow(lambda, x) / this.factorial(x); cumulativeProbability += cells[x]; x++; } while (cumulativeProbability < 1 - this._epsilon); return cells; } /** * The [χ2 (Chi-Squared) Goodness-of-Fit Test](http://en.wikipedia.org/wiki/Goodness_of_fit#Pearson.27s_chi-squared_test). * return if data follow a specified distribution * * @param {Array} sample * @param {Function} distributionType * @param {number} significance * @returns {boolean} * * @exemple * chiSquaredGoodnessOfFit(sample, 'poisson', 0.05)); //= false */ }, { key: 'chiSquaredGoodnessOfFit', value: function chiSquaredGoodnessOfFit(sample, distributionType, significance) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); this._validator.validate('distributionType', distributionType, ['isFunction']); this._validator.validate('significance', significance, ['isNumber', 'positive']); /* Generate an array with number of ocurences for each data in sample. */ var observedFrequencies = []; observedFrequencies = sample.reduce(function (accumulator, val) { if (accumulator[val] === undefined) accumulator[val] = 0; accumulator[val] += 1; return accumulator; }, []).filter(function (v) { return v !== undefined; }); /* number of hypothesized distribution parameters estimated, expected to be supplied in the distribution test. */ /* Lose one degree of freedom for estimating `lambda` from the sample data. */ var sampleMean = this.mean(sample); /* The hypothesized distribution. Generate the hypothesized distribution. */ var hypothesizedDistribution = distributionType(sampleMean); /* Create an array holding a histogram of expected data given the */ /* sample size and hypothesized distribution. */ var expectedFrequencies = []; expectedFrequencies = Object.entries(hypothesizedDistribution).reduce(function (accumulator, current, i) { if (observedFrequencies[i]) accumulator[i] = current[1] * sample.length; return accumulator; }, []); /* Concat frequencies < 3 with the previous one */ expectedFrequencies = Object.entries(expectedFrequencies).reduceRight(function (previous, current) { if (previous[1] < 3) current[1] += previous[1]; return current; }); /* Compute chiSquared value */ var chiSquared = 0; chiSquared = Object.entries(observedFrequencies).reduce(function (accumulator, current, i) { accumulator += Math.pow(current[1] - expectedFrequencies[i], 2) / expectedFrequencies[i]; return accumulator; }, chiSquared); var c = 1; var degreesOfFreedom = Object.keys(observedFrequencies).length - c - 1; return this._chiSquaredProbTable[degreesOfFreedom][significance] < chiSquared; } /** * The [a one-sample t-test](https://en.wikipedia.org/wiki/Student%27s_t-test#One-sample_t-test). * * @param {Array} sample * @param {number} mu * @returns {number} */ }, { key: 'tTestOneSample', value: function tTestOneSample(sample, mu) { this._validator.validate('sample', sample, ['isArray', 'length > 0']); this._validator.validate('mu', mu, ['isNumber']); var mean = this.mean(sample); var sd = this.stdDeviation(sample); var sqrtSampleSize = Math.sqrt(sample.length); /* t-value */ return (mean - mu) / (sd / sqrtSampleSize); } /** * The [two sample t-test](http://en.wikipedia.org/wiki/Student's_t-test). * * @param {Array} sample1 * @param {Array} sample2 * @returns {number} */ }, { key: 'tTestTwoSample', value: function tTestTwoSample(sample1, sample2) { this._validator.validate('sample1', sample1, ['isArray', 'length > 0']); this._validator.validate('sample2', sample2, ['isArray', 'length > 0']); var n = sample1.length; var m = sample2.length; var meanX = this.mean(sample1); var meanY = this.mean(sample2); var sampleVarianceX = this.sampleVariance(sample1); var sampleVarianceY = this.sampleVariance(sample2); var weightedVariance = ((n - 1) * sampleVarianceX + (m - 1) * sampleVarianceY) / (n + m - 2); /* t-value */ return (meanX - meanY) / Math.sqrt(weightedVariance * (1 / (n + 1) / m)); } /** * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression) * * @param {Array<Array<number>>} data * @returns {*} */ }, { key: 'linearRegression', value: function linearRegression(data) { this._validator.validate('data', data, ['isArray']); var dataLength = data.length; /* 1 element, the result will be a slope to 0 and an intersect ot the second coordinate elements */ if (dataLength === 1) return { slope: slope, intersect: data[0][1] }; /* Compute all sum, and finally the slope and intersect */ var sumX = 0, sumY = 0, sumXX = 0, sumXY = 0; data.forEach(function (element) { sumX += element[0]; sumY += element[1]; sumXX += Math.pow(element[0], 2); sumXY += element[0] * element[1]; }); var slope = (dataLength * sumXY - sumX * sumY) / (dataLength * sumXX - sumX * sumX); var intersect = sumY / dataLength - slope * sumX / dataLength; // Return both values as an object. return { slope: slope, intersect: intersect }; } }, { key: 'chiSquaredProbTable', get: function get() { return this._chiSquaredProbTable; } }]); return StatisticalMethod; }(); exports.default = StatisticalMethod; module.exports = exports['default']; /***/ }, /* 6 */ /***/ function(module, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * We use `ε`, epsilon, as a stopping criterion when we want to iterate * until we're "close enough". Epsilon is a very small number: for * simple statistics, that number is **0.0001** * * This is used in calculations like the binomialDistribution, in which * the process of finding a value is [iterative](https://en.wikipedia.org/wiki/Iterative_method): * it progresses until it is close enough. * * @type {number} */ var epsilon = 0.0001; exports.default = epsilon; module.exports = exports['default']; /***/ }, /* 7 */ /***/ function(module, exports) { 'use strict'; /** * The [χ2 (Chi-Squared) Distribution](http://en.wikipedia.org/wiki/Chi-squared_distribution) * * @type {*} */ Object.defineProperty(exports, "__esModule", { value: true }); var chiSquaredTable = { '1': { '0.995': 0, '0.99': 0, '0.975': 0, '0.95': 0, '0.9': 0.02, '0.5': 0.45, '0.1': 2.71, '0.05': 3.84, '0.025': 5.02, '0.01': 6.63, '0.005': 7.88 }, '2': { '0.995': 0.01, '0.99': 0.02, '0.975': 0.05, '0.95': 0.1, '0.9': 0.21, '0.5': 1.39, '0.1': 4.61, '0.05': 5.99, '0.025': 7.38, '0.01': 9.21, '0.005': 10.6 }, '3': { '0.995': 0.07, '0.99': 0.11, '0.975': 0.22, '0.95': 0.35, '0.9': 0.58, '0.5': 2.37, '0.1': 6.25, '0.05': 7.81, '0.025': 9.35, '0.01': 11.34, '0.005': 12.84 }, '4': { '0.995': 0.21, '0.99': 0.3, '0.975': 0.48, '0.95': 0.71, '0.9': 1.06, '0.5': 3.36, '0.1': 7.78, '0.05': 9.49, '0.025': 11.14, '0.01': 13.28, '0.005': 14.86 }, '5': { '0.995': 0.41, '0.99': 0.55, '0.975': 0.83, '0.95': 1.15, '0.9': 1.61, '0.5': 4.35, '0.1': 9.24, '0.05': 11.07, '0.025': 12.83, '0.01': 15.09, '0.005': 16.75 }, '6': { '0.995': 0.68, '0.99': 0.87, '0.975': 1.24, '0.95': 1.64, '0.9': 2.2, '0.5': 5.35, '0.1': 10.65, '0.05': 12.59, '0.025': 14.45, '0.01': 16.81, '0.005': 18.55 }, '7': { '0.995': 0.99, '0.99': 1.25, '0.975': 1.69, '0.95': 2.17, '0.9': 2.83, '0.5': 6.35, '0.1': 12.02, '0.05': 14.07, '0.025': 16.01, '0.01': 18.48, '0.005': 20.28 }, '8': { '0.995': 1.34, '0.99': 1.65, '0.975': 2.18, '0.95': 2.73, '0.9': 3.49, '0.5': 7.34, '0.1': 13.36, '0.05': 15.51, '0.025': 17.53, '0.01': 20.09, '0.005': 21.96 }, '9': { '0.995': 1.73, '0.99': 2.09, '0.975': 2.7, '0.95': 3.33, '0.9': 4.17, '0.5': 8.34, '0.1': 14.68, '0.05': 16.92, '0.025': 19.02, '0.01': 21.67, '0.005': 23.59 }, '10': { '0.995': 2.16, '0.99': 2.56, '0.975': 3.25, '0.95': 3.94, '0.9': 4.87, '0.5': 9.34, '0.1': 15.99, '0.05': 18.31, '0.025': 20.48, '0.01': 23.21, '0.005': 25.19 }, '11': { '0.995': 2.6, '0.99': 3.05, '0.975': 3.82, '0.95': 4.57, '0.9': 5.58, '0.5': 10.34, '0.1': 17.28, '0.05': 19.68, '0.025': 21.92, '0.01': 24.72, '0.005': 26.76 }, '12': { '0.995': 3.07, '0.99': 3.57, '0.975': 4.4, '0.95': 5.23, '0.9': 6.3, '0.5': 11.34, '0.1': 18.55, '0.05': 21.03, '0.025': 23.34, '0.01': 26.22, '0.005': 28.3 }, '13': { '0.995': 3.57, '0.99': 4.11, '0.975': 5.01, '0.95': 5.89, '0.9': 7.04, '0.5': 12.34, '0.1': 19.81, '0.05': 22.36, '0.025': 24.74, '0.01': 27.69, '0.005': 29.82 }, '14': { '0.995': 4.07, '0.99': 4.66, '0.975': 5.63, '0.95': 6.57, '0.9': 7.79, '0.5': 13.34, '0.1': 21.06, '0.05': 23.68, '0.025': 26.12, '0.01': 29.14, '0.005': 31.32 }, '15': { '0.995': 4.6, '0.99': 5.23, '0.975': 6.27, '0.95': 7.26, '0.9': 8.55, '0.5': 14.34, '0.1': 22.31, '0.05': 25, '0.025': 27.49, '0.01': 30.58, '0.005': 32.8 }, '16': { '0.995': 5.14, '0.99': 5.81, '0.975': 6.91, '0.95': 7.96, '0.9': 9.31, '0.5': 15.34, '0.1': 23.54, '0.05': 26.3, '0.025': 28.85, '0.01': 32, '0.005': 34.27 }, '17': { '0.995': 5.7, '0.99': 6.41, '0.975': 7.56, '0.95': 8.67, '0.9': 10.09, '0.5': 16.34, '0.1': 24.77, '0.05': 27.59, '0.025': 30.19, '0.01': 33.41, '0.005': 35.72 }, '18': { '0.995': 6.26, '0.99': 7.01, '0.975': 8.23, '0.95': 9.39, '0.9': 10.87, '0.5': 17.34, '0.1': 25.99, '0.05': 28.87, '0.025': 31.53, '0.01': 34.81, '0.005': 37.16 }, '19': { '0.995': 6.84, '0.99': 7.63, '0.975': 8.91, '0.95': 10.12, '0.9': 11.65, '0.5': 18.34, '0.1': 27.2, '0.05': 30.14, '0.025': 32.85, '0.01': 36.19, '0.005': 38.58 }, '20': { '0.995': 7.43, '0.99': 8.26, '0.975': 9.59, '0.95': 10.85, '0.9': 12.44, '0.5': 19.34, '0.1': 28.41, '0.05': 31.41, '0.025': 34.17, '0.01': 37.57, '0.005': 40 }, '21': { '0.995': 8.03, '0.99': 8.9, '0.975': 10.28, '0.95': 11.59, '0.9': 13.24, '0.5': 20.34, '0.1': 29.62, '0.05': 32.67, '0.025': 35.48, '0.01': 38.93, '0.005': 41.4 }, '22': { '0.995': 8.64, '0.99': 9.54, '0.975': 10.98, '0.95': 12.34, '0.9': 14.04, '0.5': 21.34, '0.1': 30.81, '0.05': 33.92, '0.025': 36.78, '0.01': 40.29, '0.005': 42.8 }, '23': { '0.995': 9.26, '0.99': 10.2, '0.975': 11.69, '0.95': 13.09, '0.9': 14.85, '0.5': 22.34, '0.1': 32.01, '0.05': 35.17, '0.025': 38.08, '0.01': 41.64, '0.005': 44.18 }, '24': { '0.995': 9.89, '0.99': 10.86, '0.975': 12.4, '0.95': 13.85, '0.9': 15.66, '0.5': 23.34, '0.1': 33.2, '0.05': 36.42, '0.025': 39.36, '0.01': 42.98, '0.005': 45.56 }, '25': { '0.995': 10.52, '0.99': 11.52, '0.975': 13.12, '0.95': 14.61, '0.9': 16.47, '0.5': 24.34, '0.1': 34.28, '0.05': 37.65, '0.025': 40.65, '0.01': 44.31, '0.005': 46.93 }, '26': { '0.995': 11.16, '0.99': 12.2, '0.975': 13.84, '0.95': 15.38, '0.9': 17.29, '0.5': 25.34, '0.1': 35.56, '0.05': 38.89, '0.025': 41.92, '0.01': 45.64, '0.005': 48.29 }, '27': { '0.995': 11.81, '0.99': 12.88, '0.975': 14.57, '0.95': 16.15, '0.9': 18.11, '0.5': 26.34, '0.1': 36.74, '0.05': 40.11, '0.025': 43.19, '0.01': 46.96, '0.005': 49.65 }, '28': { '0.995': 12.46, '0.99': 13.57, '0.975': 15.31, '0.95': 16.93, '0.9': 18.94, '0.5': 27.34, '0.1': 37.92, '0.05': 41.34, '0.025': 44.46, '0.01': 48.28, '0.005': 50.99 }, '29': { '0.995': 13.12, '0.99': 14.26, '0.975': 16.05, '0.95': 17.71, '0.9': 19.77, '0.5': 28.34, '0.1': 39.09, '0.05': 42.56, '0.025': 45.72, '0.01': 49.59, '0.005': 52.34 }, '30': { '0.995': 13.79, '0.99': 14.95, '0.975': 16.79, '0.95': 18.49, '0.9': 20.6, '0.5': 29.34, '0.1': 40.26, '0.05': 43.77, '0.025': 46.98, '0.01': 50.89, '0.005': 53.67 }, '40': { '0.995': 20.71, '0.99': 22.16, '0.975': 24.43, '0.95': 26.51, '0.9': 29.05, '0.5': 39.34, '0.1': 51.81, '0.05': 55.76, '0.025': 59.34, '0.01': 63.69, '0.005': 66.77 }, '50': { '0.995': 27.99, '0.99': 29.71, '0.975': 32.36, '0.95': 34.76, '0.9': 37.69, '0.5': 49.33, '0.1': 63.17, '0.05': 67.5, '0.025': 71.42, '0.01': 76.15, '0.005': 79.49 }, '60': { '0.995': 35.53, '0.99': 37.48, '0.975': 40.48, '0.95': 43.19, '0.9': 46.46, '0.5': 59.33, '0.1': 74.4, '0.05': 79.08, '0.025': 83.3, '0.01': 88.38, '0.005': 91.95 }, '70': { '0.995': 43.28, '0.99': 45.44, '0.975': 48.76, '0.95': 51.74, '0.9': 55.33, '0.5': 69.33, '0.1': 85.53, '0.05': 90.53, '0.025': 95.02, '0.01': 100.42, '0.005': 104.22 }, '80': { '0.995': 51.17, '0.99': 53.54, '0.975': 57.15, '0.95': 60.39, '0.9': 64.28, '0.5': 79.33, '0.1': 96.58, '0.05': 101.88, '0.025': 106.63, '0.01': 112.33, '0.005': 116.32 }, '90': { '0.995': 59.2, '0.99': 61.75, '0.975': 65.65, '0.95': 69.13, '0.9': 73.29, '0.5': 89.33, '0.1': 107.57, '0.05': 113.14, '0.025': 118.14, '0.01': 124.12, '0.005': 128.3 }, '100': { '0.995': 67.33, '0.99': 70.06, '0.975': 74.22, '0.95': 77.93, '0.9': 82.36, '0.5': 99.33, '0.1': 118.5, '0.05': 124.34, '0.025': 129.56, '0.01': 135.81, '0.005': 140.17 } }; exports.default = chiSquaredTable; module.exports = exports['default']; /***/ }, /* 8 */ /***/ function(module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance ins