A production-quality Python library for Analysis of Variance (ANOVA) and Multiple Linear Regression with structured output, simultaneous inference, and FWER control.
Project description
statscore
A production-quality Python library for Analysis of Variance (ANOVA) and Multiple Linear Regression with structured output, simultaneous inference, and family-wise error rate (FWER) control.
Features
- One-Way & Two-Way ANOVA — sum-of-squares decomposition, F-tests, MLE estimation
- Multiple Comparison Procedures — Bonferroni, Šidák, Scheffé, and Tukey methods with automatic "best" selection
- OLS Multiple Linear Regression — matrix-based estimation, TSS partition, R²
- Simultaneous Inference — confidence intervals, confidence regions (ellipsoids), general hypothesis tests
- Prediction Intervals — Scheffé and Bonferroni simultaneous prediction CIs
- Structured Output — all functions return typed dataclass objects, not raw tuples
- Minimal Dependencies — only NumPy and SciPy required
Installation
# From PyPI (once published):
pip install statscore
# From source (development):
git clone https://github.com/furkankyildirim/statscore.git
cd statscore
pip install -e ".[dev]"
Requirements: Python >= 3.9, NumPy >= 1.21, SciPy >= 1.7
Quick Start
One-Way ANOVA
import numpy as np
from statscore import ANOVA1_partition_TSS, ANOVA1_test_equality
data = [
np.array([28, 23, 14, 27, 31]),
np.array([33, 36, 34, 29, 24]),
np.array([18, 21, 20, 22]),
]
partition = ANOVA1_partition_TSS(data)
print(f"SS_total = {partition.SS_total}")
print(f"SS_within = {partition.SS_within}")
print(f"SS_between = {partition.SS_between}")
result = ANOVA1_test_equality(data, alpha=0.05)
print(f"F = {result.F_statistic:.4f}, p = {result.p_value:.4f}")
print(f"Reject H0: {result.reject_H0}")
Multiple Comparisons with FWER Control
from statscore import ANOVA1_CI_linear_combs, ANOVA1_test_linear_combs
C = np.array([[1, -1, 0], [0, 1, -1], [1, 0, -1]])
d = np.zeros(3)
# Automatic method selection (picks narrowest valid intervals)
ci_result = ANOVA1_CI_linear_combs(data, alpha=0.05, C=C, method="best")
for i, (lo, hi) in enumerate(ci_result.intervals):
print(f"CI_{i+1}: [{lo:.2f}, {hi:.2f}]")
Multiple Linear Regression
from statscore import (
Mult_LR_Least_squares, Mult_norm_LR_test_general, Mult_norm_LR_pred_CI
)
X = np.column_stack([np.ones(n), x1, x2])
ols = Mult_LR_Least_squares(X, y)
print(f"beta_hat = {ols.beta_hat}")
print(f"Se^2 = {ols.sigma2_unbiased:.4f}")
# General hypothesis test: H0: C*beta = c0
C = np.array([[0, 1, -1]])
c0 = np.array([0.0])
result = Mult_norm_LR_test_general(X, y, C, c0, alpha=0.05)
print(f"F = {result.test_statistic:.4f}, p = {result.p_value:.4f}")
# Simultaneous prediction intervals
D = np.array([[1, 0.5, 1.0], [1, 1.0, 0.0]])
pred = Mult_norm_LR_pred_CI(X, y, D, alpha=0.05, method="best")
for i, (lo, hi) in enumerate(pred.intervals):
print(f"Prediction {i+1}: {pred.point_estimates[i]:.2f} [{lo:.2f}, {hi:.2f}]")
Package Structure
statscore/
├── __init__.py # Top-level exports (20 public functions)
├── anova/
│ ├── one_way.py # ANOVA1_partition_TSS, ANOVA1_test_equality
│ ├── two_way.py # ANOVA2_partition_TSS, ANOVA2_MLE, ANOVA2_test_equality
│ └── multiple_tests.py # Contrasts, orthogonality, corrections, CI, tests
├── regression/
│ ├── least_squares.py # Mult_LR_Least_squares, Mult_LR_partition_TSS
│ ├── inference.py # Simultaneous CI, CR, general/component/linear tests
│ └── prediction.py # Mult_norm_LR_pred_CI
├── utils/
│ ├── distributions.py # Critical values and p-values (F, t, chi2, q)
│ └── validation.py # Input validation helpers
├── examples/
│ └── demo.py # Full demonstration of all 20 functions
└── tests/ # 58 unit tests (pytest)
API Reference
ANOVA Functions
| Function | Description |
|---|---|
ANOVA1_partition_TSS(data) |
Partition SS_total into SS_within and SS_between |
ANOVA1_test_equality(data, alpha) |
F-test for equality of group means |
ANOVA1_is_contrast(c) |
Check if coefficients form a contrast |
ANOVA1_is_orthogonal(n, c1, c2) |
Check orthogonality of two contrasts |
Bonferroni_correction(alpha, m) |
Bonferroni-corrected significance level |
Sidak_correction(alpha, m) |
Šidák-corrected significance level |
ANOVA1_CI_linear_combs(data, alpha, C, method) |
Simultaneous CIs for linear combinations |
ANOVA1_test_linear_combs(data, alpha, C, d, method) |
Test multiple linear combinations (FWER) |
ANOVA2_partition_TSS(data) |
Two-way ANOVA sum of squares partition |
ANOVA2_MLE(data) |
MLE for μ, α_i, β_j, δ_{ij} |
ANOVA2_test_equality(data, alpha, test) |
Two-way ANOVA F-tests ("A", "B", "AB") |
Regression Functions
| Function | Description |
|---|---|
Mult_LR_Least_squares(X, y) |
OLS estimation: β̂, σ² MLE & unbiased |
Mult_LR_partition_TSS(X, y) |
TSS = RegSS + RSS decomposition |
Mult_norm_LR_simul_CI(X, y, alpha) |
Simultaneous CIs for all β_i |
Mult_norm_LR_CR(X, y, C, alpha) |
Confidence region (ellipsoid) for Cβ |
Mult_norm_LR_is_in_CR(X, y, C, c0, alpha) |
Test if c₀ is inside the CR |
Mult_norm_LR_test_general(X, y, C, c0, alpha) |
General test H₀: Cβ = c₀ |
Mult_norm_LR_test_comp(X, y, alpha, components) |
Test H₀: β_{j₁}=...=β_{jᵣ}=0 |
Mult_norm_LR_test_linear_reg(X, y, alpha) |
Test existence of linear regression |
Mult_norm_LR_pred_CI(X, y, D, alpha, method) |
Simultaneous prediction CIs |
Mathematical Background
One-Way ANOVA
Model: X_{ij} = μ + α_i + ε_{ij}, where ε_{ij} ~ N(0, σ²).
Sum of squares decomposition:
- SS_total = Σ_i Σ_j (X_{ij} - X̄)²
- SS_within = Σ_i Σ_j (X_{ij} - X̄_i)²
- SS_between = Σ_i n_i (X̄_i - X̄)²
- Identity: SS_total = SS_within + SS_between
F-test: F = [SS_b/(I-1)] / [SS_w/(n-I)] ~ F_{I-1, n-I} under H₀.
Two-Way ANOVA
Model: X_{ijk} = μ + α_i + β_j + δ_{ij} + ε_{ijk}.
Decomposition: SS_total = SS_A + SS_B + SS_AB + SS_E
Multiple Linear Regression
Model: Y = Xβ + ε, where ε ~ N(0, σ²I).
OLS estimator: β̂ = (X^T X)^{-1} X^T Y
TSS partition: TSS = RegSS + RSS
General test: H₀: Cβ = c₀, using F = [(Cβ̂ - c₀)^T [C(X^TX)^{-1}C^T]^{-1} (Cβ̂ - c₀)] / (r · S_e²)
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run linter
ruff check .
# Type checking
mypy statscore/
Running the Demo
python examples/demo.py
This exercises all 20 functions with representative sample data.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file statscore-0.0.1.tar.gz.
File metadata
- Download URL: statscore-0.0.1.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50d84cfc3d0e39deeffeb1795213ce4775785b64bba1c2dcd1a2147ee706d99e
|
|
| MD5 |
fffb9a2d92c6643b5836191a99cf87df
|
|
| BLAKE2b-256 |
79e6778ad1ee2da0889d7875ed7ca66da09e9017fe7ada748adc7edd8a6de61b
|
Provenance
The following attestation bundles were made for statscore-0.0.1.tar.gz:
Publisher:
publish.yml on furkankyildirim/statscore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
statscore-0.0.1.tar.gz -
Subject digest:
50d84cfc3d0e39deeffeb1795213ce4775785b64bba1c2dcd1a2147ee706d99e - Sigstore transparency entry: 1756168550
- Sigstore integration time:
-
Permalink:
furkankyildirim/statscore@fc9e434e55736eb8c35806ee9d7bb3bf5795fa40 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/furkankyildirim
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fc9e434e55736eb8c35806ee9d7bb3bf5795fa40 -
Trigger Event:
push
-
Statement type:
File details
Details for the file statscore-0.0.1-py3-none-any.whl.
File metadata
- Download URL: statscore-0.0.1-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d66cec57c08279bc0165797fa62e83ac5c832c31d09c6052792c6946217cda16
|
|
| MD5 |
49874189effa9d5a877d3e36ef72ba31
|
|
| BLAKE2b-256 |
bbc4ebe67eb85d03d8f949a21110dac9ae96a1870274916e62d92647dc0f3194
|
Provenance
The following attestation bundles were made for statscore-0.0.1-py3-none-any.whl:
Publisher:
publish.yml on furkankyildirim/statscore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
statscore-0.0.1-py3-none-any.whl -
Subject digest:
d66cec57c08279bc0165797fa62e83ac5c832c31d09c6052792c6946217cda16 - Sigstore transparency entry: 1756168554
- Sigstore integration time:
-
Permalink:
furkankyildirim/statscore@fc9e434e55736eb8c35806ee9d7bb3bf5795fa40 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/furkankyildirim
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fc9e434e55736eb8c35806ee9d7bb3bf5795fa40 -
Trigger Event:
push
-
Statement type: