The Machines · Statistics & machine learning

stats

Statistics — machines/stats.shoddy

the stats machine's icon

Summary

stats is the numbers-about-numbers machine. Give it a list of values and it tells you where they sit (Mean, Median, Modes), how spread out they are (StdDev, Iqr, Mad), what shape they make (Skewness, Kurtosis), and how two lists move together (Correl, LinFit). Then it tells you whether what you're seeing is real: t-tests, chi-square tests, ANOVA, and confidence intervals — a confidence interval being a range the true answer very likely falls inside. Each test reports an honest p-value: the chance that luck alone would produce a gap this large. That p-value is computed from the actual distribution — the curve that says how likely each outcome is — not looked up in a table. It is pure Shoddy from top to bottom, built over four runtime builtins: Sort, and the three special functions (Erf, GammaP, BetaI) that give the normal, chi-square, t, and F curves their native precision.

A Brief History of Student

The t-test in this machine was invented in a brewery, and published under a false name. William Sealy Gosset was a chemist at Guinness in Dublin. His questions were industrial ones: which barley strain yields more, does this batch differ from that one? His samples were always a handful, because experiments cost money. The statistics of the day assumed samples large enough that such questions answered themselves. So in 1908 Gosset worked out exactly how much less a small sample can be trusted — the t-distribution. Guinness regarded its use of statistics as a trade secret and let him publish only under a pseudonym. He chose "Student", and the name stuck to the method forever. It is the founding story of practical statistics. The tests in this machine exist not to adorn research papers but to answer a brewer's kind of question — sixteen measurements, two batches, is the difference real? — with an honest p-value computed from the actual distribution. That is precisely what Gosset built.

Why It's Useful

The moment a program measures anything — test scores, reaction times, plant heights, coin flips — the questions start. What's typical? How much do they vary? Are these two groups actually different, or did chance just make them look that way? Those questions have canonical, centuries-polished answers, and stats gives them their Shoddy names. It's the difference between eyeballing two averages and being able to say "p = 0.02: a gap this large happens by luck about one time in fifty." Every convention is the standard classroom one: sample variance divides by n−1, quantiles interpolate the way R and Excel do, and p-values are two-sided. So answers here match answers from R, scipy, or a textbook worked example.

One scale note: Shoddy lists are linked lists, and most of these words walk them more than once. That's perfect for classroom-sized data — dozens to thousands of values — and wrong for bulk analytics. Know which one you're doing.

User's Guide

Include the file (it brings seq and dict along) and ask your questions:

Include "stats.shoddy"

Def Main()
    Let scores = { 72, 85, 91, 68, 77, 85, 94, 81 }

    Print(Mean(scores))                  ' 81.625
    Print(Median(scores))                ' 83
    Print(StdDev(scores))                ' 8.94... (sample, n-1)
    Print(Percentile(scores, 90))        ' the 90th percentile
    Print(Outliers(scores))              ' [ ] — nobody past the fences

    ' Did the class really improve after the new textbook?
    Let before = { 71, 78, 82, 69, 75 }
    Let after  = { 76, 84, 88, 71, 82 }
    Let t = TTestPaired(before, after)
    Print(PVal(t))                       ' small p: yes, it's real

    ' How tight is our estimate of the mean?
    Let ci = MeanCI(scores, 0.95)
    Print(Str(Fst(ci)) & " TO " & Str(Snd(ci)))

A few things worth remembering:

Builtins

The three special functions the runtime dispatches — not defined here, documented here

These are not stats's Defs. The engine dispatches them, and a Def whose name is a builtin is refused. They are listed on this page because stats is the machine whose domain they belong to, and they need no Include. The same three are documented in machines/stats.shoddy's own header block.

Three functions the .NET base library does not have, implemented in the engine because they need native precision. Under the hood they use the classic Lanczos log-gamma, power series, and modified-Lentz continued fractions, accurate to about 1e−14 relative over the ranges used here. They are what makes every p-value on this page a real p-value rather than a lookup in a printed table. They are also the reason this machine needs the runtime at all — everything else in the file is ordinary Shoddy. All three are pure, and all three abort outside their domain. The CDF words below check before they call.

WordDescription
Erf(x)The error function: odd, and bounded strictly between −1 and 1. NormCdf below is this, shifted and scaled.
GammaP(a, x)The regularized lower incomplete gamma P(a, x). Aborts unless a is positive and x is not negative. Chi2Cdf is this one.
BetaI(a, b, x)The regularized incomplete beta Ix(a, b). Aborts unless a and b are both positive and x is between 0 and 1. TCdf and FCdf are both this one.

Sort is not documented here, though this machine leans on it for every median, quantile and rank. It is a sequence operation and seq is the sequences machine, so its entry is there — this machine is a consumer of it, not its home.

Word Reference

Every word, plus the Fit and TestResult types

Aggregation poly — List or Array

WordDescription
Sum(xs)Adds every number together. Empty list totals 0.
Product(xs)Multiplies every number together. Empty list gives 1.
Maximum(xs)The largest value. Needs at least one item.
Minimum(xs)The smallest value. Needs at least one item.

Central tendency

WordDescription
Mean(xs)The arithmetic mean. Average is kept as an everyday alias.
WeightedMean(xs, ws)Mean with per-value weights — grades with different credit hours, say.
GeoMean(xs)Geometric mean, for rates and growth factors. All values must be positive.
HarmonicMean(xs)Harmonic mean — the right average for rates like speeds over a fixed distance.
Median(xs)The middle value (interpolated for even counts).
Modes(xs)ALL of the most frequent values, in first-seen order. Works on any =-comparable values, not just numbers.

Quantiles and spread

WordDescription
Quantile(xs, p)The value a fraction p (0 to 1) of the way through the sorted data, linearly interpolated (R type 7 / Excel PERCENTILE.INC).
Percentile(xs, k)The same, taking 0..100: Percentile(xs, 75) is the third quartile.
Iqr(xs)Interquartile range: Q3 − Q1, the box-plot box.
RangeOf(xs)Max − min. (Not called "Range" — that's the builtin that builds { a .. b }.)
Var(xs) / VarP(xs)Variance: sample (n−1) and population (n) forms, two-pass for stability.
StdDev(xs) / StdDevP(xs)Standard deviation — the typical distance of a value from the mean. Same two forms.
StdErr(xs)Standard error of the mean: StdDev / √n.
Mad(xs)Median absolute deviation — a robust spread measure outliers can't drag around.
SqDevSum(xs)Sum of squared deviations from the mean — the shared core under the variance words.

Shape, z-scores, outliers

WordDescription
Skewness(xs)Which way the distribution leans (moment form, as scipy with bias=True).
Kurtosis(xs)How heavy the tails are — excess form, so the normal distribution scores 0.
ZScore(x, m, s)How many SDs x sits from mean m: (x - m) / s.
ZScores(xs)The whole list standardized against its own mean and sample SD.
Outliers(xs)Values beyond the 1.5×IQR box-plot fences.
OutliersZ(xs, z)Values more than z sample SDs from the mean.

Frequencies dict association lists

WordDescription
Freq(xs)Value → count as a dict, keys in first-seen order. Read it with DictGet and friends.
RelFreq(xs)Value → proportion of the whole (multiply by 100 for percentages).
Ecdf(xs, x)Empirical CDF: the proportion of the data at or below x.

Correlation and regression

WordDescription
Cov(xs, ys)Sample covariance (n−1) — the primitive under the next two.
Correl(xs, ys)Pearson correlation, −1 to 1.
Spearman(xs, ys)Rank correlation — Pearson on the ranks; catches any monotone relationship, straight or not.
RankOf(xs, x) / Ranks(xs)Average ranks (ties share), the machinery under Spearman.
LinFit(xs, ys)Least-squares line → Fit(Slope, Intercept, R2): y ≈ Slope·x + Intercept, with R2 the share of variance explained.

Distributions

WordDescription
NormPdf(z) / NormCdf(z)Standard normal density and CDF (via Erf). For general x, standardize with ZScore first.
Chi2Cdf(x, df)Chi-square CDF (via GammaP).
TCdf(t, df)Student's t CDF (via BetaI).
FCdf(f, d1, d2)F CDF (via BetaI).
NormInv(p) / TInv(p, df)The inverse CDFs (quantile functions), found by bisection — what turns "95% confident" into an exact critical value.

Inference all p-values two-sided

WordDescription
TTest1(xs, mu0)One-sample t-test: is the mean plausibly mu0? → TestResult(Stat, Df, PVal).
TTest2(xs, ys)Two-sample t-test for independent groups — pooled/equal-variance, the textbook form (R's var.equal = TRUE).
TTestPaired(xs, ys)Paired t-test: a one-sample test on the before/after differences.
ZTest1(xs, mu0, sigma)One-sample z-test when the population SD is known. Df is 0.
Anova(gs)One-way ANOVA over a list of groups (a list of lists). Stat is F; Df is the between-groups df; within = total n − groups.
ChiSqGof(obs, exp)Chi-square goodness of fit: observed counts against expected counts.
ChiSqTest(rows)Chi-square independence on a contingency table given as a list of rows.
TwoPropZTest(k1, n1, k2, n2)Two-proportion z-test: k1 successes of n1 against k2 of n2, pooled SE.
TwoSidedTP(t, df)Two-sided p for a t statistic — the helper the t-tests share.

Intervals and effect sizes

WordDescription
MeanCI(xs, conf)t-based confidence interval for the mean → Pair(lo, hi). conf is e.g. 0.95.
PropCI(k, n, conf)Confidence interval for a proportion (normal approximation), k successes of nPair(lo, hi).
CohenD(xs, ys)Cohen's d: the two means' difference in pooled-SD units — how big the effect is, not just whether it's there.
PooledVar(xs, ys)Pooled variance of two samples — shared by TTest2 and CohenD.

Who Uses It

UserHow
engEvery descriptive statistic and distribution eng offers is an Eng* face over one of these, and LinFit sits under its four regression models.
finEvery descriptive statistic fin offers is a Fin* face over one of these, and LinFit sits under its four regression models.
plotterSum, Maximum, Minimum, Quantile and Median — axis ranges and the distribution marks come from the summaries.
tallyThe whole report half: Mean, Quantile, Correl, LinFit, Freq, TTest2, Anova and Outliers, one spec verb each.

The Machines It Uses

MachineWhy
seqCountIf, Flatten and ZipWith under the summaries.