/** * The numeric core the analytic intelligence tools compute with. * * WHY THIS EXISTS: six advertised tools -- intelligent-assistant, * natural-language-query, pattern-recognition, predictive-analytics, * recommendation-engine and smart-summarization -- published 48 operations * between them and implemented none. Every call returned * `{ success: true, confidence: 0.85, result: ' completed * successfully' }`, a fabricated measurement: a caller asking * predictive-analytics to detect anomalies was told it had succeeded, with a * confidence that was a literal in the source. * * Everything those tools now report is computed here, from the caller's own * data, by a named method whose formula is written down and whose result is * checked against a hand-computed value in * tests/unit/analytics-core.test.ts. Three sibling tools in this directory * (anomaly-explainer, sentiment-analysis, knowledge-graph) each carry their * own copy of this arithmetic as private class methods; those are left alone * here, but nothing new duplicates them. * * WHAT IT WILL NOT DO: no function here invents a value for missing input. * A sample too short for a method is an error naming the method's minimum, * because the alternative -- a default, a zero, a 0.85 -- is how the thing * this file replaces came to exist. */ /** Sample sizes below which a method has no defined answer. */ export declare const MINIMUM_SAMPLES: Readonly<{ /** A mean needs one point. */ readonly mean: 1; /** A sample variance divides by n-1. */ readonly variance: 2; /** A correlation needs two paired points, and a slope needs two. */ readonly paired: 2; /** A residual standard error divides by n-2. */ readonly regressionInterval: 3; /** Mann-Kendall's normal approximation is stated for n >= 4. */ readonly mannKendall: 4; }>; /** Methods for flagging a point as an outlier. */ export declare enum OutlierMethod { /** Distance from the mean in sample standard deviations. */ ZScore = "z-score", /** Distance outside the quartiles, in interquartile ranges. */ Iqr = "iqr" } /** The direction a monotonic trend test reports. */ export declare enum TrendDirection { Increasing = "increasing", Decreasing = "decreasing", /** The test did not reject "no trend" at the stated significance. */ None = "none" } /** * The normal quantile for a two-sided 95% interval. Written as a named * constant because every interval in this file is a normal approximation and * says so, rather than implying an exact t-distribution it does not use. */ export declare const NORMAL_QUANTILE_95 = 1.959963984540054; /** Significance threshold paired with the quantile above. */ export declare const SIGNIFICANCE_95 = 0.05; /** Arithmetic mean. */ export declare const mean: (values: readonly number[]) => number; /** Sample variance, dividing by n-1 (Bessel's correction). */ export declare const variance: (values: readonly number[]) => number; /** Sample standard deviation. */ export declare const stdDev: (values: readonly number[]) => number; /** * The p-th percentile by linear interpolation between order statistics -- * the same rule numpy applies by default, so a figure reported here can be * checked against it. */ export declare const percentile: (values: readonly number[], p: number) => number; /** Median, which is the 50th percentile by the rule above. */ export declare const median: (values: readonly number[]) => number; /** Each value's distance from the mean, in sample standard deviations. */ export declare const zScores: (values: readonly number[]) => number[]; /** A point the chosen rule places outside the sample's normal range. */ export interface Outlier { index: number; value: number; /** Z-score, or IQR distance outside the nearer quartile. */ score: number; } /** * Outliers by z-score or by the interquartile rule. The threshold is the * caller's, because what counts as extreme is a property of their data and * not of this function; the two conventional defaults are 3 and 1.5. */ export declare const outliers: (values: readonly number[], method: OutlierMethod, threshold: number) => Outlier[]; /** * Pearson's product-moment correlation. Returns 0 when either series is * constant, because the coefficient is undefined there -- a constant series * has no variation to co-vary. */ export declare const pearson: (x: readonly number[], y: readonly number[]) => number; /** An ordinary-least-squares straight line through paired points. */ export interface LinearFit { slope: number; intercept: number; /** Coefficient of determination, 1 - SSres/SStot. */ r2: number; /** Residual standard error, sqrt(SSres/(n-2)); null when n < 3. */ residualStdError: number | null; sampleSize: number; } /** Fit y = slope*x + intercept by ordinary least squares. */ export declare const linearFit: (x: readonly number[], y: readonly number[]) => LinearFit; /** One forecast point with the interval the fit supports. */ export interface ForecastPoint { /** Index on the same axis the series was fitted over. */ at: number; value: number; /** Lower/upper 95% prediction bound, or null when n < 3. */ lower: number | null; upper: number | null; } /** * Extrapolate a series by least squares over its own index, with a 95% * prediction interval widened for distance from the mean -- the standard * se * sqrt(1 + 1/n + (x-xbar)^2/Sxx), using a normal quantile rather than a * t quantile, which this returns under the name `interval: 'normal-95'` at * the call sites so nobody reads it as exact. */ export declare const forecastLinear: (series: readonly number[], horizon: number) => { fit: LinearFit; points: ForecastPoint[]; }; /** * Exponentially weighted moving average, seeded with the first observation. * s[0] = x[0]; s[t] = alpha*x[t] + (1-alpha)*s[t-1]. */ export declare const ewma: (series: readonly number[], alpha: number) => number[]; /** * Holt's linear (double exponential) smoothing, for a series with a level * and a trend but no seasonal term. Seeded as level = x[0] and * trend = x[1] - x[0], which is Holt's own initialisation. */ export declare const holtLinear: (series: readonly number[], alpha: number, beta: number, horizon: number) => { level: number; trend: number; fitted: number[]; forecast: number[]; }; /** The outcome of a Mann-Kendall monotonic trend test. */ export interface TrendTest { /** Kendall's S statistic: concordant minus discordant pairs. */ s: number; /** Kendall's tau-a, S divided by the number of pairs. */ tau: number; /** Normal-approximation test statistic, tie-corrected. */ z: number; /** Two-sided p-value from that normal approximation. */ p: number; direction: TrendDirection; } /** * Mann-Kendall test for a monotonic trend -- a rank test, so it does not * assume the series is normal or linear, which is why it is used here for * "is this trending" and linearFit is used for "by how much". The variance * carries the standard correction for tied groups. */ export declare const mannKendall: (series: readonly number[]) => TrendTest; /** * Autocorrelation at one lag, normalised by the series' own variance about * its mean -- the usual estimator, so r(0) = 1. */ export declare const autocorrelation: (series: readonly number[], lag: number) => number; /** * The lag in [2, maxLag] with the highest autocorrelation, and that value. * A caller decides whether the strength is worth calling a season; this only * reports which lag is strongest and how strong it is. */ export declare const strongestSeasonalLag: (series: readonly number[], maxLag: number) => { lag: number; correlation: number; } | null; /** Cosine of the angle between two equal-length vectors. */ export declare const cosineSimilarity: (a: readonly number[], b: readonly number[]) => number; /** One cluster of a k-means partition. */ export interface Cluster { centroid: number[]; /** Indices into the input, ascending. */ members: number[]; /** Mean squared distance from the centroid to its own members. */ inertia: number; } export interface KMeansResult { clusters: Cluster[]; iterations: number; /** Whether assignments stopped changing before the iteration ceiling. */ converged: boolean; /** Total within-cluster sum of squares. */ inertia: number; } /** * k-means by Lloyd's algorithm with k-means++ seeding, made reproducible by * a seeded generator. Empty clusters are dropped rather than re-seeded, so * the result reports the clusters that actually have members instead of * padding the count the caller asked for. */ export declare const kMeans: (points: ReadonlyArray, k: number, seed: number, maxIterations?: number) => KMeansResult; /** A repeated subsequence found in an ordered event stream. */ export interface Sequence { /** The repeated run, in order. */ pattern: string[]; /** How many times it occurs, counting overlapping occurrences. */ occurrences: number; /** Occurrences divided by the number of windows of that length. */ support: number; } /** * Frequent contiguous subsequences of length `length`, by exact count over a * sliding window. `minOccurrences` is the caller's, and a run occurring once * is never reported as a pattern. */ export declare const mineSequences: (events: readonly string[], length: number, minOccurrences: number) => Sequence[]; /** Counts of each distinct value, descending by count then by value. */ export declare const frequencies: (values: readonly string[]) => Array<{ value: string; count: number; share: number; }>; /** A proportion with its Wilson score interval. */ export interface Proportion { /** Successes over trials. */ rate: number; successes: number; trials: number; /** Wilson score 95% bounds, clamped to [0, 1]. */ lower: number; upper: number; } /** * A proportion and its Wilson score 95% interval. * * WHY WILSON: the textbook normal interval p +- z*sqrt(p(1-p)/n) is wrong * exactly where a failure rate matters most -- at 0 successes it returns the * zero-width interval [0, 0], asserting the event cannot happen. Wilson gives * 0 out of 10 an upper bound near 0.28, which is the honest statement: ten * clean trials do not rule out a one-in-four failure rate. */ export declare const wilsonInterval: (successes: number, trials: number) => Proportion; /** How far predictions sat from what happened. */ export interface RegressionMetrics { sampleSize: number; /** Mean absolute error. */ mae: number; /** Root mean squared error. */ rmse: number; /** Mean error, signed: positive means the predictions ran high. */ bias: number; /** * Mean absolute percentage error, or null when any actual is zero -- the * quantity is undefined there, and substituting a number for it is how a * meaningless figure ends up being quoted. */ mape: number | null; /** 1 - SSres/SStot against the actuals' own mean. */ r2: number; } /** * Error metrics for a set of predictions against what actually happened. * Nothing is fitted here: both series are the caller's, so these measure the * predictions rather than describing a fit to them. */ export declare const regressionMetrics: (actual: readonly number[], predicted: readonly number[]) => RegressionMetrics; //# sourceMappingURL=analytics-core.d.ts.map