Tobit
Tobit estimates a censored normal (Tobit) regression model by maximum likelihood. The observed dependent variable y is a continuous latent regression y* = x'β + ε (ε ~ N(0, σ²)) censored at a lower bound, an upper bound, or both. It shares the general maximum-likelihood API shape with Logit (data/y/x/options constructor, .fit(), z-tests, cov_type, marginal_effects(), predict()), but y is continuous rather than 0/1, σ is reported as an estimated parameter, and the results add censoring_fit_check() in place of pred_table().
Censoring bounds
TobitOptions.lower (default 0.0) and TobitOptions.upper (default None) set the censoring bounds; None means that side is not censored. The default is the standard left-censored-at-zero Tobit. For a right-censored-only model, pass lower=None explicitly. fit() raises ValidationError if both bounds are None, if lower >= upper, or if any y value falls outside the given bounds, and also if no observation lies strictly inside the bounds (the model is then unidentified).
TobitResults.lower / .upper echo back the bounds actually used.
Standard error types
TobitOptions.cov_type supports "classical" (observed-information / Hessian-based), "opg" (outer product of gradients), "hc0", "hc1", and "cluster" (requires cluster). As with Logit, HC2/HC3 and HAC are not available. Internally the optimizer works in (β, log σ) space; the reported covariance is transformed to (β, σ) space so that TobitResults.std_errors includes a standard error for sigma alongside the coefficients. param_names is ["const", <x…>, "sigma"].
Overall significance test
TobitResults.wald_statistic / wald_p_value report a Wald test of the joint hypothesis that all non-intercept coefficients are zero (chi-square distributed, matching AER::tobit). Tobit does not provide a likelihood-ratio statistic or a pseudo-R², because the intercept-only Tobit model has no closed-form log-likelihood.
Solver options
TobitOptions.solver selects the optimization algorithm: "newton" (default, Newton-Raphson with a Levenberg-Marquardt damped step for the indefinite-Hessian regions specific to the (β, log σ) likelihood), "bfgs", or "lbfgs". All three converge to the same maximum-likelihood estimate. max_iter and tol control the iteration limit and the gradient-norm convergence threshold. When the solver does not converge within max_iter iterations, a ComputationError is raised unless raise_on_non_convergence=False, in which case TobitResults.converged is False instead.
Marginal effects and predictions
TobitResults.marginal_effects() and predict() both take a target:
target |
Quantity |
|---|---|
"expected_latent" |
E[y*\|x] = x'β (the linear predictor) |
"expected_observed" (default) |
E[y\|x], the censoring-adjusted conditional mean (McDonald–Moffitt) |
"prob_uncensored" |
P(uncensored\|x) |
marginal_effects() computes dy/dx with delta-method standard errors, evaluated at "overall" (average marginal effects, the default), "mean", or "median"; the constant term is excluded. predict() returns row-oriented fitted values for the training data (in-sample only). See Getting Started for an example.
Censoring fit check
TobitResults.censoring_fit_check() replaces pred_table(). For each censored direction it compares the observed censoring rate (fraction of y exactly at the boundary) against the model-implied rate (mean fitted boundary probability), returned as a per-direction breakdown ("lower" / "uncensored" / "upper").
econometricsmodels.Tobit(data, y, x, options=None)
Censored regression (Tobit) estimator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
A polars DataFrame containing the dependent and independent variables. |
required |
y
|
str
|
Column name of the dependent variable. May be censored at
|
required |
x
|
list[str]
|
List of column names of the independent variables. |
required |
options
|
TobitOptions | None
|
Estimation options. Defaults to |
None
|
Examples:
>>> import polars as pl
>>> from econometricsmodels import Tobit
>>> df = pl.DataFrame({"y": [0.0, 1.0], "x1": [1.0, 2.0]})
>>> result = Tobit(df, y="y", x=["x1"]).fit()
>>> result.params["x1"]
fit()
Estimate the Tobit model by maximum likelihood.
Returns:
| Type | Description |
|---|---|
TobitResults
|
The estimation results. |
Raises:
| Type | Description |
|---|---|
TypeError
|
An argument has the wrong type (for example
|
ValidationError
|
The input or options are invalid (a
column is missing, contains missing values or
NaN/infinity, |
ComputationError
|
A problem was detected during
computation (e.g. non-convergence, a singular
Hessian/OPG/design matrix). A subclass of
|
econometricsmodels.TobitOptions
Estimation options for Tobit.
See docs/spec/tobit-spec.md for the rationale behind each field's meaning
and default value.
cluster
property
Column name to use as the cluster group key when cov_type="cluster".
Refers to a column in data rather than being passed as a separate array.
Specifying it with any other cov_type raises ValidationError.
confidence_level
property
Confidence level for confidence intervals, in the range (0, 1). Defaults to 0.95 (a 95% confidence interval).
cov_type
property
Standard error type: one of "classical", "opg", "hc0", "hc1", "cluster". Case-insensitive.
include_intercept
property
Whether the engine should automatically add an intercept column.
When true, a column of all 1.0 is prepended to the design matrix.
If the user's x already contains a constant column while this is true,
the resulting perfect collinearity raises ComputationError (singular
design matrix).
lower
property
Lower censoring bound. None means "no censoring from below". Defaults to
0.0 (the standard left-censored-at-zero Tobit model). At least one of
lower/upper must be set (both None raises ValidationError).
max_iter
property
Maximum number of solver iterations, an integer from 1 to 10,000 (anything else
raises ValidationError).
raise_on_non_convergence
property
If true (default), raise ComputationError when the solver fails to
converge within max_iter iterations. If false, return the result at the
final iterate instead (with converged=False).
solver
property
Optimization solver: one of "newton" (default), "bfgs", "lbfgs". Case-insensitive.
tol
property
Convergence tolerance. For solver="newton", an absolute threshold on
the total gradient norm (default 1e-6). For solver="bfgs"/"lbfgs",
a per-observation-average gradient threshold (the total gradient norm
divided by the number of observations must fall below tol, default
1e-8), matching how statsmodels/scipy normalize convergence checks
by nobs. The two defaults are not interchangeable: Newton's absolute
semantics with a 1e-8 threshold (or bfgs/lbfgs's normalized
semantics with a 1e-6 threshold) measurably degrades either speed or
precision. Passing tol explicitly always uses the
semantics of the chosen solver. For bfgs/lbfgs, the solver also
reports convergence when the gradient norm is within 100 * tol of the
target and the line search can no longer make progress because the
log-likelihood has reached floating-point precision (common with very
large samples); this window scales with tol, so it widens if you
loosen tol. Note: the solver-dependent default is
resolved once, at construction time. Changing solver afterwards via
the setter does not re-resolve tol — set both together (or set tol
explicitly) if you change solver after construction.
upper
property
Upper censoring bound. None (default) means "no censoring from above".
econometricsmodels.TobitResults(raw)
Tobit estimation results.
Array-valued properties (params, std_errors, etc.) are exposed
as dictionaries keyed by coefficient name (for O(1) lookup of a
single parameter). They include an entry for "sigma" (the error
term's standard deviation) in addition to the regression
coefficients, since _lib.TobitResult reports sigma alongside
beta in a unified (k+1)-length representation (see
engine_pybind/src/nonlinear/tobit.rs, TobitResult). Use
coef_table() for a row-oriented listing
(docs/spec/nonlinear-common.md section 5).
marginal_effects(), predict(), and censoring_fit_check() are
provided as separate methods rather than fields on this class (they
depend on a representative point / prediction target not fixed at
fit() time; see docs/spec/nonlinear-common.md
section 6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
TobitResult
|
The estimation result object returned by |
required |
Note
Users normally do not construct this directly; it is returned
by Tobit.fit().
aic
property
Akaike Information Criterion (AIC).
bic
property
Bayesian Information Criterion (BIC).
conf_int
property
Coefficient name to confidence interval (lower, upper)
(includes "sigma").
converged
property
Whether the solver converged within max_iter iterations.
cov_type
property
Standard error type actually used (normalized to lowercase).
dep_var_name
property
Column name of the dependent variable.
df_model
property
Model degrees of freedom (number of slope coefficients,
excluding the intercept and sigma).
df_resid
property
Residual degrees of freedom (n - (k + 1), where k + 1
includes sigma as an estimated parameter).
log_likelihood
property
Log-likelihood at the fitted parameters.
lower
property
Lower censoring bound actually used (echoes
TobitOptions.lower). None means no censoring from below.
n_iter
property
Actual number of solver iterations.
n_obs
property
Number of observations.
p_values
property
Coefficient name to two-sided p-value (includes "sigma").
param_names
property
List of coefficient names ("const" first when
include_intercept=True; "sigma" last).
params
property
Coefficient name to coefficient value (includes "sigma").
sigma
property
Point estimate of the error term's standard deviation.
Equal to params["sigma"]; provided as a convenience shortcut.
solver
property
Optimization solver actually used (normalized to lowercase).
stat_df
property
Degrees of freedom of the t distribution behind test_stats,
or None when stat_dist is "normal". May differ from
df_resid (e.g. cluster-robust inference uses G - 1), so use
this to recompute p-values from test_stats.
stat_dist
property
Distribution of test_stats: "t" (t-statistics) or
"normal" (z-statistics).
std_errors
property
Coefficient name to standard error (includes "sigma").
test_stats
property
Coefficient name to z-statistic (includes "sigma").
Tobit uses a z-test (standard normal), not a t-test (see
docs/spec/nonlinear-common.md section 4).
upper
property
Upper censoring bound actually used (echoes
TobitOptions.upper). None means no censoring from above.
wald_df
property
Degrees of freedom of the chi-squared Wald test
(wald_statistic). None when there are no slope coefficients.
wald_dist
property
Distribution of wald_statistic: always "chi2" (chi-squared).
wald_p_value
property
P-value of the Wald test (chi-squared distribution with
df_model degrees of freedom). NaN when df_model == 0.
wald_statistic
property
Wald test statistic for overall model significance (all slope coefficients jointly zero; the Tobit analogue of OLS's F-statistic and Logit/Probit's likelihood-ratio statistic).
NaN when df_model == 0 (no slope coefficients to test).
augment(new_data=None, target='expected_observed')
Source data with the predicted values appended as a column.
Same target/new_data semantics as predict(), but returns
a polars DataFrame (the training data, or new_data when
given, plus a new predicted-value column) instead of a
row-oriented list. See OLSResults.augment() for the
project's general policy on this DataFrame-returning
exception.
Like Logit/Probit's fixed "predicted_probability" column, the
appended column here has a predicted_ prefix and is named "predicted_{target}", using
the lowercased target (e.g. target="expected_observed" or
target="Expected_Observed" both produce
"predicted_expected_observed"), since predict()'s meaning
depends on target. This also lets augment() be called once
per target on the same DataFrame without a name collision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_data
|
DataFrame | None
|
Same as |
None
|
target
|
str
|
Same as |
'expected_observed'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A polars DataFrame: the source data's columns plus |
DataFrame
|
|
DataFrame
|
source. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
Same as |
censoring_fit_check()
Censoring goodness-of-fit check.
For each direction ("lower"/"uncensored"/"upper") that
applies to this model, compares the observed rate (fraction of
training observations exactly at that boundary) against the
model-implied average probability. Replaces Logit/Probit's
pred_table(), which is not meaningful for Tobit's continuous
y (docs/spec/nonlinear-common.md section 6). A direction is
omitted from the result when the corresponding
TobitOptions.lower/upper was None (that direction has no
censoring).
Returns:
| Type | Description |
|---|---|
list[dict[str, float | str]]
|
A list of dictionaries, one per applicable category (at |
list[dict[str, float | str]]
|
most 3: |
list[dict[str, float | str]]
|
|
coef_table()
Row-oriented summary table of the coefficients.
Shaped to be usable almost as-is in a REST API response. Same
shape as LogitResults.coef_table(). Includes a row for
"sigma" in addition to the regression coefficients (see
params).
Returns:
| Type | Description |
|---|---|
list[dict[str, float | str]]
|
A list of dictionaries, one per coefficient (including |
list[dict[str, float | str]]
|
|
list[dict[str, float | str]]
|
|
marginal_effects(at='overall', target='expected_observed', confidence_level=0.95)
Marginal effects (dy/dx) with delta-method standard errors.
Unlike Logit/Probit, this is Tobit's own implementation (not
the shared dydx_and_jacobian pattern) because the formula
differs per target (see docs/spec/nonlinear-common.md
section 6). Independent of the confidence_level
used in fit() (may differ from it). The constant term
(intercept) is excluded from the output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
at
|
str
|
The representative point at which to evaluate the
marginal effects. One of |
'overall'
|
target
|
str
|
Which quantity's marginal effect to compute. Same
three values as |
'expected_observed'
|
confidence_level
|
float
|
Confidence level for the confidence interval, in the range (0, 1). Defaults to 0.95. |
0.95
|
Returns:
| Type | Description |
|---|---|
list[dict[str, float | str]]
|
A list of dictionaries, one per explanatory variable |
list[dict[str, float | str]]
|
(excluding the intercept). Keys are |
list[dict[str, float | str]]
|
|
list[dict[str, float | str]]
|
|
list[dict[str, float | str]]
|
always a z-statistic (normal distribution). |
list[dict[str, float | str]]
|
the marginal effect estimate (corresponds to |
list[dict[str, float | str]]
|
Stata's |
Raises:
| Type | Description |
|---|---|
ValidationError
|
|
predict(new_data=None, target='expected_observed')
Predicted values for target, on the training data or new_data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_data
|
DataFrame | None
|
New data to predict on. Must contain columns with
the same names as the |
None
|
target
|
str
|
Which quantity to predict. One of
|
'expected_observed'
|
Returns:
| Type | Description |
|---|---|
list[dict[str, float]]
|
Row-oriented predictions, one dict per observation. Each |
list[dict[str, float]]
|
dict has a single key, |
Raises:
| Type | Description |
|---|---|
ValidationError
|
|