Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GLM Support #763

Merged
merged 53 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
32bbf90
initial commit
s3alfisc Dec 21, 2024
e56725f
method for step halfing
s3alfisc Dec 22, 2024
08ea97f
cleanups and replace Stamann eta update; works now without fixed effects
s3alfisc Dec 22, 2024
3d316da
Logit without fixed effects works
s3alfisc Dec 22, 2024
8da865d
add probit class
s3alfisc Dec 22, 2024
eaa6b19
delete Fepois
s3alfisc Dec 22, 2024
c293dec
type hints
s3alfisc Dec 22, 2024
37d31a3
type hints
s3alfisc Dec 22, 2024
f3bf0a3
rename to get_fit
s3alfisc Dec 22, 2024
2c7c323
add some tests
s3alfisc Dec 22, 2024
5a19b9d
add gaussian, fix crit bug
s3alfisc Dec 23, 2024
6f6aded
no coefficient crit
s3alfisc Dec 23, 2024
8a9cc28
more tests
s3alfisc Dec 23, 2024
e3b9139
test run N = 100
s3alfisc Dec 23, 2024
6ae6bbe
inherit from Feols, add predict method
s3alfisc Dec 25, 2024
82f5ef3
vcov reorg
s3alfisc Dec 25, 2024
e85b8bb
add depvar checks
s3alfisc Dec 26, 2024
c782636
update weights
s3alfisc Dec 26, 2024
2d4c1b5
gaussian gives identical results
s3alfisc Dec 26, 2024
8d0f06d
gaussian works except iid
s3alfisc Dec 26, 2024
6acf35d
fix irls_weights, add to tests
s3alfisc Dec 26, 2024
1054284
update tests
s3alfisc Dec 27, 2024
26819e2
test cleanup
s3alfisc Dec 27, 2024
2f3a294
iid hetero match
s3alfisc Dec 27, 2024
dbc7b93
work with scores vor crv1
s3alfisc Dec 28, 2024
f762040
crv1 inference passes for glms
s3alfisc Dec 28, 2024
9486a07
error when glms with fixed effects
s3alfisc Dec 28, 2024
8473c9e
dones test scores for gaussian vs fixest
s3alfisc Dec 28, 2024
31c8fd2
mention GLMs in quickstart
s3alfisc Dec 28, 2024
36b94b3
mention GLMs in quickstart
s3alfisc Dec 28, 2024
d6aee54
add bug in bread for IV
s3alfisc Dec 28, 2024
ef01859
custom iid method for poisson
s3alfisc Dec 28, 2024
e44c0e0
compare deviance in tests
s3alfisc Dec 28, 2024
43991e7
fix probit deviance -> no more convergence problems
s3alfisc Dec 28, 2024
54f5deb
avg_slopes to docs
s3alfisc Dec 28, 2024
0c5d211
pyarrow to docs dependencies
s3alfisc Dec 28, 2024
917347a
fix error in docs
s3alfisc Dec 28, 2024
821d9b3
update changelog
s3alfisc Dec 28, 2024
c3feec9
another docs bug
s3alfisc Dec 28, 2024
642cf6a
adress Juan's comments
s3alfisc Dec 30, 2024
9d37b0a
udate readmes
s3alfisc Jan 1, 2025
12b3a5a
update lock file
s3alfisc Jan 1, 2025
355e837
align pyproject toml and lock with main
s3alfisc Jan 1, 2025
3f4a175
Merge branch 'master' into glm
s3alfisc Jan 1, 2025
8b5ad8c
update lock file
s3alfisc Jan 1, 2025
9984633
small cleanups
s3alfisc Jan 1, 2025
d7055a1
Merge branch 'master' into glm
s3alfisc Jan 2, 2025
915f309
merge with master
s3alfisc Jan 4, 2025
e75cfa6
enable context for glms
s3alfisc Jan 4, 2025
38d83f5
enable context for glms
s3alfisc Jan 4, 2025
224bcc6
enforce formulaic < 1.1.0
s3alfisc Jan 4, 2025
3c71ab9
Merge branch 'master' into glm
s3alfisc Jan 4, 2025
de787e5
add pyarrow to docs deps, required by marginaleffects
s3alfisc Jan 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ For questions on `PyFixest`, head on over to our [PyFixest Discourse forum](http

## Features

- **OLS**, **WLS** and **IV** Regression
- **OLS**, **WLS** and **IV** Regression with Fixed-Effects Demeaning via [Frisch-Waugh-Lovell](https://bookdown.org/ts_robinson1994/10EconometricTheorems/frisch.html)
- **Poisson Regression** following the [pplmhdfe algorithm](https://journals.sagepub.com/doi/full/10.1177/1536867X20909691)
- Multiple Estimation Syntax
- Probit, Logit and Gaussian Family GLMs (currently without fixed effects demeaning, this is WIP)
- Several **Robust** and **Cluster Robust Variance-Covariance** Estimators
- **Wild Cluster Bootstrap** Inference (via
[wildboottest](https://github.com/py-econometrics/wildboottest))
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## PyFixest 0.28.0 (In Development, can be installed from github)

- Adds a `pf.feglm()` function that supports GLMs with normal and binomial families (gaussian, logit, probit) without fixed effects. Fixed effects support is work in progress.
- Fix a bug that caused reindexing of `LPDID._coeftable` when calling `LPDID.iplot()`. As a result, a second call of `LPDID.iplot()` would fail.

## PyFixest 0.27.0
Expand Down
3 changes: 2 additions & 1 deletion docs/pyfixest.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ For questions on `PyFixest`, head on over to our [PyFixest Discourse forum](http

## Features

- **OLS**, **WLS** and **IV** Regression
- **OLS**, **WLS** and **IV** Regression with Fixed-Effects Demeaning via [Frisch-Waugh-Lovell](https://bookdown.org/ts_robinson1994/10EconometricTheorems/frisch.html)
- **Poisson Regression** following the [pplmhdfe algorithm](https://journals.sagepub.com/doi/full/10.1177/1536867X20909691)
- Multiple Estimation Syntax
- Probit, Logit and Gaussian Family GLMs (currently without fixed effects demeaning, this is WIP)
- Several **Robust** and **Cluster Robust Variance-Covariance** Estimators
- **Wild Cluster Bootstrap** Inference (via
[wildboottest](https://github.com/py-econometrics/wildboottest))
Expand Down
35 changes: 35 additions & 0 deletions docs/quickstart.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from lets_plot import LetsPlot
from marginaleffects import slopes, avg_slopes

import pyfixest as pf

Expand Down Expand Up @@ -408,6 +409,40 @@ q1 = np.array([2.0, 1.0])
fit.wald_test(R=R1, q=q1)
```

# Other GLMs (without fixed effects)

`PyFixest` supports a range of other GLMs without fixed effects (adding fixed effect support is WIP) via the `pf.feglm()` function.

```{python}
data_glm = pf.get_data(N=100, seed = 170)
data_glm["Y"] = np.where(data_glm["Y"] > 0, 1, 0)

fit_gaussian = pf.feglm(fml = "Y~X1", data = data_glm, family = "gaussian")
fit_logit = pf.feglm(fml = "Y~X1", data = data_glm, family = "logit")
fit_probit = pf.feglm(fml = "Y~X1", data = data_glm, family = "probit")

pf.etable([
fit_gaussian,
fit_logit,
fit_probit,
])
```

You can make predictions on the `response` and `link` scale via the `predict()` method:

```{python}
fit_logit.predict(type = "response")[0:5]
fit_logit.predict(type = "link")[0:5]
```

You can compute the **average marginal effect** via the [marginaleffects package](https://github.com/vincentarelbundock/pymarginaleffects):

```{python}
avg_slopes(fit_logit, variables = "X1")
```

Please take a look at the [marginaleffects book](https://marginaleffects.com/) to learn about other transformations that the `marginaleffects` package supports.

# Multiple Estimation

`PyFixest` supports a range of multiple estimation functionality: `sw`, `sw0`, `csw`, `csw0`, and multiple dependent variables. The meaning of these options is explained in the [Multiple Estimations](https://lrberge.github.io/fixest/articles/multiple_estimations.html) vignette of the `fixest` package:
Expand Down
4,048 changes: 2,085 additions & 1,963 deletions pixi.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyfixest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# Import frequently used functions and classes
from pyfixest.estimation import (
bonferroni,
feglm,
feols,
fepois,
rwolf,
Expand All @@ -33,6 +34,7 @@
"estimation",
"etable",
"event_study",
"feglm",
"feols",
"fepois",
"get_data",
Expand Down
92 changes: 92 additions & 0 deletions pyfixest/estimation/FixestMulti_.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

import pandas as pd

from pyfixest.estimation.fegaussian_ import Fegaussian
from pyfixest.estimation.feiv_ import Feiv
from pyfixest.estimation.felogit_ import Felogit
from pyfixest.estimation.feols_ import Feols, _check_vcov_input, _deparse_vcov_input
from pyfixest.estimation.feols_compressed_ import FeolsCompressed
from pyfixest.estimation.fepois_ import Fepois
from pyfixest.estimation.feprobit_ import Feprobit
from pyfixest.estimation.FormulaParser import FixestFormulaParser
from pyfixest.utils.dev_utils import DataFrameType, _narwhals_to_pandas
from pyfixest.utils.utils import capture_context
Expand Down Expand Up @@ -320,6 +323,7 @@ def _estimate_all_models(
lean=_lean,
sample_split_value=sample_split_value,
sample_split_var=_splitvar,
context=_context,
)
FIT.prepare_model_matrix()
FIT.demean()
Expand Down Expand Up @@ -348,12 +352,100 @@ def _estimate_all_models(
sample_split_value=sample_split_value,
sample_split_var=_splitvar,
separation_check=separation_check,
context=_context,
# solver=_solver
)
FIT.prepare_model_matrix()
FIT.to_array()
FIT.drop_multicol_vars()

elif _method == "feglm-logit":
FIT = Felogit(
FixestFormula=FixestFormula,
data=_data,
ssc_dict=_ssc_dict,
drop_singletons=_drop_singletons,
drop_intercept=_drop_intercept,
weights=_weights,
weights_type=_weights_type,
solver=solver,
collin_tol=collin_tol,
fixef_tol=_fixef_tol,
lookup_demeaned_data=lookup_demeaned_data,
tol=iwls_tol,
maxiter=iwls_maxiter,
store_data=_store_data,
copy_data=_copy_data,
lean=_lean,
sample_split_value=sample_split_value,
sample_split_var=_splitvar,
separation_check=separation_check,
context=_context,
)

FIT.prepare_model_matrix()
FIT.to_array()
FIT._check_dependent_variable()
FIT.drop_multicol_vars()

elif _method == "feglm-probit":
FIT = Feprobit(
FixestFormula=FixestFormula,
data=_data,
ssc_dict=_ssc_dict,
drop_singletons=_drop_singletons,
drop_intercept=_drop_intercept,
weights=_weights,
weights_type=_weights_type,
solver=solver,
collin_tol=collin_tol,
fixef_tol=_fixef_tol,
lookup_demeaned_data=lookup_demeaned_data,
tol=iwls_tol,
maxiter=iwls_maxiter,
store_data=_store_data,
copy_data=_copy_data,
lean=_lean,
sample_split_value=sample_split_value,
sample_split_var=_splitvar,
separation_check=separation_check,
context=_context,
)

FIT.prepare_model_matrix()
FIT.to_array()
FIT._check_dependent_variable()
FIT.drop_multicol_vars()

elif _method == "feglm-gaussian":
FIT = Fegaussian(
FixestFormula=FixestFormula,
data=_data,
ssc_dict=_ssc_dict,
drop_singletons=_drop_singletons,
drop_intercept=_drop_intercept,
weights=_weights,
weights_type=_weights_type,
solver=solver,
collin_tol=collin_tol,
fixef_tol=_fixef_tol,
lookup_demeaned_data=lookup_demeaned_data,
tol=iwls_tol,
maxiter=iwls_maxiter,
store_data=_store_data,
copy_data=_copy_data,
lean=_lean,
sample_split_value=sample_split_value,
sample_split_var=_splitvar,
separation_check=separation_check,
context=_context,
)

FIT.prepare_model_matrix()
FIT.to_array()
FIT._check_dependent_variable()
FIT.drop_multicol_vars()

elif _method == "compression":
FIT = FeolsCompressed(
FixestFormula=FixestFormula,
Expand Down
8 changes: 8 additions & 0 deletions pyfixest/estimation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@
detect_singletons,
)
from pyfixest.estimation.estimation import (
feglm,
feols,
fepois,
)
from pyfixest.estimation.fegaussian_ import Fegaussian
from pyfixest.estimation.feiv_ import (
Feiv,
)
from pyfixest.estimation.felogit_ import Felogit
from pyfixest.estimation.feols_ import (
Feols,
)
from pyfixest.estimation.fepois_ import (
Fepois,
)
from pyfixest.estimation.feprobit_ import Feprobit
from pyfixest.estimation.FixestMulti_ import (
FixestMulti,
)
Expand All @@ -31,13 +35,17 @@
)

__all__ = [
"Fegaussian",
"Feiv",
"Felogit",
"Feols",
"Fepois",
"Feprobit",
"FixestMulti",
"bonferroni",
"demean",
"detect_singletons",
"feglm",
"feols",
"fepois",
"literals",
Expand Down
Loading
Loading