A twelve-week course on the probability and statistics that a radio sensing result rests on. The running scenario is deliberately small and introduced from zero: a few Wi-Fi receivers and a Bluetooth scanner in a room, a transmitter that sends packets at a known rate, and the question "how many people are here, and how sure are we?". Every week isolates one statistical idea inside that scenario, shows it as a live picture the student can push, and then breaks it.
The throughline has two halves. An estimate without a defensible uncertainty is not a result. And an uncertainty is only defensible if you know what the independent unit is and what the method must beat. Sensor streams are long, correlated and drifting, so a million minutes can hold the information of six days, and a clever model can lose to "same as an hour ago". The course teaches students to see both traps before they compute anything.
Lectures are self-contained. No week depends on a lab notebook, a campaign or a named experiment: each scenario is stated in place, with its assumptions, and the numbers on the slides come from the week's own seeded workbook.
The 12-week arc
1 of 12 lectures published — each a self-contained read with a slide deck and runnable workbook. Start at the first published week and work forward.
| Wk | Theme & focus | Read |
|---|---|---|
| 01 | Estimation theory & the CRLB start here Bias, variance, MSE decomposition, score, Fisher information and the Cramér-Rao floor, with RSSI ranging under log-normal shadowing as the worked case. Rebuilt 2026-09-29 under the interactive-first contract with ten widgets: `PacketDraw`, `BiasVarianceDart` (sample size N 2 to 200, shrink factor c 0.5 to 1.2, true value mu 0 to 8 dB), `DivisorRace`, `FisherCurvature` (noise sigma 0.5 to 8 dB, packets 1 to 400), `ScoreWeld`, `CoverageRain`, `RangingFloor` (distance 1 to 20 m, shadowing 2 to 10 dB, path-loss exponent 1.6 to 4, packets 1 to 400), `ReceiverGeometry`, `AveragingFloor`, `SupportBreaker`; break it: 1 packet, a support that moves with the parameter, and a bias fixed to the place | read → slides · workbook |
| 02 | Counting with likelihoods Poisson, negative binomial and Conway-Maxwell-Poisson models for per-minute counts (packets heard, Bluetooth addresses, people), dispersion and the Fano factor, maximum likelihood for a count. Widgets: `DispersionDial` (mean 0.5 to 40 per minute, dispersion nu 0.3 to 3; seeded histogram against the pmf, Fano readout), `SuperpositionCounter` (people k 0 to 10, per-person NegBin shape; shows k people sum to NegBin(k·alpha, p)). Break it: fit a Poisson to under-dispersed counts and watch the 90 % interval over-cover and the likelihood ratio flag the misfit | planned |
| 03 | Bayesian inference for a headcount Prior, likelihood and a grid posterior over the number of people from one noisy level reading; nested credible sets; the open "N or more" bucket; the resolution ladder (the set width is 2·z·sigma over the slope of the level-versus-count curve). Widgets: `CountPosterior` (observed level, level noise sigma, curve slope, prior uniform or negative binomial; 50 % and 90 % sets, mass above the top label), `ResolutionLadder` (knee N0 1 to 10 people, amplitude, noise; resolvable bucket at 1, 3 and 6 people). Break it: a saturating curve fitted from one calibration point, where every busy minute reads "2 or more" | planned |
| 04 | Hierarchical models & shrinkage Many receivers, each with its own offset: no pooling, complete pooling and partial pooling; empirical Bayes; Stein's paradox as the reason shrinkage wins. Widgets: `PoolingSlider` (receivers 3 to 20, between-receiver spread tau 0 to 5, within noise sigma, pooling weight lambda; per-receiver estimates slide toward the grand mean, MSE readout for each regime), `SteinRace` (dimension k 1 to 20; James-Stein against the raw mean). Break it: pool receivers that do not share a mean (a heterogeneity toggle) and shrinkage increases the error | planned |
| 05 | Dependence in time & resampling Stationarity, autocorrelation, AR(1) and Ornstein-Uhlenbeck models of a quiet channel, effective sample size, why the day and not the minute is the replication unit, block bootstrap and exact enumeration when only a few days exist (six days give only 462 distinct resamples). Widgets: `OUChannel` (relaxation time 0.5 to 10 min, noise 0.01 to 0.1 dB, sampling 1 to 100 Hz, window; ACF and n_eff readout, naive against corrected 95 % CI), `BlockBootstrap` (block length 1 to 120, resamples; coverage of the interval by simulation). Break it: an iid bootstrap on autocorrelated minutes, whose nominal 95 % interval covers far less | planned |
| 06 | Experimental design & confounding Treatments, blocking, randomisation, ABBA ordering against slow drift, within-unit contrasts (same receiver, same arm) before across-unit ones, confounders that ride on the clock (the building filling while one person walks), and a first causal diagram. Widgets: `DriftDesign` (design AB, ABBA or randomised; drift slope 0 to 1 dB per hour; effect size; estimated effect and its bias), `ConfounderDAG` (toggle arrows time to occupancy to signal; adjusted against unadjusted estimate). Break it: an AB design under linear drift that reports an effect where there is none | planned |
| 07 | Tests, power & equivalence p-values as a statistic of the design, power and sample size, significance by sample size (the p-value falls while the effect shrinks), two one-sided tests for equivalence within a margin, surrogate nulls for correlated series (circular shift, AR surrogates), multiple comparisons. Widgets: `PowerExplorer` (effect delta, sigma, n per arm 5 to 5,000, alpha; power curve and p-value readout), `TOSTWindow` (margin Delta, observed difference and its CI; pass means inside the margin, fail does not mean different), `SurrogateNull` (series redness phi 0 to 0.99; shuffle against circular-shift null). Break it: the forking-paths slider (analyses tried 1 to 40) and the family-wise error it buys | planned |
| 08 | Covariance & counting sources with eigenvalues Sample covariance of a CSI snapshot matrix (subcarriers by chains by time), the Marchenko-Pastur bulk, the BBP phase transition, the number of eigenvalues above the edge as a source count, shrinkage covariance estimators, and why one shared transmitter makes receivers non-independent. Widgets: `EigenBulk` (dimension p 8 to 256, snapshots n 16 to 4,096, spike strengths per body; histogram against the MP law, count above the edge), `SpikeSink` (aspect ratio gamma; spike SNR against the threshold square root of gamma). Break it: shrink n until the bodies sink into the bulk, then add a common-mode spike from a shared transmitter that counts as one extra "person" | planned |
| 09 | State-space inference & fusion Hidden states that move: the Kalman filter, a birth-death count process, sparse anchors (a manual count or a Bluetooth reference), gain decay as an anchor ages, and fusion as inference (switch on disagreement, do not blindly average). Widgets: `AnchoredKalman` (process noise q, measurement noise R, anchor period 5 to 120 min; gain curve and 90 % band), `FusionSwitch` (two sensors with their own noise and bias; averaged against switched estimate). Break it: a filter with the wrong process noise, whose band is too narrow and misses the truth | planned |
| 10 | Calibration & drift Identifiable calibration: an independent reference fixes the scale, a level-only offset is not a slope; where to spend a fixed reference budget (early against spread through the day); the baselines a calibrated model must beat (hour-of-day clock, persistence); sequential change detection with CUSUM, AR(1) whitening, and an anytime-valid trigger. Widgets: `ReferenceBudget` (references 1 to 12, schedule morning or distributed, drift slope; mean error against clock and persistence), `DriftDetector` (shift size, AR phi 0 to 0.95, whitening toggle, threshold h; false alarms per hour and detection delay). Break it: calibrate on an empty room and apply the scale to a busy one | planned |
| 11 | Honest uncertainty & reporting Split conformal prediction and its exchangeability assumption, weighted conformal under drift, coverage checked out of sample and under environment shift, interval scores that trade width against misses, and the reporting canon (CDFs, CIs, effect sizes, the replication unit named). Widgets: `ConformalBand` (calibration residuals 10 to 500, spread, target coverage; half-width readout), `ShiftCoverage` (environment shift in people; coverage falls from nominal), `IntervalScore` (width against miss penalty). Break it: calibrate on one room, test in another, and watch 90 % become much less | planned |
| 12 | Capstone A pre-registered analysis plan for a sensing experiment, delivered as a short interactive deck: hypotheses, the replication unit, the baselines, the exact interval method with its coverage check, a sample-size widget (`PlanPower`: days, receivers, effect, autocorrelation), and one break-it slide showing which violation would invalidate the plan | planned |
Capstone
Week 12: each student takes a real or planned sensing experiment and writes a
pre-registration a reviewer could hold them to. It states the hypotheses, the design
(blocking, order, what is held fixed), the replication unit and its count, the
baselines the method must beat, the exact analysis, and the uncertainty reporting,
including how coverage will be checked out of sample. It ships as a short Slidev deck
under the same contract as the lectures: one PlanPower widget that recomputes the
power when the number of independent days or the autocorrelation changes, and one
break-it slide that shows the result a violated assumption would produce.