Skip to contents

“Equations from District 7. Linear models for people the algorithm forgot.”

RougeLM is an R package providing datasets and utilities for teaching linear models in the context of the BetaBit StatPunk universe — a cyberpunk dystopia set in WaszKrak megapolis, 2047, where every citizen is reduced to a number by the LifeCalc algorithm.

The package is a companion to the book “Equations from District 7: A Practical Guide to Linear Models”.


Installation

# From GitHub (development version)
# install.packages("remotes")
remotes::install_github("BetaAndBit/RougeLM")

Datasets

Dataset Description n Variables
lifecalc LifeCalc social scoring — multicollinearity & regularisation 5,000 25

lifecalc

A simulated dataset of 5,000 WaszKrak residents scored by the fictional LifeCalc algorithm. The outcome variable SocialScore is generated by a sparse true model:

SocialScore ≈ 0.40 × DistrictScore
             − 16   × prior_flag
             − 3.5  × gender
             + 0.18 × EmploymentScore
             + 0.12 × EducationScore
             + 0.10 × MedicalScore
             + ...
             + ε

The remaining 17 variables are correlated proxies organised into four clusters — education, employment, health, behaviour — that introduce structured multicollinearity. The dataset is designed for:

  • Demonstrating VIF and the cost of multicollinearity
  • Comparing AIC and BIC for model selection
  • Showing how LASSO recovers the sparse true model
  • Contrasting LASSO and Ridge regularisation

Usage

library(RougeLM)
library(glmnet)

data(lifecalc)

# 1. Check correlation clusters
lifecalc_cor_clusters(lifecalc)

# 2. Full OLS — inflated standard errors from multicollinearity
model_full <- lm(SocialScore ~ ., data = lifecalc)
summary(model_full)

# 3. VIF diagnostic
lifecalc_vif(lifecalc)

# 4. LASSO — recover the sparse true model
X  <- model.matrix(SocialScore ~ ., data = lifecalc)[, -1]
y  <- lifecalc$SocialScore
cv <- cv.glmnet(X, y, alpha = 1, nfolds = 10)

# Which variables survive?
coef(cv, s = "lambda.min")

# 5. Ridge — all variables retained, coefficients shrunk
cv_ridge <- cv.glmnet(X, y, alpha = 0, nfolds = 10)
coef(cv_ridge, s = "lambda.min")

Variable clusters

DistrictScore  ──────────────────────────────────────────────── SocialScore
prior_flag     ──────────────────────────────────────────────── (dominant)
               │
               ├── Education: EducationScore, LiteracyScore,
               │              CuriosityScore, VerificationScore
               │
               ├── Employment: EmploymentScore, NetworkScore,
               │               ConsumptionScore, MobilityScore
               │
               ├── Health: MedicalScore, SleepScore, RecoveryScore,
               │           NutritionScore, StressIndex,
               │           GeneticRiskScore, ChronicLoadScore
               │
               └── Behaviour: ComplianceScore, NarrativeScore,
                              RoutineScore, AttentionScore,
                              DisplacementScore

Functions

Function Description
generate_lifecalc(n, seed) Regenerate the dataset with custom size and seed
lifecalc_cor_clusters(data) Tidy correlation summary by cluster
lifecalc_vif(data) VIF table for the full OLS model

The BetaBit universe

Beta and Bit are statistical Robin Hoods in a world where data is power.

“We’re poor but we have something most data scientists don’t.” “What?” “The ability to look in a mirror without disgust.”

The lifecalc dataset recreates the data they spent a year collecting — one subscore at a time — before Ghost gave them the full model and they finally understood what they had been looking at.

prior_flag coefficient: −16. The most important feature in the model. Set before you were born. Non-reversible.


License

MIT © Beta & Bit Collective