import inspect
from html import escape
import numpy as np
import crabbymetrics as cm
from IPython.display import HTML, display
def html_table(headers, rows, table_attrs=""):
parts = [
f"<table {table_attrs}>".strip(),
"<thead>",
"<tr>",
*[f"<th>{escape(str(header))}</th>" for header in headers],
"</tr>",
"</thead>",
"<tbody>",
]
for row in rows:
parts.append("<tr>")
for cell in row:
parts.append(f"<td>{cell}</td>")
parts.append("</tr>")
parts.extend(["</tbody>", "</table>"])
return "".join(parts)
def class_rows(classes):
rows = []
for cls in classes:
methods = []
for method_name in sorted(name for name in dir(cls) if not name.startswith("_")):
method = getattr(cls, method_name)
if not callable(method):
continue
methods.append(
f"<code>{escape(method_name)}{escape(str(inspect.signature(method)))}</code>"
)
rows.append(
[
f"<code>{escape(cls.__name__)}{escape(str(inspect.signature(cls)))}</code>",
"<br>".join(methods),
]
)
return rowscrabbymetrics API Reference
Library sitrep and verified Python surface
1 Overview
crabbymetrics is a compact Rust-backed econometrics library exposed to Python through pyo3 and packaged with maturin. The public API is intentionally small: estimator classes, transformer classes, an Optimizers helper namespace, numpy arrays as the only runtime dependency, and a scikit-adjacent fit / predict / summary pattern.
The class pages remain the canonical API reference, but this overview now does two extra jobs:
- it shows the live constructor and method surface from the installed module;
- it groups the growing class list into a navigable left-TOC landing page instead of relying on an oversized navbar dropdown.
2 Sitrep
src/lib.rsregisters the Python classes, while estimator implementations are split by family undersrc/estimators/.- Shared linear algebra, covariance, bootstrap, and NumPy conversion helpers live in
src/utils.rs. - Packaging is lean. The Python package declares only
numpyat runtime, while native builds are handled bymaturin. - Release automation already exists in
.github/workflows/wheels.ymlfor Linux and macOS wheels across Python 3.10 to 3.14. - Coverage is broad for a small codebase: linear estimators, GLMs/classifiers, survival models, panel estimators, semiparametric treatment-effect estimators, callback-driven
GMM/MEstimator, and matrix/design transforms. - The main maturity gaps are still documentation depth and some remaining API asymmetries across older estimators.
- The recent MLE overhaul standardizes the layered prediction contract more explicitly:
predict_lin(...)for the latent linear index,predict(...)for mean-scale predictions, andpredict_label(...)only where labels are conceptually distinct from probabilities. - Survival models now follow the same spirit: parametric PH models expose hazard, cumulative-hazard, and survival surfaces, while Cox-style models default to relative-risk predictions because the baseline hazard is not yet estimated.
3 Regression and GLMs
This is the general supervised-learning part of the library: regression, classification, count models, and related coefficient-inference utilities. Anytime-valid confidence sequences currently enter through the fitted OLS summary interface.
Reference pages:
- OLS
- ABCOLS
- Anytime-Valid Confidence Sequences
- Ridge
- FixedEffectsOLS
- ElasticNet
- BaggedPolynomialRegressor
- Logit
- MultinomialLogit
- Poisson
Worked docs:
- ABC OLS
- Bagged Polynomial Regression
- Anytime-Valid Confidence Sequences
- MLE Prediction Interface
- Logit
- Multinomial Logit
- Poisson
display(HTML(html_table(
["Constructor", "Methods"],
class_rows([
cm.OLS,
cm.ABCOLS,
cm.Ridge,
cm.FixedEffectsOLS,
cm.ElasticNet,
cm.BaggedPolynomialRegressor,
cm.Logit,
cm.MultinomialLogit,
cm.Poisson,
])
)))| Constructor | Methods |
|---|---|
OLS() |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)fit_sketch(self, /, x, y, sketch_size, seed=None)fit_weighted(self, /, x, y, sample_weight)predict(self, /, x)summary(self, /, vcov='hc1', lags=None, clusters=None, anytime_valid=False, g=1.0, level=0.95)wald_test(self, /, r, q=None, vcov=None, lags=None, clusters=None) |
ABCOLS() |
column_names(self, /)constraint_matrix(self, /)design_matrix(self, /)fit(self, /, y, x, categories, cont_cat_interactions=None, cat_cat_interactions=None, center_continuous=True)fitted_values(self, /)predict(self, /, x, categories)residuals(self, /)summary(self, /) |
Ridge(penalty=None, cv=5) |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)fit_weighted(self, /, x, y, sample_weight)predict(self, /, x)summary(self, /, vcov='hc1', lags=None, clusters=None) |
FixedEffectsOLS() |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, fe, y)fit_weighted(self, /, x, fe, y, sample_weight)summary(self, /, vcov='hc1', lags=None, clusters=None)wald_test(self, /, r, q=None, vcov=None, lags=None, clusters=None) |
ElasticNet(penalty=1.0, l1_ratio=0.5, tolerance=0.0001, max_iterations=1000) |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)predict(self, /, x)summary(self, /) |
BaggedPolynomialRegressor(n_estimators=50, degree=2, max_features=None, max_samples=None, bootstrap=True, penalty=1.0, seed=42) |
fit(self, /, x, y)predict(self, /, x)summary(self, /) |
Logit(alpha=0.0, max_iterations=100, gradient_tolerance=0.0001) |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)predict(self, /, x)predict_label(self, /, x, cutoff=0.5)predict_lin(self, /, x)summary(self, /)wald_test(self, /, r, q=None) |
MultinomialLogit(alpha=0.0, max_iterations=100, gradient_tolerance=0.0001) |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)predict(self, /, x)predict_label(self, /, x)predict_lin(self, /, x)summary(self, /) |
Poisson(alpha=0.0, max_iterations=100, tolerance=0.0001) |
bootstrap(self, /, n_bootstrap, seed=None)fit(self, /, x, y)predict(self, /, x)predict_lin(self, /, x)summary(self, /, vcov='vanilla')wald_test(self, /, r, q=None, vcov='vanilla') |
4 Survival, time-to-event, and recurrent-event models
Reference pages:
Worked docs:
display(HTML(html_table(
["Constructor", "Methods"],
class_rows([
cm.ExponentialPH,
cm.WeibullPH,
cm.CoxPH,
cm.AndersenGill,
])
)))| Constructor | Methods |
|---|---|
ExponentialPH() |
fit(self, /, x, time, event, max_iterations=100, tolerance=1e-08)predict(self, /, x, time)predict_cumulative_hazard(self, /, x, time)predict_hazard(self, /, x)predict_lin(self, /, x)predict_log_hazard(self, /, x)predict_survival(self, /, x, time)summary(self, /)survival(self, /, x, time) |
WeibullPH() |
fit(self, /, x, time, event, max_iterations=100, tolerance=1e-08)predict(self, /, x, time)predict_cumulative_hazard(self, /, x, time)predict_hazard(self, /, x, time)predict_lin(self, /, x, time)predict_log_hazard(self, /, x, time)predict_survival(self, /, x, time)summary(self, /)survival(self, /, x, time) |
CoxPH() |
fit(self, /, x, time, event, max_iterations=50, tolerance=1e-08)predict(self, /, x)predict_lin(self, /, x)predict_log_hazard_ratio(self, /, x)predict_relative_risk(self, /, x)summary(self, /) |
AndersenGill() |
fit(self, /, x, start, stop, event, max_iterations=50, tolerance=1e-08)predict(self, /, x)predict_lin(self, /, x)predict_log_hazard_ratio(self, /, x)predict_relative_risk(self, /, x)summary(self, /) |
5 Causal inference and panels
6 Hypothesis testing and utilities
7 Transforms
display(HTML(html_table(
["Constructor", "Methods"],
class_rows([
cm.PCA,
cm.RandomizedPCA,
cm.KernelBasis,
cm.NystromBasis,
cm.RandomFourierFeatures,
])
)))| Constructor | Methods |
|---|---|
PCA(n_components, whiten=False) |
fit(self, /, x)fit_transform(self, /, x)inverse_transform(self, /, scores)summary(self, /)transform(self, /, x) |
RandomizedPCA(n_components, oversamples=10, power_iter=1, seed=None) |
fit(self, /, x)fit_transform(self, /, x)inverse_transform(self, /, scores)summary(self, /)transform(self, /, x) |
KernelBasis(kernel='gaussian', bandwidth=0.5, coef0=1.0, degree=2.0) |
fit(self, /, x)fit_transform(self, /, x)summary(self, /)transform(self, /, x) |
NystromBasis(n_components, kernel='gaussian', bandwidth=0.5, coef0=1.0, degree=2.0, ridge=1e-10, seed=None) |
fit(self, /, x)fit_transform(self, /, x)summary(self, /)transform(self, /, x) |
RandomFourierFeatures(n_components, bandwidth=0.5, seed=None) |
fit(self, /, x)fit_transform(self, /, x)summary(self, /)transform(self, /, x) |
8 Estimation interfaces and optimizers
9 Compatibility note
Older example and ablation pages remain in the site because they are useful worked examples. The class pages above are the canonical API docs, and the API overview page is now the intended navigation hub. If the navbar stays slim, this page is where the full surface should grow.