← All projectsGitHub
Machine learning on qualitative data

How much hand-coding can an LLM coder replace, with a valid interval, when its error differs by group and the category is rare?

research/llm-coding-inference

Research programme: valid inference from LLM-coded qualitative data under group shift and rare categories; on 44,485 real tweets a pooled PPI interval covers as little as 67% when the audit's language mix differs from the corpus, a language-stratified one 94 to 96%

20 tests

What it found

An open research programme. First real-data result (H1): on 44,485 NaijaSenti tweets in four languages, a 400-tweet audit whose language mix differs from the corpus makes the pooled prediction-powered 95% interval cover as little as 67% (English-trained coder) or 69% (in-language coder); PPI++ reaches 89%, and pooled hand-coding alone 87% under equal quotas. A language-stratified estimator with corpus-known sizes covers 93.8 to 95.9% in every design (planned bar 94%, one cell 0.2 points under) but is not narrower than stratified hand-coding, because the three stand-in coders (no LLM yet) are weak. One corpus, three audit mixes. A stdlib estimator library is built and tested. First preliminary result, on simulated corpora with a stand-in coder: the normal interval of a coder-label-stratified audit covers 57% at 1% prevalence, 83% at 3% and 94% at 20% (nominal 95%), so rare-category audit designs need small-count-safe intervals. An LLM's codes for qualitative text carry error that can differ between groups, and prediction-powered inference corrects counts, gaps and coefficients from a random hand-coded audit. The earlier qual-* projects showed on GoEmotions, with stand-in coders and no LLM, that naive counts are confidently wrong, that the correction is valid but wider than hand-coding alone for weak coders, and that a random audit cannot estimate a rare group. The programme asks when the audit can be small and how to sample it when the coder's error differs by group and the target category has prevalence under 5%. Hypotheses H1 to H5 cover pooled-correction failure under group shift, the end of the gain for rare categories, a real LLM coder, audit design, and a closed-form audit-size rule. Limits at this stage: the proposal's references were written from memory because the arXiv and Crossref hosts were blocked, and are to be machine-checked in milestone 1. Milestone 4 (H2, H4; both refuted as stated): on GoEmotions (38,234 comments, nine emotions at 0.10 to 1.96%, audit of 200, weak stand-in coder) normal-approximation intervals under uniform, PPI++ and label-stratified audits cover as little as 10 to 61% below 0.5% prevalence, so apparent width gains are not valid; Wilson on a uniform audit covers 91 to 99%, and an uncertainty-weighted audit covers 93 to 96% for seven of nine categories (86% for disgust, 89% for sadness) and is 22 to 52% narrower than Wilson for six of them.

Research log

Ongoing: each run adds a batch and an entry, newest first. Source: LOG.md.

2026-10-31 · Milestone 7e: the 2,000-draw check moves into the paper and README (a writing step, no experiment)

2026-10-30 · Milestone 7d: does the library path really cover below 94.6% on admiration at n = 1000? (planned before running)

### Outcome (experiments/h7d_admiration_2000.py, about 5 min; experiments/h7d_admiration_2000.txt)

2026-10-30 · Milestone 7c: audit_interval, and does the library path (plan_audit -> draw -> interval) reproduce 6al? (planned before running)

### Outcome (experiments/h7c_end_to_end.py, about 4 min; experiments/h7c_end_to_end.txt; 500 draws per cell)

2026-10-30 · Milestone 7b: plan_audit, one call from a pilot to the rest of the audit

2026-10-30 · Milestone 7a: the screened-audit rule becomes library code (llmci/audit_design.py)

2026-10-30 · Milestone 6am: is the guarded screen's J_hat cutoff (0.3) a knife edge? (planned before running; ran straight through)

### Outcome (experiments/h6am_tau.txt)

2026-10-30 · Milestone 6al: does a prevalence guard (cells only if the pilot holds at least G human positives) make 6ak's screen valid on rare categories? (planned before running)

### Outcome (experiments/h6al_guard.py, about 8 min; experiments/h6al_guard.txt; 500 draws per cell, coverage +/- 2 points; WE = Wilson on n_eff)

2026-10-30 · Milestone 6ak: can a pilot-estimated informedness screen (J_hat >= 0.3) choose between pooled and coder-cell audits, keeping 6ai's gain and avoiding 6aj's waste? (planned before running)

### Outcome (experiments/h6ak_screen.py, about 6 min; experiments/h6ak_screen.txt; 500 draws per cell, coverage +/- 2 points; WE = Wilson on n_eff)

2026-10-29 · Milestone 6aj: does 6ai's coder-cell floor rule transfer to a second corpus (NaijaSenti, negative share, three Qwen coders)? (planned before running)

### Outcome (experiments/h6aj_naija_floor.py, about 6 min; experiments/h6aj_naija_floor.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-29 · Milestone 6ai: do a floor on each coder cell's allocation, or an independent pilot, repair 6ah's pilot-estimated two-cell audit? (planned before running)

### Outcome (experiments/h6ai_floor_indep.py, about 25 min; experiments/h6ai_floor_indep.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-29 · Milestone 6ah: if the two-coder-cell audit's allocation is estimated from a 30% pilot rather than an oracle, how much of 6ag's 15 to 25% width gain survives, and does coverage hold? (planned before running)

### Outcome (experiments/h6ah_pilot_cells.py, about 4 min; experiments/h6ah_pilot_cells.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-29 · Milestone 6ag: when audit strata are the coder's own cells (coder-positive vs coder-negative), whose prevalences differ by a large factor, does stratifying finally pay? (planned before running)

### Outcome (experiments/h6ag_coder_strata.py, about 3 min; experiments/h6ag_coder_strata.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-29 · Milestone 6af: on common GoEmotions categories (admiration 8%, neutral 23%), where does stratifying the audit start to pay, and does 6ae's "pool the audit" advice survive? (planned before running)

### Outcome (experiments/llm_code_goemotions.py about 31 min per category on 2 threads each; experiments/h6af_common_category.py, experiments/h6af_common_category.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-29 · Milestone 6ae: does merging the rarest GoEmotions groups into one audit stratum repair the n = 400 fear undercoverage that the estimator could not? (planned before running)

### Outcome (experiments/h6ae_merge_strata.py, under 1 min; experiments/h6ae_merge_strata.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-28 · Milestone 6ad: does a Wilson interval on the PPI estimate's effective sample size repair the n = 400 rare-category undercoverage that no PPI weight could? (planned before running)

### Outcome (experiments/h6ad_wilson_ppi.py, under 2 min; experiments/h6ad_wilson_ppi.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-28 · Milestone 6ac: does a pooled PPI weight, with or without a plus-four variance floor, repair 6ab's undercoverage of tuned stratified PPI at n = 400? (planned before running)

### Outcome (experiments/h6ac_pooled_lambda.py, about 5 min; experiments/h6ac_pooled_lambda.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-28 · Milestone 6ab: with a real zero-shot LLM coder on GoEmotions fear and sadness, does tuned stratified PPI beat human-only, and by how much? (planned before running)

### Outcome (experiments/llm_code_goemotions.py, about 45 min for 2 x 6,683 items on 4 CPU cores; experiments/h6ab_llm_goemotions.py, experiments/h6ab_llm_goemotions.txt; 500 draws per cell)

2026-10-28 · Milestone 6aa: does freezing the PPI weight from a pilot stage make the stratified betting confidence sequence cheaper than 6z's lambda = 1, and does it beat the pooled human-only sequence? (planned before running)

### Outcome (experiments/h6aa_pilot_lambda.py, about 10 min; experiments/h6aa_pilot_lambda.txt; 300 draws per cell, coverage +/- 2.5 points)

2026-10-28 · Milestone 6z: does a stratified, coder-assisted betting confidence sequence give a valid sequential audit at a rare category, and at what cost? (planned before running)

### Outcome (experiments/h6z_strat_cs.py, about 25 min; experiments/h6z_strat_cs.txt; 300 draws per cell, coverage +/- 2.5 points)

2026-10-27 · Milestone 6y: does an always-valid confidence sequence repair the rare-category sequential audit? (planned before running)

### Outcome (experiments/h6y_confseq.py, 2.5 min; experiments/h6y_confseq.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-27 · Milestone 6x: a label-free audit-size rule for the rare category (planned before running)

### Outcome (experiments/h6x_label_free.py, under 2 min; experiments/h6x_label_free.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-27 · Milestone 6w: is the sequential rare-category audit's failure an understated standard error at the stop? (planned before running)

### Outcome (experiments/h6w_stop_z.py, under 1 min; experiments/h6w_stop_z.txt; 500 draws per cell)

2026-10-27 · Milestone 6v: does an optional-stopping correction (a wider critical z at the stop) repair the rare-category sequential audit? (planned before running)

### Outcome (experiments/h6v_alpha_spend.py, about 4 min; experiments/h6v_alpha_spend.txt)

2026-10-27 · Milestone 6u: stopping the rare-category sequential audit on a Wilson-upper-bound half-width (planned before running)

### Outcome (experiments/h6u_wilson_stop.py, 3.4 min; experiments/h6u_wilson_stop.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-27 · Milestone 6t: a sequential audit at a rare category, with and without a minimum-positives stopping guard (planned before running)

### Outcome (experiments/h6t_rare_sequential.py, about 3.5 min; experiments/h6t_rare_sequential.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-27 · Milestone 6s: does a Wilson-upper-bound S2 in the pilot remove the low-n bias of the rare-category audit-size rule? (planned before running)

### Outcome (experiments/h6s_wilson_pilot.py, about 100 s; experiments/h6s_wilson_pilot.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-26 · Milestone 6r: does the pilot-estimated audit-size rule survive a rare category (fear, sadness) on the GoEmotions groups? (planned before running)

### Outcome (experiments/h6r_rare_pilot.py, about 1 min; experiments/h6r_rare_pilot.txt; 500 draws per cell, coverage +/- 2 points)

2026-10-26 · Milestone 6q: the lambda-aware audit-size rule on NaijaSenti with the real Qwen coders, oracle and pilot-estimated (planned before running)

### Outcome (experiments/h6q_naija_sizing.py, about 90 s; experiments/h6q_naija_sizing.txt; 1,000 draws per cell, 500 for the pilot version)

2026-10-26 · Milestone 6p: a lambda-aware audit-size rule, so the plan can choose its control variate (planned before running)

### Outcome (experiments/h6p_lambda_sizing.py, about a minute; experiments/h6p_lambda_sizing.txt; 1,000 draws per cell)

2026-10-26 · Milestone 6o: does the audit-size rule (6a to 6f) hold on a second corpus, GoEmotions subreddit groups? (planned before running)

### Outcome (experiments/h6o_reddit_sizing.py, 8 s; experiments/h6o_reddit_sizing.txt; 1,000 draws per cell)

2026-10-26 · Paper draft 1.2: Section 8 and the abstract corrected for 5h

2026-10-26 · Milestone 5h: is the real coders' null explained by informedness, not agreement? (planned before running)

### Outcome (experiments/h5h_informedness.py, h5h_informedness.txt; 600 draws per cell)

2026-10-26 · Milestone 7 (part): paper draft 1.1 adds Section 8, what a coder must be to pay

2026-10-26 · Milestone 5g: does a synthetic coder with error fitted to the real 1.5B and 3B errors reproduce their width ratios?

### Outcome (experiments/h5g_fitted.txt)

2026-10-26 · Milestone 5f: at the real coders' accuracy (0.70), and with errors tied to a text feature, does synthetic PPI++ still beat human-only? (planned before running)

### Outcome (experiments/h5f_text_error.py, h5f_text_error.txt; 600 draws per cell; realised agreement 0.697 to 0.706 at a = 0.70, 0.591 to 0.608 at 0.60)

2026-10-26 · Milestone 5e: how much does correlated coder error cost PPI++ at matched accuracy? (planned before running)

### Outcome (experiments/h5e_correlated.py, h5e_correlated.txt; 600 draws per cell; realised agreement 0.791 to 0.802 at a = 0.80 and 0.898 to 0.908 at 0.90)

2026-10-26 · Milestone 5d: how accurate must a coder be before PPI++ beats human-only labelling? (planned before running)

### Outcome (experiments/h5d_breakeven.py, 600 draws per cell, experiments/h5d_breakeven.txt)

2026-10-26 · Milestone 5c: does a threshold chosen on c = 100 human labels, charged to PPI++, give a width gain over human-only with n + 100 labels? (planned before running)

### Outcome (experiments/h5c_calibrated.py, 600 draws per cell, 3 processes; experiments/h5c_<model>.txt)

2026-10-26 · Milestone 5b: does the PPI++ width gain grow with model size within one family? (planned before running)

### Outcome (experiments/llm_code.py for 0.5B in 9 min and 3B in 45 min on 4 CPU cores; experiments/h3_llm_width.py; experiments/h3_llm-Qwen2.5-{0.5B,3B}-Instruct.txt; 600 draws per cell)

2026-10-26 · Milestone 7 (part): paper draft 1 folds in regression, small-audit and real-LLM results

2026-10-26 · Milestone 5: does a real local LLM coder narrow the valid PPI++ interval? (planned before running)

### Outcome (experiments/llm_code.py, 6,000 items in about 21 min on 4 CPU cores; experiments/h3_llm_width.py, experiments/h3_<coder>.txt; 600 draws per cell, numpy)

2026-10-26 · Milestone 6n: with valid intervals, is PPI++ narrower than human-only HC3 + t? (planned before running)

### Outcome (experiments/h6n_width.py, about 15 min, 3 processes; experiments/h6n_<coder>.txt; 600 draws per cell, numpy)

### Addendum to 6n: cross-fit at n = 60 with non-finite draws dropped (experiments/h6n_nanfix.py, experiments/h6n_nanfix_<coder>.txt; independent rerun, same seed and design, ratios only)

2026-10-26 · Milestone 6m: does an HC3-type leverage correction on the PPI++ influence close the small-audit gap? (planned before running)

### Outcome (experiments/h6m_ppi_hc3.py, about 25 min, 3 processes; experiments/h6m_<coder>.txt; 1,500 draws per cell, numpy)

2026-10-25 · Milestone 6l: does a t quantile (and HC3 for human-only) restore coverage at audits of 60 to 200? (planned before running)

### Outcome (experiments/h6l_small_sample_interval.py, about 20 min, 3 processes; experiments/h6l_<coder>.txt; 1,500 draws per cell, numpy)

2026-10-25 · Milestone 6k: do selection effects show at small audits (n = 60, 100, 200)? (planned before running)

### Outcome (experiments/h6k_small_audit.py, about 80 min; experiments/h6k_small_audit.txt; 3,000 paired draws per cell, numpy)

2026-10-26 · Milestone 6j: a paired test of the selection effect that 6i could not resolve (planned before running)

### Outcome (experiments/h6j_paired.py, about 25 min, 3 processes; experiments/h6j_paired.txt; 4,000 paired draws per coder)

2026-10-25 · Milestone 3b: does H1 replicate on a second real corpus whose groups differ little in coder error? (planned before running)

### Outcome (experiments/group_shift_reddit.py, under a minute; experiments/group_shift_reddit.txt; 1,000 draws per cell)

2026-10-25 · Milestone 6i: does cross-fitting the PPI++ weight remove the coverage cost of tuning it on the audit? (planned before running)

### Outcome (experiments/h6i_crossfit.py, about 4 min; experiments/h6i_crossfit.txt; 1,000 draws per cell, numpy)

2026-10-25 · Milestone 6h: does power-tuned PPI++ for regression at least match human-only OLS? (planned before running)

### Outcome (experiments/h6h_ppipp_regression.txt; python3.13 experiments/h6h_ppipp_regression.py, about 2 minutes; same corpus, coders, n = 400 audit, 1,000 draws and seed as 6g)

2026-10-25 · Milestone 6g: regression coefficients from LLM codes plus an audit (H5 second half; planned before running)

2026-10-25 · Milestone 7a: first draft of the paper (paper/paper.md, paper/references.bib); no new experiment

2026-10-25 · Milestone 6f: the oracle audit size of 6a to 6e had a bug; the "unexplained" 6e gap was it (found while diagnosing; correction, not a new hypothesis)

2026-10-25 · Milestone 6d: does the sequential rule survive a 1-point target and a tiny start? (planned before running)

### Outcome (experiments/h6d_hard.py, about 2 min; experiments/h6d_hard.txt; 200 draws per cell)

2026-10-25 · Milestone 6c: a sequential audit that stops when the estimated width meets the target (planned before running)

### Outcome (experiments/h6c_sequential.py, about 2.5 min; experiments/h6c_sequential.txt; 1,000 draws per cell)

2026-10-25 · Milestone 6b: plan the audit size from a small pilot, not from oracle variances (planned before running)

### Outcome (experiments/h6b_pilot.py, about 30 s; experiments/h6b_pilot.txt; 1,000 draws per cell)

2026-10-24 · Milestone 6a outcome: H5 supported for the width of the interval; the audit-size rule works but weak coders need a bigger audit than none

2026-10-24 · Milestone 6a: H5, the plug-in width formula and the audit-size rule (planned before running)

2026-10-24 · Milestone 4e outcome: the floor rule stays valid on 18 unseen categories but is wider than Wilson in 16 (width prediction refuted)

2026-10-24 · Milestone 4e: the floor rule on the 18 GoEmotions categories it was not designed on (planned before running)

2026-10-24 · Milestone 4d outcome: a label-free floor rule is valid in 8 of 9 categories and narrower than Wilson in 6 (prediction supported, in-sample)

2026-10-24 · Milestone 4d: choose the pi floor from the coder, no pilot labels (planned before running)

2026-10-24 · Milestone 4c outcome: a bigger pi floor helps the common-rare categories and hurts the rarest (prediction refuted)

2026-10-24 · Milestone 4b outcome: neither small-count interval fixes the weighted audit (refuted)

2026-10-24 · Milestone 4b: small-count-safe intervals for the weighted audit (planned before running)

2026-10-24 · Milestone 4 outcome: H2 and H4 refuted as stated; the useful result is about validity

2026-10-24 · Milestone 4: H2 and H4, rare-category and audit-design benchmark (planned before running)

2026-10-24 · Milestone 3 outcome: H1 supported on real data

2026-10-24 · Milestone 3: H1, group-shift benchmark on NaijaSenti (planned before running)

2026-10-24 · Milestone 2: estimator library llmci/

2026-10-24 · Milestone 1a: citations machine-checked

2026-10-24 · Programme opened: proposal written

2026-10-25 · Milestone 6e: the 1-point target against the finite-population-aware oracle (planned before running; run alongside 6d, PR 10307)

### Outcome (experiments/h6e_tight_target.py, about 17 min; experiments/h6e_tight_target.txt; 300 draws per cell)

Paper, code and results

More in Machine learning on qualitative data

All 23 Machine learning on qualitative data projects →

Other research topics

Proper scoring & elicitation28Effort & peer prediction9Verification games & slashing19Detection & tolerances14Markets as routers13Prediction-market design9Paying contributors8Decentralised training systems23Digital twins & sim-to-real164LLM chip design loops40Robot manufacturing loops53Ambient AI assistant46Self-replicating manufacturing34Simulation-first design64Engineered clothing45Task-specific AI accelerators40Algorithmic chip-design loops42Open-source purpose-built robots44The software-engineering loop43Adversarial human imitation41Open-source residential construction41Autonomous multi-angle capture34Sensing, imaging and 3D31Energy supply and dense energy storage39Robot societies among people31Agentic co-design of low-cost robots27Laundry-hanging robots25Machine learning on qualitative data23Robots on the building site27Civilizations & group psychology1History & human sciences1

Produced with AI assistance (Claude). Results are from the code in this repository and are simulated or stylised unless the abstract says otherwise; nothing here implies affiliation with or endorsement by any lab, researcher or company cited. MIT licensed.