User Tools

Site Tools


statistics:regression

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
statistics:regression [2026/08/19 17:49] – New page: Regression — model families by outcome, dependence in repeated crawls, causal identification; 391-paper corpus analysis + simulation. Authored by Claude karel.kubicek.claudestatistics:regression [2026/08/21 14:50] (current) – Boxes: <wrap> renders a span, use uppercase <WRAP>; one box per list, not per bullet karel.kubicek.claude
Line 1: Line 1:
 ====== Regression ====== ====== Regression ======
  
-A hypothesis test asks whether two groups of sites differ. A regression asks **by how much, holding other things constant** — and that is almost always the question a web measurement actually has. Do sites with a consent banner set fewer third-party cookies //once you account for site rank, category and country//? Does the number of trackers go up after a policy deadline //once you account for the fact that popular sites had more to begin with//? Every one of those is a regression, and this page is about the four things that make one hard here rather than in a textbook: your outcome is a **count** or a **binary flag per site**, not a nice continuous number; your rows are **not independent** because the same site appears twice or shares a tag manager with two hundred others; your coefficient is **not causal** unless you did something specific to make it so; and half the time the model in the paper is not doing inference at all, it is a **classifier**.+A hypothesis test asks whether two groups of sites differ. A regression asks **by how much, holding other things constant** — and that is almost always the question a web measurement actually has. Do sites with a consent banner set fewer third-party cookies //once you account for site rank, category and country//? Does the number of trackers go up after a policy deadline //once you account for the fact that popular sites had more to begin with//? Every one of those is a regression, and this page is about the four things that make one hard here rather than in a textbook: your outcome is a **count** or a **binary flag per site**, not a nice continuous number; your rows are **not independent** because the same site appears twice or shares a tag manager with two hundred others; your coefficient is **not causal** unless you did something specific to make it so; and often enough to matter the model in the paper is not doing inference at all, it is a **classifier** — 124 papers here use a regression only as a classifier, against 253 that use one as an estimator.
  
 This page assumes you know what a regression coefficient and a standard error are. It does not explain the linear model. What it does is date the practice: which model families this literature actually fits, what it does about repeated crawls of the same site (essentially nothing), and what changed in 2025–2026. This page assumes you know what a regression coefficient and a standard error are. It does not explain the linear model. What it does is date the practice: which model families this literature actually fits, what it does about repeated crawls of the same site (essentially nothing), and what changed in 2025–2026.
Line 12: Line 12:
 **''statistics[].method'' is free text and arrives in 315 distinct spellings across 530 tuples**, so nothing below is an exact-string count. The fold is three folds, because a regression is three independent choices — what the outcome is, what you did about dependence, and what the coefficient is claimed to be — and one ranked list of names hides all three. Folded and counted by paper: **''statistics[].method'' is free text and arrives in 315 distinct spellings across 530 tuples**, so nothing below is an exact-string count. The fold is three folds, because a regression is three independent choices — what the outcome is, what you did about dependence, and what the coefficient is claimed to be — and one ranked list of names hides all three. Folded and counted by paper:
  
-  * **Outcome family.** Continuous/OLS **187 (47.8%)**, binary **132 (33.8%)**, ordinal **46 (11.8%)**, count **17 (4.3%)**, proportion (beta) **3 (0.8%)**. **33 papers (8.4%) name a regression but never its outcome family** — "multivariate regression", "regression analysis", "elastic net".+  * **Outcome family.** Continuous/OLS **179 (45.8%)**, binary **132 (33.8%)**, ordinal **46 (11.8%)**, count **17 (4.3%)**, proportion (beta) **3 (0.8%)**. **42 papers (10.7%) name a regression but never its outcome family** — "multivariate regression", "regression analysis", "generalized linear mixed model", "elastic net".
   * **Dependence.** **311 of 391 (79.5%) name nothing at all.** 75 (19.2%) fit a random effect, 3 (0.8%) use fixed effects, 2 (0.5%) use GEE, and exactly **one paper's method string says its standard errors are clustered**. Three more report heteroskedasticity-robust standard errors, which harden a variance assumption and do nothing about correlated rows.   * **Dependence.** **311 of 391 (79.5%) name nothing at all.** 75 (19.2%) fit a random effect, 3 (0.8%) use fixed effects, 2 (0.5%) use GEE, and exactly **one paper's method string says its standard errors are clustered**. Three more report heteroskedasticity-robust standard errors, which harden a variance assumption and do nothing about correlated rows.
   * **Identification.** **365 (93.4%) are associational**, with no design that would license a causal reading. All ten papers that name one — difference-in-differences, regression discontinuity, interrupted time series, instrumental variables, Heckman, propensity weighting — are **2022 or later**, and five of the ten are 2025–2026.   * **Identification.** **365 (93.4%) are associational**, with no design that would license a causal reading. All ten papers that name one — difference-in-differences, regression discontinuity, interrupted time series, instrumental variables, Heckman, propensity weighting — are **2022 or later**, and five of the ten are 2025–2026.
Line 18: Line 18:
 Two gaps are worth naming on their own. Two gaps are worth naming on their own.
  
-  * **Random-effects models are a user-study technique that has not crossed over.** Across all 5,859 papers, **76 fit a random-effects or multilevel model. 58 of the 76 (76.3%) recruited human participants. Four ran a crawl, and not one of the four fits //the site// as the random effect.** Participants get modelled as random effects routinely and correctly — Yuan et al. {[yuan2024_adversarial]} write //"We treat each participant as a random effect because the same user has viewed 15 webpages (i.e., repeated measures)"// — and the identical sentence with "site" in place of "participant" does not appear anywhere in this corpus.+  * **Random-effects models are a user-study technique that has not crossed over.** Across all 5,859 papers, **76 fit a random-effects or multilevel model. 58 of the 76 (76.3%) recruited human participants. Four ran a crawl, and not one of the four fits //the site// as the random effect.** Participants get modelled as random effects routinely and correctly — Yuan et al. {[yuan2024_adversarial]} write //"We treat each participant as a random effect because the same user has viewed 15 webpages (i.e., repeated measures)"//. **One paper in 5,859 fits the //website// as a random effect** — Zeng et al. {[zeng2022_factors]} (IMC 2022), and it is a field study with participants, not a crawl. That is what two full-text probes and a hand read of every hit found; it is a floor, and [[#What the corpus does about it|an earlier draft of this page got it wrong in the other direction]].
   * **Overdispersed counts are usually not fitted with a count model.** A full-text probe across 5,869 stored papers finds **6 that use the word "overdispersion"** and 4 that mention zero-inflation. [[#Counts: third parties per site, requests per page, ads per video|A simulation on this page]] puts the false-positive rate of a Poisson regression on realistically overdispersed tracker counts at **60.4% against a nominal 5%**.   * **Overdispersed counts are usually not fitted with a count model.** A full-text probe across 5,869 stored papers finds **6 that use the word "overdispersion"** and 4 that mention zero-inflation. [[#Counts: third parties per site, requests per page, ads per video|A simulation on this page]] puts the false-positive rate of a Poisson regression on realistically overdispersed tracker counts at **60.4% against a nominal 5%**.
  
-And the one thing that surprises people: **whether ignoring the repeated crawls makes your //p//-value too small or too large depends on where your predictor varies.** For a site-level predictor it is too small (7.8% false positives at two waves, **32.4% at twelve**). For a before/after predictor on the same sites it is too **large** — the naive test is conservative and costs you power (61.6% against 75.2% in the same simulation). "Clustering inflates false positives" is the wrong rule to carry around.+And the one thing that surprises people: **whether ignoring the repeated crawls makes your //p//-value too small or too large depends on where your predictor varies.** For a site-level predictor it is too small (8.6% false positives at two waves, **32.4% at twelve**). For a before/after predictor on the same sites it is too **large** — the naive test is conservative and costs you power (61.6% against 75.2% in the same simulation). "Clustering inflates false positives" is the wrong rule to carry around.
 </WRAP> </WRAP>
  
 ===== What to Read First ===== ===== What to Read First =====
  
-  * **Gelman & Hill** {[gelman2007_regression]} — **read this one first** if you read only one. It is the standard reference for exactly the situation this page is about: a regression whose rows are nested inside groups you did not chooseChapters 11–13 are the multilevel material; the earlier chapters are the best short account anywhere of what a logistic coefficient means. +  * **Gelman, Hill Vehtari, //Regression and Other Stories//** {[gelman2020_stories]} — **read this one first** if you read only one. It is the 2020 successor to Gelman & Hill's 2007 //Data Analysis Using Regression and Multilevel/Hierarchical Models// {[gelman2007_regression]}, and it is the one to buy nowThe catch is that the multilevel material is not in it. //Regression and Other Stories// covers single-level modelling — what a logistic coefficient means, why you should plot the fitted model, how to think about prediction and causal inference — and Cambridge's own listing points readers to the 2007 volume for the multilevel/hierarchical half.((Verified 2026-08-19 against the Cambridge Core listing for //Regression and Other Stories// (2020, 548 pp.), which describes the scope as regression for "comparison, estimation, prediction, and causal inference" and cross-references //Data Analysis Using Regression and Multilevel/Hierarchical Models// as the companion. The 2007 book has not been superseded for the random-effects material.)) **For the random-effects material on this page you still want the 2007 book, chapters 11–13.** 
-  * **Shmueli, "To Explain or to Predict?"** {[shmueli2010_explain]} (Statistical Science 2010) — the four pages to read before you decide whether your logistic regression is a model or a classifier. This is the distinction 124 papers in this corpus are on one side of and 253 on the other, and the two demand entirely different reporting. See [[#Regression as Inference Is Not Regression as a Classifier]]. +  * **Shmueli, "To Explain or to Predict?"** {[shmueli2010_explain]} (Statistical Science 2010) — read this before you decide whether your logistic regression is a model or a classifier. This is the distinction 124 papers in this corpus are on one side of and 253 on the other, and the two demand entirely different reporting. See [[#Regression as Inference Is Not Regression as a Classifier]]. 
-  * **Cameron & Miller** {[cameron2015_practitioners]} — cluster-robust inference, written for practitioners rather than econometricians. The direct fix for [[#The Same Site, Crawled Twice]], and the one that fits in a single ''cov_type="cluster"'' argument. +  * **Cameron & Miller** {[cameron2015_practitioners]} and **MacKinnon, Nielsen & Webb** {[mackinnon2023_clusterrobust]} — cluster-robust inference, written for practitioners rather than econometricians. The direct fix for [[#The Same Site, Crawled Twice]], and the one that fits in a single ''cov_type="cluster"'' argument. Cameron & Miller is the readable introduction; the 2023 guide is the current one and is where the awkward cases live — few clusters, wildly unequal cluster sizes, and the wild bootstrap that fixes both
-  * **Ver Hoef & Boveng** {[verhoef2007_quasipoisson]} — quasi-Poisson against negative binomial for overdispersed counts, in four pages and one figure. If your outcome is "number of third parties on the site", this decides your model.+  * **Ver Hoef & Boveng** {[verhoef2007_quasipoisson]} — quasi-Poisson against negative binomial for overdispersed counts, in seven pages. If your outcome is "number of third parties on the site", this decides your model.
   * **Mood** {[mood2010_logistic]} (European Sociological Review 2010) — "Logistic Regression: Why We Cannot Do What We Think We Can Do". Odds ratios are **not** comparable across models, across samples, or across groups, even when nothing about the effect changed. If you have ever added a control variable to a logistic model and read the change in the odds ratio as confounding, this is the paper.   * **Mood** {[mood2010_logistic]} (European Sociological Review 2010) — "Logistic Regression: Why We Cannot Do What We Think We Can Do". Odds ratios are **not** comparable across models, across samples, or across groups, even when nothing about the effect changed. If you have ever added a control variable to a logistic model and read the change in the odds ratio as confounding, this is the paper.
-  * **Barr et al.** {[barr2013_maximal]} — "Keep it maximal": which random effects to include, and why leaving one out is an anti-conservative choice rather than a neutral simplification.+  * **Barr et al.** {[barr2013_maximal]} — "Keep it maximal": which random effects to include, and why leaving one out is an anti-conservative choice rather than a neutral simplification. **Read it with its rebuttal**, Matuschek et al. {[matuschek2017_balancing]}, in the same journal four years later: maximal structures buy type-I error control at a real cost in power, and a data-supported ("parsimonious") structure is often the better trade. The two papers together are the argument; neither alone is.
   * **Bates et al.** {[bates2015_lme4]} — the ''lme4'' paper. Read it as documentation of what ''(1 | site)'' actually estimates, not as an R advertisement.   * **Bates et al.** {[bates2015_lme4]} — the ''lme4'' paper. Read it as documentation of what ''(1 | site)'' actually estimates, not as an R advertisement.
 +  * **Tang, Bauer & Christin** {[tang2025_misuse]} (SOUPS 2025) — a systematic review of 121 SOUPS papers over twenty years, coding 479 statistical assertions. Its two headline numbers are the ones this page's corpus figures corroborate for models rather than tests: //"tests in 23% of papers inadequately account for non-independence between samples"// and //"58% of papers lack information to verify whether an assertion is supported"//. SOUPS is **not** one of this corpus's seven venues, which is why it is the external anchor rather than a corpus figure.
   * **Nenadić, Rodriguez & Calandrino** {[nenadic2026_swiss]} (PoPETs 2026) — **the best worked example in this corpus of a repeated-crawl regression.** A balanced panel of 11,800 websites observed twice, a binary per-site outcome, difference-in-differences, standard errors clustered on the website, a logistic robustness check and a false-discovery-rate correction on top. See [[#What a good one looks like]].   * **Nenadić, Rodriguez & Calandrino** {[nenadic2026_swiss]} (PoPETs 2026) — **the best worked example in this corpus of a repeated-crawl regression.** A balanced panel of 11,800 websites observed twice, a binary per-site outcome, difference-in-differences, standard errors clustered on the website, a logistic robustness check and a false-discovery-rate correction on top. See [[#What a good one looks like]].
  
Line 44: Line 45:
 The corpus separates them, and the split is stark. **155 papers name a regression model in ''tools[]'' rather than ''statistics[]'', and 148 of those tuples are categorised ''ml-model-or-algorithm''.** **253 papers name one in ''statistics[]''. The two sets overlap in only 31 papers — so 124 papers use a regression purely as a classifier and never as an estimator.** If you searched the literature for "logistic regression in web measurement" and read the first ten hits, you would probably read ten baselines and learn nothing about inference. The corpus separates them, and the split is stark. **155 papers name a regression model in ''tools[]'' rather than ''statistics[]'', and 148 of those tuples are categorised ''ml-model-or-algorithm''.** **253 papers name one in ''statistics[]''. The two sets overlap in only 31 papers — so 124 papers use a regression purely as a classifier and never as an estimator.** If you searched the literature for "logistic regression in web measurement" and read the first ten hits, you would probably read ten baselines and learn nothing about inference.
  
-<wrap todo>+<WRAP todo>
 **Say which one you are doing, in the sentence that introduces the model.** "We fit a logistic regression of //banner present// on //rank, category and country// to estimate the association between …" and "we train a logistic-regression classifier as a baseline against our detector" are two different sentences, and a reader cannot tell them apart from a table of coefficients. Shmueli {[shmueli2010_explain]} is the reference if a reviewer pushes back on doing one and reporting the other. **Say which one you are doing, in the sentence that introduces the model.** "We fit a logistic regression of //banner present// on //rank, category and country// to estimate the association between …" and "we train a logistic-regression classifier as a baseline against our detector" are two different sentences, and a reader cannot tell them apart from a table of coefficients. Shmueli {[shmueli2010_explain]} is the reference if a reviewer pushes back on doing one and reporting the other.
-</wrap>+</WRAP>
  
 The rest of this page is about the first activity. Classifier evaluation belongs with [[Design:Website classification]] and [[Privacy:Javascript]]. The rest of this page is about the first activity. Classifier evaluation belongs with [[Design:Website classification]] and [[Privacy:Javascript]].
Line 52: Line 53:
 ===== Choose the Model from the Outcome, Not from Habit ===== ===== Choose the Model from the Outcome, Not from Habit =====
  
-Nearly half the regressions in this corpus are linear (187 of 391, 47.8%). Some of those outcomes are genuinely continuous — page load time, price, latency. Many are not. Butkiewicz et al. {[butkiewicz2011_website]} (IMC 2011) is the archetype of the early pattern and still a useful read: a LASSO linear regression of page load time on a set of complexity metrics that are themselves counts — number of objects, number of servers, number of origins. The response there is a duration, so linear is right; the //predictors// are counts, which is a different and much less consequential problem.+Nearly half the regressions in this corpus are linear (179 of 391, 45.8%). Some of those outcomes are genuinely continuous — page load time, price, latency. Many are not. Butkiewicz et al. {[butkiewicz2011_website]} (IMC 2011) is the archetype of the early pattern and still a useful read: a LASSO linear regression of page load time on a set of complexity metrics that are themselves counts — number of objects, number of servers, number of origins. The response there is a duration, so linear is right; the //predictors// are counts, which is a different and much less consequential problem.
  
 ==== Counts: third parties per site, requests per page, ads per video ==== ==== Counts: third parties per site, requests per page, ads per video ====
Line 59: Line 60:
  
 The specific failure is **overdispersion**. A Poisson regression assumes variance equals mean. Real tracker counts have variance many times their mean, and when that assumption breaks the model does not merely fit badly — it reports standard errors that are far too small, and rejects true nulls at a rate nothing like its nominal α. The specific failure is **overdispersion**. A Poisson regression assumes variance equals mean. Real tracker counts have variance many times their mean, and when that assumption breaks the model does not merely fit badly — it reports standard errors that are far too small, and rejects true nulls at a rate nothing like its nominal α.
 +
 +**Compute your own variance-to-mean ratio before you choose the model, and put it in the paper.** It is one line (''y.var() / y.mean()''), it decides the question, and **no paper in this corpus reports one** — which is why the ratio of 13 used below is a plausible guess rather than a measured fact about the web.
  
 Part A of the script below measures it. Both groups of sites are drawn from the **same** distribution, so every rejection is a false positive: Part A of the script below measures it. Both groups of sites are drawn from the **same** distribution, so every rejection is a false positive:
Line 74: Line 77:
      variance == mean, so it reports standard errors that are far too small and      variance == mean, so it reports standard errors that are far too small and
      rejects a true null far more often than its nominal alpha. This part      rejects a true null far more often than its nominal alpha. This part
-     measures that rate, and shows the three fixes: a negative-binomial model, +     measures that rate, and shows the fixes: a negative-binomial model, a 
-     quasi-Poisson scale correction, and heteroskedasticity-robust standard+     quasi-Poisson scale correction, and heteroskedasticity-robust standard
      errors on the Poisson fit.      errors on the Poisson fit.
 +
 +     The negative-binomial row is fitted TWICE on purpose. `sm.families.
 +     NegativeBinomial(alpha=...)` takes the dispersion as a FIXED input, so
 +     handing it the true simulated value is an oracle an analyst does not have.
 +     The second row estimates the dispersion jointly with the coefficients,
 +     which is what you actually do, and is the number to read.
  
   B. REPEATED CRAWLS OF THE SAME SITE CUT BOTH WAYS. When the same sites are   B. REPEATED CRAWLS OF THE SAME SITE CUT BOTH WAYS. When the same sites are
Line 131: Line 140:
  
     rejects = {"Poisson GLM": 0, "Poisson GLM + robust (HC0) SE": 0,     rejects = {"Poisson GLM": 0, "Poisson GLM + robust (HC0) SE": 0,
-               "quasi-Poisson (Pearson scale)": 0, "negative binomial GLM": 0}+               "quasi-Poisson (Pearson scale)": 0, 
 +               "negative binomial GLM, alpha KNOWN (oracle)": 0, 
 +               "negative binomial, alpha ESTIMATED": 0}
     for _ in range(iters):     for _ in range(iters):
         y = rng.negative_binomial(nb_n, nb_p, size=n_sites)         y = rng.negative_binomial(nb_n, nb_p, size=n_sites)
Line 146: Line 157:
         rejects["quasi-Poisson (Pearson scale)"] += qp.pvalues[1] < ALPHA         rejects["quasi-Poisson (Pearson scale)"] += qp.pvalues[1] < ALPHA
  
 +        # alpha handed in: the analyst does not know it. Kept as an upper bound
 +        # on how well a count model can possibly do here.
         nb = sm.GLM(y, X, family=sm.families.NegativeBinomial(alpha=dispersion)).fit()         nb = sm.GLM(y, X, family=sm.families.NegativeBinomial(alpha=dispersion)).fit()
-        rejects["negative binomial GLM"] += nb.pvalues[1] < ALPHA+        rejects["negative binomial GLM, alpha KNOWN (oracle)"] += nb.pvalues[1] < ALPHA
  
-    print(f"   {'model':32s} {'false positives':>16s}   (nominal {ALPHA:.0%})")+        # alpha estimated jointly with the coefficients: what you actually run. 
 +        try: 
 +            nb2 = sm.NegativeBinomial(y, X).fit(disp=0) 
 +            rejects["negative binomial, alpha ESTIMATED"] += nb2.pvalues[1] < ALPHA 
 +        except Exception:      # a non-converged fit is a result, not a crash 
 +            pass 
 + 
 +    print(f"   {'model':44s} {'false positives':>16s}   (nominal {ALPHA:.0%})")
     for k, v in rejects.items():     for k, v in rejects.items():
-        print(f"   {k:32s} {v / iters:>15.1%}")+        print(f"   {k:44s} {v / iters:>15.1%}")
     return {k: v / iters for k, v in rejects.items()}     return {k: v / iters for k, v in rejects.items()}
  
Line 256: Line 276:
    two groups drawn from that SAME distribution -> every rejection is false    two groups drawn from that SAME distribution -> every rejection is false
  
-   model                             false positives   (nominal 5%) +   model                                         false positives   (nominal 5%) 
-   Poisson GLM                                60.4% +   Poisson GLM                                            60.4% 
-   Poisson GLM + robust (HC0) SE               5.2% +   Poisson GLM + robust (HC0) SE                           5.2% 
-   quasi-Poisson (Pearson scale)               5.0% +   quasi-Poisson (Pearson scale)                           5.0% 
-   negative binomial GLM                       5.0%+   negative binomial GLM, alpha KNOWN (oracle)             5.0% 
 +   negative binomial, alpha ESTIMATED                      5.0%
 </code> </code>
  
-**A Poisson regression on counts with variance thirteen times their mean calls a null difference significant three times in five.** All three fixes work, and all three are one argument: ''sm.GLM(..., family=Poisson()).fit(cov_type="HC0")'', ''.fit(scale="X2")'' for quasi-Poisson, or ''family=NegativeBinomial()''. Ver Hoef & Boveng {[verhoef2007_quasipoisson]} is the reference for choosing between the last two — quasi-Poisson weights observations proportionally to the mean, negative binomial proportionally to the mean squared, and which is right depends on how the variance actually grows in your data.+**A Poisson regression on counts with variance thirteen times their mean calls a null difference significant three times in five.** Every fix works and each is one line: ''sm.GLM(..., family=Poisson()).fit(cov_type="HC0")'' for robust standard errors, ''.fit(scale="X2")'' for quasi-Poisson, or ''sm.NegativeBinomial(y, X).fit()'' for a negative binomial. **Note which negative-binomial call that is.** ''sm.families.NegativeBinomial(alpha=…)'' takes the dispersion as a //fixed input//, and handing it the true value is an oracle you do not have in a real analysis; ''sm.NegativeBinomial'' estimates the dispersion jointly with the coefficients, which is what you actually run. The script reports both, and here they agree at 5.0% — but the oracle row is an upper bound on how well a count model can do, not a result. Ver Hoef & Boveng {[verhoef2007_quasipoisson]} is the reference for choosing between the last two — quasi-Poisson weights observations proportionally to the mean, negative binomial proportionally to the mean squared, and which is right depends on how the variance actually grows in your data.
  
 The corpus does this rarely and lately. **17 of the 391 (4.3%) fit a count model at all, and none before 2019.** The papers that do state their reason plainly, which is why they are worth copying: The corpus does this rarely and lately. **17 of the 391 (4.3%) fit a count model at all, and none before 2019.** The papers that do state their reason plainly, which is why they are worth copying:
  
-  * Votipka et al. {[votipka2020_security]} (USENIX Sec 2020): //"This trend was uncovered by a poisson regression (appropriate for count data) we performed for issues in the Mistakes type."//+  * Votipka et al. {[votipka2020_security]} (USENIX Sec 2020): //"This trend was uncovered by a poisson regression (appropriate for count data) […] we performed for issues in the Mistakes type."// The elision is a citation marker in the original.
   * Collier et al. {[collier2019_booting]} (IMC 2019): //"We use a negative binomial rather than poisson regression model, as the events (denial of service attacks) are not independent, rather there is a simple trend to the data"//.   * Collier et al. {[collier2019_booting]} (IMC 2019): //"We use a negative binomial rather than poisson regression model, as the events (denial of service attacks) are not independent, rather there is a simple trend to the data"//.
   * Mai et al. {[mai2025_more]} (PoPETs 2025) split the choice per outcome: //"For analyses on ad load, we use Poisson regression, which is used to model count data"// for one, //"For analyses on predatory ads, we use negative binomial regression, which is the alternative to Poisson regression for data with high variances"// for the other.   * Mai et al. {[mai2025_more]} (PoPETs 2025) split the choice per outcome: //"For analyses on ad load, we use Poisson regression, which is used to model count data"// for one, //"For analyses on predatory ads, we use negative binomial regression, which is the alternative to Poisson regression for data with high variances"// for the other.
Line 273: Line 294:
   * Vu et al. {[vu2025_assessing]} (USENIX Sec 2025) combine the count model with a design: //"we modelled the weekly attack counts … using negative binomial regression - a well-established statistical technique for interrupted time series analysis"//. Weekly counts with a trend, seasonality and an intervention term is the shape of most "did the deadline change anything" questions in this field.   * Vu et al. {[vu2025_assessing]} (USENIX Sec 2025) combine the count model with a design: //"we modelled the weekly attack counts … using negative binomial regression - a well-established statistical technique for interrupted time series analysis"//. Weekly counts with a trend, seasonality and an intervention term is the shape of most "did the deadline change anything" questions in this field.
  
-<wrap todo>+<WRAP todo>
 **If your count is "how many //X// out of an opportunity that varies", you need an offset, not a ratio.** Regressing //trackers per request// or //predatory ads as a share of ads// on covariates throws away the fact that a site with 300 requests and a site with 12 give you very different amounts of information. The count model's answer is a **log offset**: put the exposure on the right-hand side with its coefficient fixed at 1. Mai et al. {[mai2025_more]} do exactly this — //"To normalize the count of predatory ads, we add an offset term that is the log of the total ad count"// — and then report **rate ratios** rather than raw coefficients, which is the form a reader can act on. One paper in 5,859 does this.((Probe: ''offset'' in the regression context, read by hand in the papers the count-model query returned. A paper could use an offset without writing the word; this is a floor.)) **If your count is "how many //X// out of an opportunity that varies", you need an offset, not a ratio.** Regressing //trackers per request// or //predatory ads as a share of ads// on covariates throws away the fact that a site with 300 requests and a site with 12 give you very different amounts of information. The count model's answer is a **log offset**: put the exposure on the right-hand side with its coefficient fixed at 1. Mai et al. {[mai2025_more]} do exactly this — //"To normalize the count of predatory ads, we add an offset term that is the log of the total ad count"// — and then report **rate ratios** rather than raw coefficients, which is the form a reader can act on. One paper in 5,859 does this.((Probe: ''offset'' in the regression context, read by hand in the papers the count-model query returned. A paper could use an offset without writing the word; this is a floor.))
-</wrap>+</WRAP>
  
 ==== Binary per-site outcomes ==== ==== Binary per-site outcomes ====
Line 283: Line 304:
 Three things to get right, none of which is about the link function. Three things to get right, none of which is about the link function.
  
-**Odds ratios are not comparable across models.** This is the one that bites. Adding a control variable to a logistic regression changes the odds ratio on your variable of interest **even when the control is unrelated to it**, because the logistic scale is fixed and adding explanatory power rescales everything. Mood {[mood2010_logistic]} is the standard citation and the recommendation is to report **average marginal effects** or **predicted probabilities** instead — quantities that live on the probability scale and mean the same thing across specifications. A full-text probe finds **20 papers in 5,869 that mention a marginal effect** and **99 that report an odds ratio**, so the field is doing the comparison-unsafe thing about five times as often as the safe one.+**Odds ratios are not comparable across models.** This is the one that bites. Adding a control variable to a logistic regression changes the odds ratio on your variable of interest **even when the control is unrelated to it**, because the logistic scale is fixed and adding explanatory power rescales everything. Mood {[mood2010_logistic]} is the standard citation and the recommendation is to report **average marginal effects** or **predicted probabilities** instead — quantities that live on the probability scale and mean the same thing across specifications. A full-text probe finds **20 papers in 5,869 that mention a marginal effect** and **100 that report an odds ratio**, so the field is doing the comparison-unsafe thing about five times as often as the safe one.
  
-**The linear probability model is a defensible choice and this literature almost never uses it.** Fitting OLS to a 0/1 outcome gives you coefficients that read directly as percentage-point changes, which is usually what you want to say, and it composes with difference-in-differences without the incomparability problem above; Angrist & Pischke {[angrist2009_mostly]} make the case. Its costs are real — predictions can leave [0,1], and the errors are heteroskedastic so you need robust standard errors — but they are costs a reviewer can evaluate. **One paper in 5,869 uses the phrase "linear probability model"**: Nenadić et al. {[nenadic2026_swiss]}, who note that with a binary outcome the OLS specification //"operates in probability space"//.+**The linear probability model is a defensible choice and this literature almost never uses it.** Fitting OLS to a 0/1 outcome gives you coefficients that read directly as percentage-point changes, which is usually what you want to say, and it composes with difference-in-differences without the incomparability problem above; Angrist & Pischke {[angrist2009_mostly]} make the case. Its costs are real — predictions can leave [0,1], and the errors are heteroskedastic so you need robust standard errors — but they are costs a reviewer can evaluate. **Two papers in 5,869 use the phrase "linear probability model"**, and only one is a web crawl: Nenadić et al. {[nenadic2026_swiss]}, who note that with a binary outcome the OLS specification //"operates in probability space"//(The other is a 2024 social-media study.)
  
 **Your sample size is the number of //events//, not the number of sites.** A crawl of 100,000 sites where 400 show the behaviour you are modelling gives a logistic regression 400 events, and the usual guidance is on the order of ten events per predictor — relaxable, but knowingly {[vittinghoff2007_relaxing]}. This is the failure mode of the rare-phenomenon paper: an enormous //n// and an unstable model. **Your sample size is the number of //events//, not the number of sites.** A crawl of 100,000 sites where 400 show the behaviour you are modelling gives a logistic regression 400 events, and the usual guidance is on the order of ten events per predictor — relaxable, but knowingly {[vittinghoff2007_relaxing]}. This is the failure mode of the rare-phenomenon paper: an enormous //n// and an unstable model.
  
-<wrap todo> +<WRAP todo> 
-**A pseudo-R² of 0.07 is not a broken model, and saying so is not a weakness.** Kieserman et al. {[kieserman2025_tracker]} fit logistic regressions on 40,150 websites to explain which ones configure Google and Meta trackers to harvest form data, and write: //"It is important to acknowledge that our models are a relatively weak fit; the former has a pseudo R-squared of 0.0721"// … //"This means that their explanatory power is limited. However, we can still draw some useful insights from them"//. They report odds ratios, //p//-values and confidence intervals per feature. That is the model to copy: an inferential regression is not judged on fit, and pretending otherwise is what leads people to report a classifier's AUC in place of a coefficient. +**A pseudo-R² of 0.07 is not a broken model, and saying so is not a weakness.** Kieserman et al. {[kieserman2025_tracker]} fit logistic regressions on 40,150 websites to explain which ones configure Google and Meta trackers to harvest form data, and write: //"It is important to acknowledge that our models are a relatively weak fit; the former has a pseudo R-squared of 0.0721"// … //"This means that their explanatory power is limited. However, we can still draw some useful insights from them"//. They report odds ratios, //p//-values and confidence intervals per feature. That is the model to copy. An inferential regression is not //primarily// judged on fit — a low pseudo-R² says the outcome has other causesnot that the coefficient is wrong — and pretending otherwise is what leads people to report a classifier's AUC in place of a coefficient. (Fit still matters when a reviewer's objection is an omitted variable; that is an argument about which covariates are in the model, not about R².) 
-</wrap>+</WRAP>
  
 ==== Proportions, rates and ordinal scales ==== ==== Proportions, rates and ordinal scales ====
  
   * **A proportion bounded in (0,1)** — share of a site's requests going to trackers, share of a page's cookies that are third-party — is not Gaussian and its variance shrinks at both ends. **Beta regression** {[ferrari2004_beta]} is the model for it; **3 papers in 5,859 use one**, all of them on social-media outcomes rather than crawl outcomes. If the proportion is a count over a known denominator, a binomial or count-with-offset model is usually better than beta regression, because it keeps the denominator.   * **A proportion bounded in (0,1)** — share of a site's requests going to trackers, share of a page's cookies that are third-party — is not Gaussian and its variance shrinks at both ends. **Beta regression** {[ferrari2004_beta]} is the model for it; **3 papers in 5,859 use one**, all of them on social-media outcomes rather than crawl outcomes. If the proportion is a count over a known denominator, a binomial or count-with-offset model is usually better than beta regression, because it keeps the denominator.
-  * **An ordinal outcome** — a Likert response, a severity band, a consent-banner "darkness" grade — should be an ordered logit or a cumulative link model, and **46 papers (11.8%) do this**, almost all of them user studies. Cumulative link mixed models (''ordinal::clmm'' in R) are the standard combination when the same participant answers several items.+  * **An ordinal outcome** — a severity band, a consent-banner "darkness" grade, a compliance level — is an ordered logit or a cumulative link model, and **46 papers (11.8%) do this**. Almost all of them are user studies scoring Likert items, so the practice and its tooling live on [[Design:User studies]]; what is worth carrying over is that a crawl'ordinal outcomes get treated as numbers far more casually than a survey's do.
   * **Time-to-event** — how long until a domain is taken down, until a vulnerability is patched, until a tracker reappears — is a Cox model, used by **7 papers (1.8%)**. If your longitudinal crawl ends before some sites have had the event, that is right-censoring, and dropping those sites or coding them as "never" both bias the answer.   * **Time-to-event** — how long until a domain is taken down, until a vulnerability is patched, until a tracker reappears — is a Cox model, used by **7 papers (1.8%)**. If your longitudinal crawl ends before some sites have had the event, that is right-censoring, and dropping those sites or coding them as "never" both bias the answer.
  
Line 333: Line 354:
 | Vetrivel et al. {[vetrivel2024_market]}, USENIX Sec 2024 | the **device type**, in a mixed-effects negative binomial model, chosen by a likelihood-ratio test | | Vetrivel et al. {[vetrivel2024_market]}, USENIX Sec 2024 | the **device type**, in a mixed-effects negative binomial model, chosen by a likelihood-ratio test |
  
-**Not one paper in the corpus fits //the site// as a random effect in a repeated crawl.** The sentence exists in this literature — Yuan et al. {[yuan2024_adversarial]} write //"We treat each participant as a random effect because the same user has viewed 15 webpages (i.e., repeated measures)"// — and it has simply never been written with "website" in it. A full-text probe finds 59 papers using the words "random effect" and 27 using "random intercept" across all 5,869 stored texts; reading the ones in crawl papers turns up participantsappsdays and devices, never sites.((Probe results are lower bounds: a paper could describe a random intercept without those words. The four crawl papers above were read individually.))+**One paper in 5,859 fits the //website// as a random effect, and it is not a crawl.** Zeng et al. {[zeng2022_factors]} (IMC 2022) recruited participants who browsed with an instrumented extension, and fitted //"a linear mixed effects model to predict rendered winning bid values"// with //"random intercepts for website, participant, bidder, and ad category"// — four crossed random effects, selected by REML AIC. It is the right model, and the website enters it because each participant saw many sites, not because the same site was crawled twice. 
 + 
 +**Not one paper fits the site as a random effect in a repeated crawl of the same sites.** The sentence exists in this literature for people — Yuan et al. {[yuan2024_adversarial]} write //"We treat each participant as a random effect because the same user has viewed 15 webpages (i.e., repeated measures)"// — and it has never been written with "website crawled twice" in it. A full-text probe finds 61 papers using the words "random effect" and 29 using "random intercept" across all 5,869 stored texts; a second probe for any random-effects phrasing within 120 characters of a site/domain/page word returns **16** papers, of which fifteen are bibliography entries"multilevel paging" and "multilevel traffic classification". Zeng et al. is the sixteenth.((Probe results are lower bounds: a paper could describe a random intercept without those words. The crawl papers above and all 16 proximity matches were read individually. The proximity probe was added after a first draft of this page claimed //no// paper models the website as a random effect — the keyword probe alone missed Zeng et al., and the claim as first written was wrong.))
  
 ==== The direction of the error depends on where your predictor varies ==== ==== The direction of the error depends on where your predictor varies ====
Line 383: Line 406:
 </WRAP> </WRAP>
  
-==== Three remedies, and which to pick ====+==== What to cluster on when there is only one crawl ==== 
 + 
 +The panel case has an obvious clustering unit: the site. A **single-wave** crawl does not, and it is the commonest design in this corpus — which makes "what do I cluster on?" the question this page is most likely to be asked and the one the literature gives least help with. **No paper in the corpus answers it.** The two crawl papers that cluster at all cluster on the product {[becerrilarreola2023_method]} and on the website across snapshots {[nenadic2026_swiss]} — and the second is a panel, so its unit is the repeated observation rather than a structural group. Nobody has clustered a single-wave crawl on anything. 
 + 
 +What you have to choose between, in rough order of how much dependence each induces and how easily you can observe it: 
 + 
 +^ Candidate cluster ^ Why sites in it move together ^ How you get it ^ 
 +| **the operator / owning entity** | one company's fifty domains are one decision about trackers | WHOIS, a public entity mapping, or the eTLD+1 of a shared login — see [[Design:Website classification]] | 
 +| **the consent platform** | a CMP's default template decides banner text, categories and pre-ticked boxes for every customer | detectable from the crawl itself; see [[Privacy:Consent]] | 
 +| **the tag manager container** | one GTM container ships the same third parties to everything it is installed on | detectable from the request graph; see [[Privacy:Requests]] | 
 +| **the CMS or site builder** | a Wix/Shopify/WordPress-plus-plugin cohort behaves as one configuration | fingerprintable from headers and paths | 
 +| **hosting / CDN / IP block** | one provider's configuration correlates rows that look unrelated | see [[Design:IP classification]] | 
 +| **the country or language of the site** | a whole legal regime, and often one national CMP vendor | see [[Design:Crawling location]] and [[Programming:Multilingual support]] | 
 + 
 +Three practical points, none of which the corpus can settle for you: 
 + 
 +  * **Cluster on the coarsest level you think the dependence lives at**, not on the one that is easiest to compute. Clustering too finely leaves the dependence in; clustering too coarsely costs precision but is not wrong. 
 +  * **You cannot cluster on two crossed dimensions with ''cov_type="cluster"''.** If you believe both the CMP and the hosting provider matter, that is two-way clustering, and ''statsmodels'' does not do it — MacKinnon et al. {[mackinnon2023_clusterrobust]} cover the estimator, and in practice people fall back to the coarser of the two. 
 +  * **Say which one you chose and why, even if the choice is arguable.** A stated clustering unit a reviewer disagrees with is a conversation; an unstated one is the 79.5%. 
 + 
 +==== Four remedies, and which to pick ====
  
 ^ Remedy ^ What it estimates ^ When it is the right one ^ Cost ^ ^ Remedy ^ What it estimates ^ When it is the right one ^ Cost ^
-| **Cluster-robust standard errors**, clustered on the site | the same coefficients; only the standard errors change | the default. You want a population-average effect and you have enough clusters | needs "enough" clusters — the usual rule of thumb is a few dozen at minimum, and web crawls have thousands {[cameron2015_practitioners]} |+| **Cluster-robust standard errors**, clustered on the site | the same coefficients; only the standard errors change | the default. You want a population-average effect and you have enough clusters | needs "enough" clusters — the usual rule of thumb is a few dozen at minimum, and web crawls have thousands {[cameron2015_practitioners]}. But **cluster //size// imbalance is its own failure mode**, and a crawl is the worst case: one tag manager on 5,000 sites and another on three. Huang {[huang2026_clusterfail]} shows the CR0 sandwich estimator misbehaves badly under that imbalance and recommends the CR2 small-sample correction; MacKinnon et al. {[mackinnon2023_clusterrobust]} recommend the wild cluster bootstrap |
 | **Random intercept for the site** (mixed model / GLMM) | a **site-specific** effect: how the outcome changes for a given site | you want to describe between-site variance itself, or you have few observations per site and want to borrow strength | for a logistic model the coefficient is no longer the population-average one, and is not comparable with a cluster-robust fit {[mood2010_logistic]} | | **Random intercept for the site** (mixed model / GLMM) | a **site-specific** effect: how the outcome changes for a given site | you want to describe between-site variance itself, or you have few observations per site and want to borrow strength | for a logistic model the coefficient is no longer the population-average one, and is not comparable with a cluster-robust fit {[mood2010_logistic]} |
 | **Fixed effects for the site** (a dummy per site) | a purely **within-site** effect | before/after with a within-site predictor and no interest in between-site comparisons | eats all site-level predictors — you cannot estimate the effect of "is a news site" | | **Fixed effects for the site** (a dummy per site) | a purely **within-site** effect | before/after with a within-site predictor and no interest in between-site comparisons | eats all site-level predictors — you cannot estimate the effect of "is a news site" |
-| **GEE with an exchangeable working correlation** | a population-average effect, like cluster-robust | you want the marginal effect and are willing to model the correlation structure | 2 papers in this corpus use one; reviewers in this field will not recognise it |+| **GEE with an exchangeable working correlation** | a population-average effect, like cluster-robust | you want the marginal effect and are willing to model the correlation structure | 2 papers in this corpus use one, so expect to have to explain it |
  
-For a crawl the honest default is **cluster-robust standard errors clustered on the site**, because it is one argument, it does not change the estimand, and thousands of clusters is exactly the regime where it works. Reach for a mixed model when the between-site variance is itself the result — "how much of the variation in tracker count is between sites rather than within them" is a mixed model's question and nothing else's. Barr et al. {[barr2013_maximal]} on which random effects to include; Moineddin et al. {[moineddin2007_simulation]} on why a mixed model with few observations per group is less well-behaved than its output suggests.+For a crawl the honest default is **cluster-robust standard errors clustered on the site**, because it is one argument, it does not change the estimand, and thousands of clusters is exactly the regime where it works. Say //which// correction you used: ''statsmodels'''s ''cov_type="cluster"'' gives you the CR0 sandwich, which is the one that degrades under unequal cluster sizes {[huang2026_clusterfail]}. Reach for a mixed model when the between-site variance is itself the result — "how much of the variation in tracker count is between sites rather than within them" is a mixed model's question and nothing else's. Barr et al. {[barr2013_maximal]} on which random effects to include; Moineddin et al. {[moineddin2007_simulation]} on why a mixed model with few observations per group is less well-behaved than its output suggests.
  
 ==== What a good one looks like ==== ==== What a good one looks like ====
Line 398: Line 441:
  
 That is five decisions a crawl paper has to make, made explicitly. It is also, as far as this corpus goes, the **only** one that makes all five. That is five decisions a crawl paper has to make, made explicitly. It is also, as far as this corpus goes, the **only** one that makes all five.
 +
 +Note the word **balanced**. Nenadić et al. analyse the 11,800 sites present in both snapshots, which is the clean case and not the usual one: a re-crawl six months later loses sites to expiry, blocking, redirection and rewritten pages. Dropping the lost sites silently turns your panel into a survivorship sample of the sites that stayed reachable, which is precisely the ones least likely to have changed. Report the attrition — how many sites entered, how many survived, and whether the survivors differ on the covariates you care about — before reporting the model. [[Statistics:Hypothesis testing#Attrition: the pairs you lose between the two crawls|The hypothesis-testing page treats attrition for paired tests]] and the argument is the same one; an unbalanced panel additionally means a mixed model and a fixed-effects model no longer answer quite the same question, because the fixed-effects fit discards every site seen once.
  
 Two 2026 near-neighbours are worth reading alongside it, both on platform data rather than crawls: Chuai et al. {[chuai2026_consensus]} fit a //"multilevel mixed-effects logistic regression"// with author- and post-level random effects and separately //"cluster robust standard errors at the note level to account for potential within-note correlations over time"//; Bobek et al. {[bobek2026_community]} run a staggered difference-in-differences with Callaway–Sant'Anna group-time treatment effects {[callaway2021_did]}, propensity-score weighting, a pre-trends test and bootstrap simultaneous confidence bands. Two 2026 near-neighbours are worth reading alongside it, both on platform data rather than crawls: Chuai et al. {[chuai2026_consensus]} fit a //"multilevel mixed-effects logistic regression"// with author- and post-level random effects and separately //"cluster robust standard errors at the note level to account for potential within-note correlations over time"//; Bobek et al. {[bobek2026_community]} run a staggered difference-in-differences with Callaway–Sant'Anna group-time treatment effects {[callaway2021_did]}, propensity-score weighting, a pre-trends test and bootstrap simultaneous confidence bands.
Line 414: Line 459:
 **The currency verdict, stated plainly.** **The currency verdict, stated plainly.**
  
-**Nothing on this page is superseded technique; the gap is adoption, not obsolescence.** Cluster-robust inference (1986), mixed models (''lme4'', 2015 for the paper, much older for the method), negative binomial regression, beta regression (2004) and the identification designs below are all long-established outside these seven venues. What dates is their **arrival** here, and every one of them arrives late.+**Nothing on this page is superseded technique; the gap is adoption, not obsolescence.** Cluster-robust inference (the sandwich estimator dates to the 1980s), mixed models (''lme4'', 2015 for the paper, much older for the method), negative binomial regression, beta regression (2004) and the identification designs below are all long-established outside these seven venues. What dates is their **arrival** here, and every one of them arrives late.
  
 **What is genuinely new in the corpus, and it is new in the last four years:** **What is genuinely new in the corpus, and it is new in the last four years:**
Line 422: Line 467:
   * **Count models.** None before 2019, 6 in 2018–2021, 5 in 2022–2024, 6 in 2025–2026*. Slowly, and from nothing.   * **Count models.** None before 2019, 6 in 2018–2021, 5 in 2022–2024, 6 in 2025–2026*. Slowly, and from nothing.
  
-**What has //not// arrived and is not close.** Site-level random effects in a crawl: zero. GEE: two papers. Zero-inflated or hurdle models for the very common "most sites have none, some have many" tracker distribution: **four papers mention zero-inflation in 5,869 full texts**, and none of the four is crawl. Reporting marginal effects instead of odds ratios: 20 papers against 99 reporting odds ratios.+**What has //not// arrived and is not close.** Site-level random effects in a crawl: zero. GEE: two papers. Zero-inflated or hurdle models for the very common "most sites have none, some have many" tracker distribution: **four papers in 5,869 full texts contain the phrase, and only two of them fit one** — a cybercrime-market study and a social-media virality study. The other two are bibliography entries (a zero-inflated Poisson paper, and the ''glmmTMB'' package paper), and one of //those// is the corpus's only crawl paper to have the phrase anywhere in it at all. Reporting marginal effects instead of odds ratios: 20 papers against 100 reporting odds ratios.
  
 **Random-effects use is rising and the rise is monotone**, so this is not a mid-window fashion: 0% of the 29 regression papers in 2010–2013, 14.0% of 50 in 2014–2017, 19.6% of 102 in 2018–2021, 21.9% of 128 in 2022–2024, 24.4% of 82 in 2025–2026*. But the growth is almost entirely in user studies; the crawl share has not moved. **Random-effects use is rising and the rise is monotone**, so this is not a mid-window fashion: 0% of the 29 regression papers in 2010–2013, 14.0% of 50 in 2014–2017, 19.6% of 102 in 2018–2021, 21.9% of 128 in 2022–2024, 24.4% of 82 in 2025–2026*. But the growth is almost entirely in user studies; the crawl share has not moved.
Line 447: Line 492:
  
 ^ Outcome family ^ Papers ^ Share of 391 ^ ^ Outcome family ^ Papers ^ Share of 391 ^
-| continuous (OLS / linear / Gaussian GLM) | 187 47.8% |+| continuous (OLS / linear / Gaussian GLM) | 179 45.8% |
 | binary (logistic / probit / linear probability) | 132 | 33.8% | | binary (logistic / probit / linear probability) | 132 | 33.8% |
 | ordinal (ordered logit / probit, cumulative link) | 46 | 11.8% | | ordinal (ordered logit / probit, cumulative link) | 46 | 11.8% |
-| **family not stated in the method name** | **33** | **8.4%** | +| **family not stated in the method name** | **42** | **10.7%** | 
-| non-linear / curve fit (power law, log-log, polynomial, exponential) | 24 6.1% |+| non-linear / curve fit (power law, log-log, polynomial, exponential) | 23 5.9% |
 | count (Poisson / negative binomial) | 17 | 4.3% | | count (Poisson / negative binomial) | 17 | 4.3% |
 | continuous, non-mean estimand (quantile / robust M) | 9 | 2.3% | | continuous, non-mean estimand (quantile / robust M) | 9 | 2.3% |
Line 466: Line 511:
 ''statistics[].method'' agrees run-to-run on roughly a fifth of exact strings, so it cannot be ranked as written. But the deeper problem is that ranking it at all is the wrong operation. "Mixed-effects logistic regression" is not a sibling of "logistic regression" and a cousin of "OLS"; it is **binary outcome + random effects + associational**, and each of those three answers a different question a reader has. A single ranked list of names cannot show that 79.5% of papers handle dependence in no way at all, because that fact is spread across every name in the list. ''statistics[].method'' agrees run-to-run on roughly a fifth of exact strings, so it cannot be ranked as written. But the deeper problem is that ranking it at all is the wrong operation. "Mixed-effects logistic regression" is not a sibling of "logistic regression" and a cousin of "OLS"; it is **binary outcome + random effects + associational**, and each of those three answers a different question a reader has. A single ranked list of names cannot show that 79.5% of papers handle dependence in no way at all, because that fact is spread across every name in the list.
  
-The fold therefore assigns each method string a value on three independent axes — outcome family, dependence handling, identification strategy — with first-match-wins rules whose order is load-bearing. "Ordinal logistic" must beat "logistic", "quasi-Poisson" must beat "Poisson", "generalized least squares" must not be swallowed by "least squares", and the not-a-regression rules must fire before everything. The unmapped residue is **0 strings**, but only because a catch-all rule collects regression-shaped strings that name no outcome family; those 33 papers are reported as their own row above and printed in full on [[provenance:statistics:regression]] rather than being folded into "continuous".+The fold therefore assigns each method string a value on three independent axes — outcome family, dependence handling, identification strategy — with first-match-wins rules whose order is load-bearing. "Ordinal logistic" must beat "logistic", "quasi-Poisson" must beat "Poisson", "generalized least squares" must not be swallowed by "least squares", and the not-a-regression rules must fire before everything. The unmapped residue is **0 strings**, but only because a catch-all rule collects regression-shaped strings that name no outcome family; those 42 papers are reported as their own row above and printed in full on [[provenance:statistics:regression]] rather than being folded into "continuous". Getting that boundary right took a review: an earlier version of the fold matched ''\blinear\b'', which quietly swallowed every bare "generalized **linear** mixed model" into the Gaussian family — including one whose own reported detail was //"binary Decision outcome"// and one that reports odds ratios.
  
 ==== Dependence and identification ==== ==== Dependence and identification ====
  
-^ Dependence handling ^ Papers ^ Share of 391 ^ +The dependence table is [[#What the corpus does about it|above]] and is not repeated hereTwo notes on how to read it.
-| none stated in the method name 311 | 79.5% | +
-| random effects (mixed-effects / multilevel) | 75 | 19.2% | +
-| robust (heteroskedasticity-consistent) SEs only | 3 | 0.8% | +
-| fixed effects for the unit | 3 | 0.8% | +
-| GEE (population-averaged) | 2 | 0.5% | +
-| "repeated-measures" with no random effect named | 1 | 0.3% | +
-| cluster-robust standard errors | 1 | 0.3% |+
  
 ''cluster-robust'' and ''robust'' are separated on purpose. Heteroskedasticity-consistent (HC / White / Huber) standard errors fix a variance assumption; they do nothing whatever about correlated rows. Merging the two rows would let three papers that hardened against heteroskedasticity read as papers that handled dependence. ''cluster-robust'' and ''robust'' are separated on purpose. Heteroskedasticity-consistent (HC / White / Huber) standard errors fix a variance assumption; they do nothing whatever about correlated rows. Merging the two rows would let three papers that hardened against heteroskedasticity read as papers that handled dependence.
  
 The fold reads the **method string**, so this row is a floor: Chuai et al. {[chuai2026_consensus]} appear here under "robust" because that is what their regression tuples say, while the paper separately states that it clusters at the note level. The full-text probe below is the check on that, and it finds four clustering papers where the fold finds one. The fold reads the **method string**, so this row is a floor: Chuai et al. {[chuai2026_consensus]} appear here under "robust" because that is what their regression tuples say, while the paper separately states that it clusters at the note level. The full-text probe below is the check on that, and it finds four clustering papers where the fold finds one.
 +
 +Rows in both tables below overlap and neither sums to 391: **19 of the 391 have no tuple the fold could place as a model at all**, so they get no dependence or identification value, and a paper fitting two models can appear in two rows. The 372 papers that do have a placeable model produce 396 axis-2 and 377 axis-3 row memberships.
  
 ^ Identification strategy ^ Papers ^ Share of 391 ^ ^ Identification strategy ^ Papers ^ Share of 391 ^
Line 497: Line 537:
  
 ^ Of the 62 crawl-and-regression papers ^ Papers ^ Share of 62 ^ ^ Of the 62 crawl-and-regression papers ^ Papers ^ Share of 62 ^
-| continuous (OLS / linear) | 29 46.8% |+| continuous (OLS / linear) | 28 45.2% |
 | binary (logistic / probit / LPM) | 20 | 32.3% | | binary (logistic / probit / LPM) | 20 | 32.3% |
 | **count (Poisson / negative binomial)** | **7** | **11.3%** | | **count (Poisson / negative binomial)** | **7** | **11.3%** |
 | non-linear / curve fit | 4 | 6.5% | | non-linear / curve fit | 4 | 6.5% |
 +| family not stated in the method name | 4 | 6.5% |
 | time-to-event | 3 | 4.8% | | time-to-event | 3 | 4.8% |
 | ordinal | 2 | 3.2% | | ordinal | 2 | 3.2% |
 +| continuous, non-mean estimand (quantile / robust M) | 1 | 1.6% |
 +| multinomial / discrete choice | 1 | 1.6% |
 +| proportion (beta regression) | 1 | 1.6% |
 | —— | | | | —— | | |
 | **no dependence handling named** | **54** | **87.1%** | | **no dependence handling named** | **54** | **87.1%** |
Line 510: Line 554:
 | fixed effects | 1 | 1.6% | | fixed effects | 1 | 1.6% |
  
-Crawl papers are **more** likely to fit a count model than the regression population as a whole (11.3% against 4.3%), which is what you would expect given what they measure, and **less** likely to do anything about dependence (87.1% silent against 79.5%), which is the opposite of what the data structure warrants. **One crawl paper in 1,120 states that it clusters its standard errors.**+The dependence rows sum to 61, not 62: two of the 62 have no placeable model and one of those has no dependence value either. 
 + 
 +Crawl papers are **more** likely to fit a count model than the regression population as a whole (11.3% against 4.3%), which is what you would expect given what they measure, and **less** likely to do anything about dependence (87.1% silent against 79.5%), which is the opposite of what the data structure warrants. **Two crawl papers in 1,120 cluster their standard errors** — Becerril-Arreola {[becerrilarreola2023_method]}, who says so in the method the extraction captured, and Nenadić et al. {[nenadic2026_swiss]}, who say so only in prose, which is why this table counts one and the full-text probe below counts two.
  
 ^ Bucket ^ Crawl papers in corpus ^ … that ran a regression ^ Share ^ ^ Bucket ^ Crawl papers in corpus ^ … that ran a regression ^ Share ^
Line 521: Line 567:
 ==== What goes unreported ==== ==== What goes unreported ====
  
-  * **33 of the 391 (8.4%) name a regression without naming its outcome family** — "multivariate regression", "regression analysis", "hierarchical multiple regression", "elastic net". A reader cannot tell whether the outcome was continuous or binary.+  * **42 of the 391 (10.7%) name a regression without naming its outcome family** — "multivariate regression", "regression analysis", "hierarchical multiple regression", "elastic net", and every bare "generalized linear mixed model", which names a //framework// and not a distribution. A reader cannot tell whether the outcome was continuous or binary.
   * **99 of the 391 (25.3%) use a bare "regression" or "regression analysis"** as at least one of their method strings, whether or not they are more specific elsewhere.   * **99 of the 391 (25.3%) use a bare "regression" or "regression analysis"** as at least one of their method strings, whether or not they are more specific elsewhere.
   * **19 papers (4.9%) have regression tuples that name no model this fold could place at all** — the tuple names an AIC criterion, a path analysis or "regression test" and nothing else.   * **19 papers (4.9%) have regression tuples that name no model this fold could place at all** — the tuple names an AIC criterion, a path analysis or "regression test" and nothing else.
-  * **311 of the 391 (79.5%) say nothing about dependence** in the method name. This is a bound, not a rate: the extraction records the method string, and a paper could describe clustering in prose that never reached a tuple. The full-text probe is the check on that, and it agrees — 4 papers cluster, 59 use the words "random effect".+  * **311 of the 391 (79.5%) say nothing about dependence** in the method name. This is a bound, not a rate: the extraction records the method string, and a paper could describe clustering in prose that never reached a tuple. The full-text probe is the check on that, and it agrees — 4 papers cluster, 61 use the words "random effect".
  
 ^ Full-text probe across 5,869 stored papers ^ Papers matching ^ ^ Full-text probe across 5,869 stored papers ^ Papers matching ^
-| "odds ratio" | 99 +| "odds ratio" | 100 
-| "random effect"59 |+| "random effect"61 | 
 +| "random intercept" | 29 |
 | "variance inflation factor" / VIF | 27 | | "variance inflation factor" / VIF | 27 |
-| "random intercept" | 27 | 
 | "marginal effect" | 20 | | "marginal effect" | 20 |
 | "difference-in-differences" | 11 | | "difference-in-differences" | 11 |
Line 539: Line 585:
 | "zero-inflated" | 4 | | "zero-inflated" | 4 |
 | generalised estimating equations | 2 | | generalised estimating equations | 2 |
-| "linear probability model" | |+| "linear probability model" | |
  
-Every probe is a **lower bound**: a paper can describe the same thing in different words and the probe will miss it. They are here because they are an independent check on the tuple-based counts, computed from the same text the extractor read.+Every probe is a **lower bound**: a paper can describe the same thing in different words and the probe will miss it. They are here because they are an independent check on the tuple-based counts, computed from the same text the extractor read, with **whitespace collapsed first** — a PDF line break falls inside a two-word phrase often enough to matter, and collapsing it moved four of these counts.
  
 ==== Methodology and limitations of these figures ==== ==== Methodology and limitations of these figures ====
  
-  * **The fold is a three-axis rule list with a printed residue of 0**, and the catch-all that makes it 0 is itself reported as a row (33 papers) and printed in full on the provenance page. Reading a catch-all as an answer is the failure mode this avoids.+  * **The fold is a three-axis rule list with a printed residue of 0**, and the catch-all that makes it 0 is itself reported as a row (42 papers) and printed in full on the provenance page. Reading a catch-all as an answer is the failure mode this avoids.
   * **Non-regressions are excluded, not silently dropped.** 37 papers whose ''regression'' tuples name AIC, VIF, SEM, latent class analysis or a decision tree are counted separately.   * **Non-regressions are excluded, not silently dropped.** 37 papers whose ''regression'' tuples name AIC, VIF, SEM, latent class analysis or a decision tree are counted separately.
   * **A paper counts once**, never once per mention. 530 tuples across 391 papers.   * **A paper counts once**, never once per mention. 530 tuples across 391 papers.
Line 553: Line 599:
   * **The ''detail'' field is not a measurement of reporting practice.** It is a capped free-text field the extractor filled when a value happened to be in the quoted sentence. Counts of R², CIs and //p//-values inside it establish an ordering and nothing more.   * **The ''detail'' field is not a measurement of reporting practice.** It is a capped free-text field the extractor filled when a value happened to be in the quoted sentence. Counts of R², CIs and //p//-values inside it establish an ordering and nothing more.
   * **The simulation is synthetic and its numbers are properties of the estimators**, not facts about the web. The intra-class correlation and the overdispersion used were chosen to be plausible, and no paper in this corpus reports either quantity for a real crawl — which is itself an open question below.   * **The simulation is synthetic and its numbers are properties of the estimators**, not facts about the web. The intra-class correlation and the overdispersion used were chosen to be plausible, and no paper in this corpus reports either quantity for a real crawl — which is itself an open question below.
-  * **Venue coverage.** Seven venues. EuroS&P, ACSAC, RAID, AsiaCCS, WPES, CHI and SOUPS are absent. SOUPS matters most here for the same reason as on [[Statistics:Hypothesis testing]]: it is where the most careful modelling in this community appears, and it is out of scope. Every claim on this page is a claim about those seven venues.+  * **Venue coverage.** Seven venues. EuroS&P, ACSAC, RAID, AsiaCCS, WPES, CHI and SOUPS are absent. SOUPS matters most here for the same reason as on [[Statistics:Hypothesis testing]]: it is where the most careful modelling in this community appears, and it is out of scope. Tang et al. {[tang2025_misuse]} audit exactly that venue and find 23% of papers mishandling non-independence — a figure this corpus cannot produce for its own seven venues, because the extraction records what a paper //says// it did and not whether the model was right. Every claim on this page is a claim about those seven venues.
   * **2025 and 2026 are provisional.** See the currency box.   * **2025 and 2026 are provisional.** See the currency box.
-  * **Every external reference was verified against a primary record on 2026-08-19**, not recalled: eleven DOIs through the Crossref API, plus the Project Euclid record for the Shmueli pagination. The full query log, the fold's residue and the rejected sources are on [[provenance:statistics:regression]]; corpus-level caveats are on [[Literature:Corpus]].+  * **Every external reference was verified against a primary record on 2026-08-19**, not recalled: fifteen methodological works and every corpus DOI through the Crossref API, plus the Project Euclid record for the Shmueli pagination and the Cambridge Core listing for //Regression and Other Stories//. The full query log, the fold's residue and the rejected sources are on [[provenance:statistics:regression]]; corpus-level caveats are on [[Literature:Corpus]].
  
 ===== What to Report ===== ===== What to Report =====
Line 572: Line 618:
 ===== Open Questions ===== ===== Open Questions =====
  
 +<WRAP todo>
   * **Nobody has estimated the intra-class correlation of a web-measurement outcome.** The simulation on this page shows the entire size of the error depends on it, and no paper in this corpus reports one. "What is the ICC of //sets a third-party cookie before consent// by consent platform, by CMS, by hosting provider, and by the same site across monthly crawls?" is a small, self-contained study that would tell every crawl paper how wrong its standard errors are. The same gap is open on [[Statistics:Hypothesis testing]] and it is one study away from being closed for both.   * **Nobody has estimated the intra-class correlation of a web-measurement outcome.** The simulation on this page shows the entire size of the error depends on it, and no paper in this corpus reports one. "What is the ICC of //sets a third-party cookie before consent// by consent platform, by CMS, by hosting provider, and by the same site across monthly crawls?" is a small, self-contained study that would tell every crawl paper how wrong its standard errors are. The same gap is open on [[Statistics:Hypothesis testing]] and it is one study away from being closed for both.
-  * **No crawl paper models the site as a random effect.** Whether that is because cluster-robust standard errors are the better tool anyway (they usually are), or because nobody has tried, is not answerable from text. Somebody should re-analyse a published longitudinal crawl both ways and report how much moves.+  * **No crawl paper models the site as a random effect.** One non-crawl field study does {[zeng2022_factors]}, so the technique is not unknown in this community — it has just never been pointed at a repeated crawl. Whether that is because cluster-robust standard errors are the better tool anyway (they usually are), or because nobody has tried, is not answerable from text. Somebody should re-analyse a published longitudinal crawl both ways and report how much moves.
   * **Nobody has published the overdispersion of a tracker count.** Six papers in 5,869 use the word. The variance-to-mean ratio of "third parties per site" on a Tranco sample is a number that would settle the Poisson-versus-negative-binomial question for the whole field, and it fits in a footnote.   * **Nobody has published the overdispersion of a tracker count.** Six papers in 5,869 use the word. The variance-to-mean ratio of "third parties per site" on a Tranco sample is a number that would settle the Poisson-versus-negative-binomial question for the whole field, and it fits in a footnote.
-  * **Zero-inflated and hurdle models have no presence at all**, despite the tracker-count distribution being the textbook motivating example — a large mass at zero and a long tail. Four papers mention zero-inflation and none is a crawl.+  * **Zero-inflated and hurdle models have no presence at all**, despite the tracker-count distribution being the textbook motivating example — a large mass at zero and a long tail. Four papers in 5,869 contain the phrase and only two fit one; neither of the two is a crawl.
   * **The 2022-onward arrival of causal designs is ten papers.** Whether it is a durable turn or a handful of authors with economics training is not decidable yet, and the 2025–2026 evidence for it sits in the provisional years.   * **The 2022-onward arrival of causal designs is ten papers.** Whether it is a durable turn or a handful of authors with economics training is not decidable yet, and the 2025–2026 evidence for it sits in the provisional years.
   * **None of the seven venues asks for any of this.** As on [[Statistics:Hypothesis testing]], the calls for papers contain no statistical-reporting requirement, so the only thing holding a regression section to a standard is an individual reviewer.   * **None of the seven venues asks for any of this.** As on [[Statistics:Hypothesis testing]], the calls for papers contain no statistical-reporting requirement, so the only thing holding a regression section to a standard is an individual reviewer.
 +</WRAP>
 ===== Related Pages ===== ===== Related Pages =====
  
statistics/regression.1787161774.txt.gz · Last modified: by karel.kubicek.claude

Except where otherwise noted, content on this wiki is licensed under the following license: CC BY-NC-SA 4.0
CC BY-NC-SA 4.0 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki