Statistical Modeling logo

Statistical Modeling

Community
WalrusQuant
statistical-modeling

Guided statistical modeling for user-provided sports data: selecting models for binary, continuous, and count outcomes; assumption checks; effect sizes; time-aware inference; GLM diagnostics; and complete reporting.

Overview

PublisherWalrusQuant
Repositorysports-analytic-skills
Skill namestatistical-modeling
Stars
53
Forks
4
Bundled files
9
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 9 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by WalrusQuant on GitHub. Read the source before you install it.

Installation

Install the Statistical Modeling AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/WalrusQuant/sports-analytic-skills/tree/main/skills/statistical-modeling
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/WalrusQuant/sports-analytic-skills.git /tmp/sports-analytic-skills
mkdir -p .claude/skills
cp -r /tmp/sports-analytic-skills/skills/statistical-modeling .claude/skills/statistical-modeling
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Statistical Modeling in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Statistical Modeling on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Statistical Modeling is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Statistical Modeling for Sports

Overview

This skill's job is classical statistical inference on a user-owned sports table: choose a GLM or test, check assumptions, report effects and uncertainty.

It is not a universal modeling workflow. Do not use it to load data, design walk-forward ML horse races, or certify leakage. Mixed, Bayesian, causal, and power-analysis material below is routed methodology — the bundled scripts only cover univariate assumption checks and an additive numeric binomial GLM.

Conduct the analysis the way a careful analyst would: right model family for the outcome, verified assumptions, honest effect sizes and uncertainty, and a write-up that survives review.

Typical stack: pandas, numpy, scipy, statsmodels, and scikit-learn (+ optional pingouin, seaborn, pymc, and arviz).

When to Use This Skill

Use this skill when:

  • Modeling win/loss, margins, points, goals, runs, or other sports outcomes
  • Comparing groups (home vs away, pre/post rule change, position groups)
  • Fitting logistic, linear, Poisson, or NegBin models on sports panels
  • Checking residual diagnostics and reporting effects with uncertainty
  • After the GLM path, clustered or partially pooled effects (see hierarchical section)
  • Reporting coefficients, odds ratios, effect sizes, and model fit
  • Choosing between classical stats models and jumping to ML

Do not use this skill as a substitute for:

  • raw data loading → use the appropriate loader skill, then return with a user-owned analysis table
  • pure EDA → eda-sports
  • walk-forward ML horse races → predictive-modeling
  • leakage review of feature pipelines → leakage-audit
  • rating systems as the primary object → ratings-strength-models

Installation

Install only the libraries required by the chosen analysis:

bash
python -m pip install pandas numpy scipy statsmodels scikit-learn
# Optional richer classical statistics and plots:
python -m pip install "pingouin>=0.6" "seaborn>=0.13"
# Optional Bayesian hierarchical work:
python -m pip install pymc arviz

Parquet input to the bundled helpers also needs pyarrow or fastparquet.

Compatibility notes:

  • Prefer statsmodels>=0.14 with a recent SciPy.
  • Pingouin 0.6+ uses p_val, cohen_d, and CI95.
  • Read bayesian_statistics.md before selecting Bayesian priors or diagnostics.

Analysis Workflow

Every sound sports statistical analysis follows this arc. Do not skip.

  1. Frame the question before fitting.

    • Outcome (win, margin, goals, player stat)
    • Predictors known at decision time T (if predictive)
    • Unit of analysis (game, team-game, player-game, possession)
    • Estimand: description, prediction, or causal claim (most sports work is predictive/descriptive)
  2. Inspect the data (eda-sports).

    • n by season/group
    • missingness
    • score distributions, zero inflation, outliers
    • home/away balance
  3. Choose the model family using the selection guide below (and references/test_selection_guide.md + references/sports_glm_guide.md).

  4. Enforce time safety for predictive work.

    • Features must be knowable at T
    • Use walk-forward validation (validation-design)
  5. Fit a minimal model first.

    • home indicator + one strength feature beats a kitchen sink
  6. Check assumptions / diagnostics.

    • Use scripts/assumption_checks.py and scripts/glm_diagnostics.py
    • residual plots, overdispersion, leverage, calibration for probabilities
  7. Compare to baselines.

    • constant rate, home-only, simple rating differential (baseline-models)
  8. Report completely.

    • family, formula, n, metrics, coefficients with uncertainty, limits
    • templates in references/reporting_standards.md + sports templates below

If the user only needs one step (e.g. “is home advantage real in this sample?”), jump to that section — but still state design assumptions.

Reference routing:


Model Selection Guide (Sports)

Binary outcomes (win/loss, threshold events)

SituationModel
Independent game outcomes, linear log-odds in featuresLogistic regression (statsmodels GLM Binomial or sklearn)
Clustered games within season/teamCluster-robust SE or mixed effects logistic
Severe separation / rare eventsFirth/penalized logistic, or careful Bayesian prior

Continuous outcomes (margin, rating residual)

SituationModel
Roughly symmetric marginsOLS / Gaussian GLM
Heavy tailsHuber robust regression, Student-t likelihood (Bayesian)
HeteroscedasticityHC3 robust SE, WLS

Counts (goals, runs, sacks, threes made)

SituationModel
Mean ≈ variancePoisson GLM
Over-dispersedNegative Binomial
Excess zerosHurdle / zero-inflated models

Ordered outcomes (win/draw/loss)

  • Proportional odds / ordered logit
  • Or two-stage: draw model + conditional direction

Hierarchical structure

  • Team strength as random intercepts
  • Pitcher/batter, goalie, QB effects with partial pooling
  • Prefer partial pooling over dummy-every-player with tiny n

Group comparisons (not full predictive models)

DesignStart here
Two independent groups, continuousWelch t-test / Mann-Whitney
Paired (same team pre/post)Paired t / Wilcoxon
3+ groupsANOVA / Kruskal-Wallis
Association of two continuousPearson / Spearman
See full treereferences/test_selection_guide.md

Worked Path on a User-Provided Team-Game Table

Start with one row per evaluated decision and document whether that means one row per game or one row per team-game. A useful binary-outcome frame contains:

FieldRole
season, event_time, stable IDschronology and alignment
wonbinary outcome
is_homepre-event context
rating_diff, rest_difflegal pre-event predictors
fold or test-season labelevaluation provenance

For symmetric team-game data, either model both perspectives with dependence-aware uncertainty or select one perspective per game. Never treat doubled rows as independent evidence.

Logistic model with robust inference

python
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf

train = model_df[model_df["season"] < 2024].copy()
fit = smf.glm(
    "won ~ is_home + rating_diff + rest_diff",
    data=train,
    family=sm.families.Binomial(),
).fit(cov_type="HC3")

odds_ratios = np.exp(fit.params)
odds_ratio_ci = np.exp(fit.conf_int())
print(fit.summary())
print(odds_ratios)
print(odds_ratio_ci)

HC3 is useful for heteroskedasticity but does not solve team, player, or temporal dependence. Use cluster-robust uncertainty or a hierarchical model when the sampling structure requires it.

Margin model

python
home = train[train["is_home"] == 1].copy()  # one row per game
margin_fit = smf.ols(
    "point_margin ~ rating_diff + rest_diff",
    data=home,
).fit(cov_type="HC3")
print(margin_fit.summary())

Inspect residual shape, changing variance, influential games, and nonlinear patterns. If the scientific question concerns an average contrast rather than a conditional linear effect, report that estimand directly too.

Count model

python
poisson_fit = smf.glm(
    "points_for ~ is_home + rating_diff",
    data=train,
    family=sm.families.Poisson(),
).fit()
dispersion = poisson_fit.pearson_chi2 / poisson_fit.df_resid
print(poisson_fit.summary())
print("Pearson dispersion:", dispersion)

Material overdispersion, excess zeros, or correlated paired scores can require a negative-binomial, hurdle/zero-inflated, or joint score model. Select that extension from diagnostics and the data-generating process—not a better-looking p-value.

Predictive evaluation

Freeze expanding time folds before fitting. Within each fold, estimate every transform and model on earlier rows only; score the later block against a training-rate constant and a simple legal-feature baseline. Report every fold, not only the mean.

For a standalone additive binomial diagnostic report:

bash
python /path/to/statistical-modeling/scripts/glm_diagnostics.py \
  --input model_frame.csv \
  --formula "won ~ is_home + rating_diff + rest_diff" \
  --out glm_report.json

The helper reports HC3 inference, odds ratios, intervals, AIC, and in-sample calibration bins. Those bins diagnose fit; they are not held-out evidence.


Assumption Checks & Diagnostics

Always check assumptions before interpreting, and report the checks.

Standalone assumption checks

bash
python /path/to/statistical-modeling/scripts/assumption_checks.py \
  --input observations.csv --value-col margin \
  --group-col venue --out assumptions.json

The helper reports Shapiro-Wilk normality, IQR outliers, and optional median-centered Levene variance testing. Formal tests supplement plots and domain judgment; at large sample sizes they can reject practically harmless departures.

Standalone binomial GLM diagnostics

bash
python /path/to/statistical-modeling/scripts/glm_diagnostics.py \
  --input model_frame.csv \
  --formula "won ~ is_home + rating_diff + rest_diff" \
  --out glm_report.json

Inputs may be CSV, Parquet, JSON, JSONL, or NDJSON. Formulas support additive numeric predictors joined by +; use --outcome-col when the binary target is not won.

What to check by family

Logistic / classification

  • separation / extreme coefficients
  • probability calibration (calibration-check)
  • influential games (high leverage matchups)
  • stability across seasons

Gaussian margin models

  • residual vs fitted curvature
  • QQ plot of residuals
  • residual variance by season or predicted mean
  • inspect influence and leverage with the fitted library's diagnostics (for example, statsmodels OLSInfluence), and use Breusch-Pagan or another predeclared variance check when appropriate

The bundled glm_diagnostics.py fits only additive numeric binomial GLMs. It does not diagnose OLS, Poisson, negative-binomial, mixed, or Bayesian models; use the model library's diagnostics and the linked checklist for those families.

Poisson scoring models

  • overdispersion: Pearson χ² / df >> 1 → NegBin
  • excess zeros

All predictive sports models

  • leakage: any feature using same-game outcomes?
  • temporal drift: does 2019 model die in 2024?

See references/assumptions_and_diagnostics.md and references/diagnostics_checklist.md.


Effect Sizes & Metrics (Sports Defaults)

p-values are usually the wrong headline for predictive sports work. Prefer:

GoalPrimary metrics
Probability modelslog-loss, Brier, calibration curves
Binary decisionsaccuracy only as secondary; care about base rates
MarginsMAE, RMSE, residual SD
CountsMAE, Poisson deviance
Group differences (explanatory)Cohen's d, risk difference, odds ratios + CIs

Odds ratio from logistic coefficient:

python
import numpy as np
or_home = np.exp(fit.params["is_home"])
ci = np.exp(fit.conf_int().loc["is_home"])
print(or_home, ci.tolist())

For classical effect size tables, power analysis, and CI methods, use references/effect_sizes_and_power.md and pingouin:

python
import pingouin as pg
# home vs away margins on home-row frame already encodes home perspective;
# example two-sample on a continuous player metric:
# pg.ttest(group_a, group_b, correction='auto')  # returns cohen_d, CI95, etc.

Hierarchical / Partial Pooling Patterns

Read this section when the estimand is a clustered or partially pooled effect. This is not the default path of the skill, and there is no bundled mixed-model helper. Prefer the GLM/test workflow above unless grouping structure is the question.

When player or team n is uneven, complete-pooling (ignore groups) and no-pooling (dummy each group) both fail. Partial pooling is the default serious approach.

python
import statsmodels.formula.api as smf
# Mixed LM example for continuous margin; requires sufficient group size
md = smf.mixedlm("point_diff ~ is_home", data=train, groups=train["team"])
mdf = md.fit()
print(mdf.summary())

For full Bayesian hierarchical rating models, keep priors explicit and report posterior predictive checks — see references/bayesian_statistics.md.


Group Comparison Examples (Sports)

Home advantage on margins (home rows)

python
home = panel.loc[panel["is_home"].eq(1), ["season", "point_diff"]].dropna()
print(home["point_diff"].describe())  # pooled descriptive game-weighted mean
print(home.groupby("season")["point_diff"].agg(["count", "mean", "std"]))

Do not attach an ordinary one-sample t-test to clustered team/season data by default. Choose the uncertainty method from the sampling structure: a season-block bootstrap for a game-weighted mean, an equal-season estimand on season summaries when seasons are the independent units, or a model with defensible cluster/hierarchical structure. Games connect two teams, so a one-way team cluster can also be inadequate. State the estimand and number of independent clusters; with few clusters, use small-sample-aware methods and weaken the claim.

Correlation: pre-game form vs margin

python
required = {"pre_form_diff", "point_diff"}
missing = required.difference(panel.columns)
if missing:
    raise ValueError(f"build and join legal pre-game form columns first: {sorted(missing)}")
feat = panel.dropna(subset=["pre_form_diff", "point_diff"])
print(pg.corr(feat["pre_form_diff"], feat["point_diff"], method="pearson"))
print(pg.corr(feat["pre_form_diff"], feat["point_diff"], method="spearman"))

The example assumes pre_form_diff was created outside this skill with an as-of/shifted feature workflow such as time-series-sports; no bundled add_pregame_form_features function exists.

Always state that observational sports associations are not automatically causal.


Reporting Templates (Sports)

Predictive logistic win model

text
Question: Pre-game P(team win) on NFL team-game panel, seasons S0–S1.
Unit: team-game. Decision time: scheduled kickoff.
Model: logistic GLM with HC3 SE.
Formula: won ~ is_home + rating_diff + pre_form_diff
Features: all declared pre-event predictors, with construction and as-of timing documented.
Validation: walk-forward by season; train on past seasons only.
Baselines: constant train win rate; home-only logistic optional.
Results: mean walk-forward log-loss = X.XXX vs constant Y.YYY; accuracy Z.ZZ.
Coefficients (train window): is_home OR=… (95% CI …); …
Diagnostics: …; calibration: …
Limits: no opponent-adjusted EPA; roster/injury not modeled; team renames handled by raw abbreviations.

Explanatory home-advantage estimate

text
Question: Mean home margin in NFL seasons …
Design: home rows only (one row per game).
Analysis: game-weighted mean point_diff; season-block bootstrap (or another
dependence-aware method justified from the design); 95% interval.
Assumptions: one row per game; cluster definition and number of clusters stated.
Result: M=…, SD=…, dependence-aware 95% CI ….
Limits: era/rule confounds; not a causal estimate of venue alone.

APA-style general templates: references/reporting_standards.md.


Integrity Rules

  1. Commit the model family before peeking at test folds.
  2. Do not drop awkward seasons after seeing metrics.
  3. Always beat a dumb baseline before claiming value.
  4. Never use same-game score components as predictors for pre-game models.
  5. Separate exploratory coefficient fishing from confirmatory walk-forward evaluation.
  6. Report failures and non-improvements.
  7. Distinguish confirmatory from exploratory analyses (see statistical integrity notes in references).
  8. Make it reproducible — seasons, formula, package versions, seeds.

Bundled Resources

references/

FileContents
sports_glm_guide.mdSports outcome → GLM family map and formulas
diagnostics_checklist.mdSports-specific diagnostic checklist
test_selection_guide.mdFull test selection tree (group comparisons, etc.)
assumptions_and_diagnostics.mdDeep assumption checking guidance
effect_sizes_and_power.mdEffect sizes, CIs, power analysis
bayesian_statistics.mdPriors, hierarchical Bayes, diagnostics
reporting_standards.mdComplete reporting standards and templates

scripts/

FileContents
assumption_checks.pyNormality, IQR outliers, and optional Levene variance check on a supplied column
glm_diagnostics.pyFit an additive logistic GLM on a user-owned table; export OR, intervals, and calibration JSON

Related Skills

NeedGo to
Deeper EDA firsteda-sports
Feature legalityfeature-rules / leakage-audit
Nonlinear ML comparisonpredictive-modeling
Ratings instead of covariatesratings-strength-models
Probability reliabilitycalibration-check
Write-upresults-reporting / model-card
Baselines ladderbaseline-models
Validation designvalidation-design

Quick Command Card

bash
python /path/to/statistical-modeling/scripts/assumption_checks.py \
  --input observations.csv --value-col margin --group-col venue \
  --out assumptions.json

python /path/to/statistical-modeling/scripts/glm_diagnostics.py \
  --input model_frame.csv \
  --formula "won ~ is_home + rating_diff + rest_diff" \
  --out glm_report.json

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Statistical Modeling AI skill do?

Guided statistical modeling for user-provided sports data: selecting models for binary, continuous, and count outcomes; assumption checks; effect sizes; time-aware inference; GLM diagnostics; and complete reporting.

Why use Statistical Modeling on TypingMind?

Because you install it once and use it with any model. Statistical Modeling is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Statistical Modeling in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/WalrusQuant/sports-analytic-skills/tree/main/skills/statistical-modeling. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Statistical Modeling?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Statistical Modeling?

As many as you like. As long as a model supports skills, you can use Statistical Modeling with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Statistical Modeling AI skill free?

Yes. It is published on GitHub by WalrusQuant under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇