Skip to content

BUG: Use weighted residuals in the covariance of weighted GLS and 3SLS - #787

Merged
bashtage merged 1 commit into
mainfrom
lm71-fix-system-weighted-gls-cov
Oct 12, 2026
Merged

bashtage merged 1 commit into
mainfrom
lm71-fix-system-weighted-gls-cov

Conversation

@bashtage

Copy link
Copy Markdown
Owner

The GLS fit of SUR and IV3SLS (method="gls", which is the default unless every equation has the same regressors) gave the covariance estimators the unweighted residuals y - x b together with the weighted regressors sqrt(w) x. The scores of the robust, kernel and clustered covariances were then sqrt(w) x e instead of w x e, so their standard errors were wrong whenever the weights were not all equal. The coefficients, the unadjusted covariance and the OLS fit (method="ols", which already used the weighted residuals) were not affected.

With one equation, GLS is weighted least squares and the robust covariance is HC0. For a regression with 200 observations and chi-squared weights, the robust standard errors of SUR were 0.1299, 0.1823 and 0.1254, where statsmodels WLS(...).fit(cov_type="HC0") gives 0.1448, 0.1982 and 0.1324. For systems with several equations, 96 of the 140 weighted combinations of GLS or OLS, iterated GLS, full_cov, constraints, debiased and covariance type differed from a direct computation of the stacked sandwich estimator, by up to 28% of the largest covariance element, for SUR and for IV3SLS. After this change all of them agree to within 1e-7, and the unweighted fits are unchanged since the weights are all one.

The covariance estimators now get the residuals scaled by the square root of the weights.

The tests compare the weighted estimators with the unweighted estimators applied to the data scaled by the square root of the normalized weights, for every covariance type, and the robust standard errors of a weighted regression with the statsmodels WLS estimator. Seven of them fail without the change.

The GLS fit of SUR and IV3SLS (method="gls", which is the default unless every
equation has the same regressors) gave the covariance estimators the unweighted
residuals y - x b together with the weighted regressors sqrt(w) x. The scores of the
robust, kernel and clustered covariances were then sqrt(w) x e instead of w x e, so
their standard errors were wrong whenever the weights were not all equal. The
coefficients, the unadjusted covariance and the OLS fit (method="ols", which already
used the weighted residuals) were not affected.

With one equation, GLS is weighted least squares and the robust covariance is HC0. For
a regression with 200 observations and chi-squared weights, the robust standard errors
of SUR were 0.1299, 0.1823 and 0.1254, where statsmodels
WLS(...).fit(cov_type="HC0") gives 0.1448, 0.1982 and 0.1324. For systems with several
equations, 96 of the 140 weighted combinations of GLS or OLS, iterated GLS,
full_cov, constraints, debiased and covariance type differed from a direct computation
of the stacked sandwich estimator, by up to 28% of the largest covariance element, for
SUR and for IV3SLS. After this change all of them agree to within 1e-7, and the unweighted
fits are unchanged since the weights are all one.

The covariance estimators now get the residuals scaled by the square root of the
weights.

The tests compare the weighted estimators with the unweighted estimators applied to
the data scaled by the square root of the normalized weights, for every covariance
type, and the robust standard errors of a weighted regression with the statsmodels
WLS estimator. Seven of them fail without the change.
@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.59%. Comparing base (6cbd30b) to head (9ef80d9).
⚠️ Report is 67 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #787      +/-   ##
==========================================
+ Coverage   99.58%   99.59%   +0.01%     
==========================================
  Files         128      128              
  Lines       24188    24486     +298     
  Branches     1809     1827      +18     
==========================================
+ Hits        24087    24387     +300     
+ Misses         40       39       -1     
+ Partials       61       60       -1     
Flag Coverage Δ
adder 99.57% <100.00%> (+0.01%) ⬆️
subtractor 99.57% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bashtage
bashtage merged commit 9e26528 into main Oct 12, 2026
24 checks passed
@bashtage
bashtage deleted the lm71-fix-system-weighted-gls-cov branch October 12, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant