@elastic/statistics

中文文档
0.0.4发布于 2026/11/05Elastic-2.0TypeScriptCommonJS近 30 天下载 12.9万

Pure statistical functions for LLM evaluations

原始使用文档
文档目录12 节
  1. Install
  2. Usage
  3. Paired t-test
  4. Wilcoxon signed-rank test
  5. Mann-Whitney U test
  6. McNemar tests
  7. Fisher's exact test
  8. Chi-squared test of independence
  9. Shapiro-Wilk normality test
  10. Scripts
  11. Semver policy
  12. License

@elastic/statistics

Pure statistical functions for TypeScript and JavaScript.

Install

npm install @elastic/statistics

Usage

Paired t-test

Mirrors scipy.stats.ttest_rel. When every difference is the same, the statistic is infinite (NaN if the difference is zero) and the p-value is 1, where scipy returns 0 (NaN).

import { pairedT } from '@elastic/statistics';

const { statistic, pValue } = pairedT([0.9, 0.85, 0.7, 0.95, 0.8], [0.8, 0.75, 0.72, 0.88, 0.7]);
// statistic and pValue are null when fewer than two pairs are given

Wilcoxon signed-rank test

Mirrors scipy.stats.wilcoxon; p-values match scipy to floating-point precision.

import { wilcoxonSignedRank } from '@elastic/statistics';

const target = [0.9, 0.85, 0.7, 0.95, 0.8, 0.6, 0.75];
const baseline = [0.8, 0.75, 0.72, 0.88, 0.7, 0.6, 0.7];

const { statistic, pValue, zStatistic } = wilcoxonSignedRank(target, baseline);
// { statistic: 1, pValue: 0.0625, zStatistic: null }

// Is target stochastically greater than baseline? Use the normal approximation with continuity correction.
wilcoxonSignedRank(target, baseline, {
  alternative: 'greater',
  method: 'asymptotic',
  correction: true,
});
OptionValuesDefaultNotes
alternative'two-sided', 'less', 'greater''two-sided'Hypothesis about the differences target - baseline.
zeroMethod'wilcox', 'pratt', 'zsplit''wilcox'Discard zero differences, rank them but drop their ranks, or split their ranks between both sums.
method'auto', 'exact', 'asymptotic''auto''auto' uses the exact distribution up to 50 pairs without ties or zeros, an exhaustive permutation test for up to 13 pairs otherwise, and the normal approximation above that.
correctionbooleanfalseContinuity correction for the normal approximation.

statistic is the smaller of the positive and negative rank sums for 'two-sided', and the positive rank sum otherwise. zStatistic is set whenever the normal approximation is used. All three are null when the test cannot be computed (no pairs, NaN in a sample, or no variance left for the normal approximation, e.g. every difference is zero); the function never throws for such inputs.

Differences are computed in floating point, so pairs that should tie can receive distinct ranks because of roundoff (0.825 - 0.775 !== 0.5 - 0.45). Round scores first when exact ties matter.

Mann-Whitney U test

Non-parametric test for two independent samples. Mirrors scipy.stats.mannwhitneyu; p-values match scipy to floating-point precision.

import { mannWhitney } from '@elastic/statistics';

const target = [0.9, 0.85, 0.7, 0.95, 0.8];
const baseline = [0.8, 0.75, 0.72, 0.6];

const { statistic, pValue, zStatistic } = mannWhitney(target, baseline);
// { statistic: 16.5, pValue: 0.1399825237583975, zStatistic: 1.475856111043418 }

mannWhitney(target, baseline, { alternative: 'greater', method: 'asymptotic' });
// { statistic: 16.5, pValue: 0.06999126187919875, zStatistic: 1.475856111043418 }
OptionValuesDefaultNotes
alternative'two-sided', 'less', 'greater''two-sided'Whether the distribution underlying target differs from, is stochastically less than, or greater than baseline's.
method'auto', 'exact', 'asymptotic''auto''auto' uses the exact distribution when a sample has at most 8 values and there are no ties, the normal approximation otherwise.
continuitybooleantrueContinuity correction for the normal approximation.

statistic is the U statistic of target; baseline's is target.length * baseline.length - statistic. zStatistic is set whenever the normal approximation is used. All three are null when the test cannot be computed (an empty sample, NaN in a sample, or every value tied under the normal approximation).

McNemar tests

Paired binary outcomes (true/false or 1/0) scored on the same examples. Only the discordant pairs count: b (first sample succeeded, second failed) and c (the reverse). The input is either the two paired arrays or a 2x2 table [[a, b], [c, d]] in the statsmodels layout (rows: first sample success / failure, columns: second sample success / failure).

import {
  mcnemar,
  mcnemarExact,
  mcnemarMidP,
  mcnemarStratified,
  pairedTable,
} from '@elastic/statistics';

const target = [1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1];
const baseline = [1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0];

mcnemar(target, baseline);
// { statistic: 0, pValue: 0.0625, method: 'mid-p' }
pairedTable(target, baseline);
// [[5, 4], [0, 3]]
mcnemarExact([
  [5, 4],
  [0, 3],
]);
// { statistic: 0, pValue: 0.125, method: 'exact' }
mcnemar(
  [
    [5, 4],
    [0, 3],
  ],
  { method: 'asymptotic' },
);
// { statistic: 2.25, pValue: 0.13361440253771584, method: 'asymptotic' }

// Categorical labels: one-vs-rest McNemar per class, in order of first appearance.
mcnemarStratified(
  ['cat', 'dog', 'dog', 'bird', 'cat', 'cat'],
  ['cat', 'cat', 'dog', 'bird', 'dog', 'bird'],
);
// [
//   { label: 'cat', statistic: 1, pValue: 0.625, method: 'mid-p' },
//   { label: 'dog', statistic: 1, pValue: 1, method: 'mid-p' },
//   { label: 'bird', statistic: 0, pValue: 0.5, method: 'mid-p' },
// ]
OptionValuesDefaultNotes
method'mid-p', 'exact', 'asymptotic''mid-p'Mid-p variant of the exact conditional test (Fagerland, Lydersen & Laake, 2013), the exact conditional test, or the chi-squared approximation.
correctionbooleantrueContinuity correction of 1 for the asymptotic statistic.

'exact' and 'asymptotic' mirror statsmodels.stats.contingency_tables.mcnemar. statistic is min(b, c) for 'mid-p' and 'exact', and the chi-squared statistic for 'asymptotic'; method reports the variant used. With no discordant pairs every variant returns statistic 0 and p-value 1 (statsmodels' asymptotic variant is undefined there). mcnemarExact and mcnemarMidP force one variant. mcnemarStratified takes paired categorical labels and runs the same test per class in a one-vs-rest setting; its p-values are not adjusted for multiple comparisons.

Fisher's exact test

Exact test of independence for a 2x2 table, given as rows (e.g. group) by columns (e.g. success / failure). Mirrors scipy.stats.fisher_exact, including its two-sided p-value (the total probability of tables at most as likely as the observed one).

import { fisherExact } from '@elastic/statistics';

fisherExact([
  [8, 2],
  [1, 5],
]);
// { statistic: 20, pValue: 0.03496503496503496 }
fisherExact(
  [
    [8, 2],
    [1, 5],
  ],
  { alternative: 'greater' },
);
// { statistic: 20, pValue: 0.024475524475524472 }

statistic is the sample odds ratio (a * d) / (b * c) of the table [[a, b], [c, d]]: Infinity when b or c is zero, null when a row or column is empty (the p-value is then 1). The function throws for tables that are not 2x2 or hold negative or non-integer counts.

Chi-squared test of independence

Pearson's chi-squared test for an R x C table given as rows. Mirrors scipy.stats.chi2_contingency; p-values match scipy to floating-point precision.

import { chiSquared } from '@elastic/statistics';

chiSquared([
  [10, 10, 20],
  [20, 20, 20],
]);
// { statistic: 2.7777777777777777, pValue: 0.2493522087772962, dof: 2,
//   expected: [[12, 12, 16], [18, 18, 24]], minimumExpected: 12 }

// Yates' continuity correction is applied to 2x2 tables unless disabled.
chiSquared([
  [12, 3],
  [17, 16],
]).pValue; // 0.12063113097759684
chiSquared(
  [
    [12, 3],
    [17, 16],
  ],
  { correction: false },
).pValue; // 0.061412253987091166

statistic and pValue are null when a row or column of expected counts is zero (scipy raises in that case); dof, expected and minimumExpected are always reported. The approximation is usually considered adequate when minimumExpected is at least 5; use fisherExact for 2x2 tables below that. The function throws for empty or ragged tables and negative counts.

Shapiro-Wilk normality test

Tests whether a sample, typically the paired differences, is normally distributed. Mirrors scipy.stats.shapiro.

import { shapiroWilk } from '@elastic/statistics';

shapiroWilk([0.12, -0.05, 0.08, 0.02, -0.11, 0.07, 0.01, 0.15, -0.03, 0.04]);
// { statistic: 0.9875422022224214, pValue: 0.992829252967651 }
shapiroWilk([0.01, 0.02, 0.02, 0.03, 0.05, 0.09, 0.2, 0.4, 0.9, 2.5]);
// { statistic: 0.6044891945571944, pValue: 0.00006255986205030777 }

statistic is W, in (0, 1]; values near 1 are consistent with normality. The test needs at least 3 values and, like scipy, gives an accurate W for any size but an approximate p-value above 5000 values. Both fields are null for fewer than three values, NaN in the sample, or a constant sample. The W statistic matches scipy to floating-point precision; the p-value goes through log(1 - W) and matches to about 1e-10 relative precision when W is very close to 1.

Scripts

npm ci
npm run build
npm test
npm run lint

Semver policy

This package follows semantic versioning:

  • Patch — bug fixes that do not change the public API
  • Minor — new functions or non-breaking additions
  • Major — breaking changes to exported types or function signatures

Until 1.0.0, the 0.x series may introduce breaking changes in minor versions.

License

Elastic License 2.0. This may be revisited when the package is made public.

版本与发布记录

@elastic/statistics 共发布 5 个版本,首次发布于 2026/09/24;过去 12 个月发布了 5 个版本。

版本发布日期距今
0.0.4latest2026/11/058 天前
0.0.32026/10/071 个月前
0.0.22026/09/281 个月前
0.0.12026/09/241 个月前
0.0.02026/09/241 个月前

关于 @elastic/statistics 的常见问题

@elastic/statistics 是什么?

Pure statistical functions for LLM evaluations

如何安装 @elastic/statistics?

在项目目录运行 npm install @elastic/statistics,或使用 pnpm add / yarn add / bun add。

@elastic/statistics 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@elastic/statistics 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@elastic/statistics 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@elastic/statistics 可以商用吗?

@elastic/statistics 使用 Elastic-2.0 许可。声明的许可为 Elastic-2.0,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@elastic/statistics 的下载量有多少?

根据 npm 官方下载统计,@elastic/statistics 在 2026/10/14 – 2026/11/12 这 30 天内被下载 129,038 次,日均约 4,301 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@elastic/statistics 还在维护吗?

最新版本 0.0.4 发布于 2026/11/05(8 天前);至今共发布 5 个版本,其中过去 12 个月发布了 5 个;首次发布于 2026/09/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。