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

PyFixest 0.9.12 #167

Merged
merged 6 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
419 changes: 211 additions & 208 deletions poetry.lock

Large diffs are not rendered by default.

Binary file modified pyfixest/__pycache__/FixestMulti.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/estimation.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/feiv.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/feols.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/fepois.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/summarize.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/utils.cpython-310.pyc
Binary file not shown.
Binary file modified pyfixest/__pycache__/visualize.cpython-310.pyc
Binary file not shown.
3 changes: 2 additions & 1 deletion pyfixest/estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ def fepois(
"""
# fepois

Method for estimating Poisson regression models with fixed effects.
Method for estimating Poisson regression models with fixed effects. Implements the `pplmhdfe` algorithm from the
Stata package of the same name.

Args:
fml (str): A two-sided formula string using fixest formula syntax.
Expand Down
22 changes: 15 additions & 7 deletions pyfixest/feols.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,19 @@ def vcov(self, vcov: Union[str, Dict[str, str]]):
vcov_type="iid",
)

sigma2 = np.sum((_u_hat.flatten()) ** 2) / (_N - 1)
self._vcov = self._ssc * bread * sigma2
if self._method == "feols":
sigma2 = np.sum(_u_hat.flatten() ** 2) / (_N - 1)
elif self._method == "fepois":
sigma2 = 1
else:
raise NotImplementedError(
f"'iid' inference is not supported for {_method} regressions."
)

self._vcov = self._ssc * bread * sigma2

elif self._vcov_type == "hetero":

self._ssc = get_ssc(
ssc_dict=_ssc_dict,
N=_N,
Expand Down Expand Up @@ -280,6 +289,10 @@ def vcov(self, vcov: Union[str, Dict[str, str]]):
self._vcov = self._ssc * bread @ meat @ bread

elif self._vcov_type == "CRV":

#import pdb;
#pdb.set_trace()

cluster_df = _data[self._clustervar]
# if there are missings - delete them!

Expand Down Expand Up @@ -327,8 +340,6 @@ def vcov(self, vcov: Union[str, Dict[str, str]]):

if _is_iv == False:
self._vcov = self._ssc * bread @ meat @ bread
# if self._is_iv == False:
# self._vcov = self._ssc * bread @ meat @ bread
else:
meat = _tXZ @ _tZZinv @ meat @ _tZZinv @ self._tZX
self._vcov = self._ssc * bread @ meat @ bread
Expand All @@ -338,9 +349,6 @@ def vcov(self, vcov: Union[str, Dict[str, str]]):
# if not, either error or turn fixefs into dummies
# for now: don't allow for use with fixed effects

# if self._has_fixef:
# raise ValueError("CRV3 inference is currently not supported with fixed effects.")

if _is_iv:
raise VcovTypeNotSupportedError(
"CRV3 inference is not supported with IV estimation."
Expand Down
6 changes: 4 additions & 2 deletions pyfixest/fepois.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(
self._check_for_separation()

self._support_crv3_inference = False
self._support_iid_inference = False
self._support_iid_inference = True

# attributes that are updated outside of the class (not optimal)
self._N_separation_na = None
Expand Down Expand Up @@ -242,6 +242,7 @@ def compute_deviance(_Y, mu):

self._scores = self._u_hat[:, None] * self._weights * X_resid
self._hessian = XWX
self._T = self._weights * X_resid

if _convergence:
self._convergence = True
Expand Down Expand Up @@ -306,7 +307,8 @@ def _check_for_separation(self, check: str = "fe") -> None:
if check == "fe":
if not self._has_fixef:
pass

elif (self._Y > 0).all():
pass
else:
Y_help = pd.Series(np.where(self._Y.flatten() > 0, 1, 0))
fe = pd.DataFrame(self.fe)
Expand Down
2 changes: 0 additions & 2 deletions pyfixest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ def get_ssc(ssc_dict, N, k, G, vcov_sign, vcov_type):
elif vcov_type in ["iid", "CRV"]:
if adj:
adj_value = (N - 1) / (N - k)
else:
adj_value = 1
else:
raise ValueError("vcov_type must be either iid, hetero or CRV.")

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyfixest"
version = "0.9.11"
version = "0.9.12"


description = "(Not so) experimental draft package for high dimensional fixed effect estimation. Supports OLS, IV and Poisson regression and a range of inference procedures."
Expand Down
Binary file modified tests/__pycache__/test_errors.cpython-310-pytest-7.3.1.pyc
Binary file not shown.
Binary file not shown.
Binary file modified tests/__pycache__/test_plots.cpython-310-pytest-7.3.1.pyc
Binary file not shown.
Binary file not shown.
Binary file modified tests/__pycache__/test_vs_fixest.cpython-310-pytest-7.3.1.pyc
Binary file not shown.
Binary file modified tests/__pycache__/test_wildboottest.cpython-310-pytest-7.3.1.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions tests/check-crv-diffs-fixest-pyfixest-glm.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Check that `PyFixest` inference for CRV gets as close to `fixest` as `glm`.


```{python, messages = FALSE, warnings = FALSE}
import pyfixest as pf
from pyfixest.estimation import fepois
from pyfixest.utils import get_data

fml = "Y ~ X1 + X2"
Expand All @@ -21,7 +21,7 @@ data_list = []
for x in range(1000):

data = get_data(100, x, "2", "3", "Fepois").dropna()
fit = pf.Fixest(data = data).fepois(fml, vcov = {'CRV1':"group_id"}).fetch_model(0)
fit = fepois(fml, vcov = {'CRV1':"group_id"})
se_list.append(fit._se)
data_list.append(data)

Expand Down
15 changes: 6 additions & 9 deletions tests/test_vs_fixest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
@pytest.mark.parametrize("N", [1000])
@pytest.mark.parametrize("seed", [76540251])
@pytest.mark.parametrize("beta_type", ["1", "2", "3"])
@pytest.mark.parametrize("error_type", ["1", "2", "3"])
@pytest.mark.parametrize("dropna", [False, True])
@pytest.mark.parametrize("model", ["Feols", "Fepois"])
@pytest.mark.parametrize("error_type",["1", "2", "3"])
@pytest.mark.parametrize("dropna", [True, False])
@pytest.mark.parametrize("model", ["Fepois", "Feols"])
@pytest.mark.parametrize("inference", ["iid", "hetero", {"CRV1": "group_id"}])
@pytest.mark.parametrize(
"fml",
Expand Down Expand Up @@ -176,8 +176,8 @@ def test_single_fit(N, seed, beta_type, error_type, dropna, model, inference, fm
warnings.filterwarnings("ignore", category=RuntimeWarning)
iv_check = feols(fml=fml, data=data, vcov="iid")

if inference == "iid":
return pytest.skip("Poisson does not support iid inference")
#if inference == "iid":
# return pytest.skip("Poisson does not support iid inference")

if iv_check._is_iv:
is_iv = True
Expand Down Expand Up @@ -206,10 +206,7 @@ def test_single_fit(N, seed, beta_type, error_type, dropna, model, inference, fm

# relax tolerance for Poisson regression - effective rtol and atol of
# 5e-05
inference_inflation_factor = 100
# relax tolerance for CRV inference - effective rtol and atol of 5e-03
if isinstance(inference, dict):
inference_inflation_factor = 500
inference_inflation_factor = 50

try:
pyfixest = fepois(fml=fml, data=data, vcov=inference)
Expand Down
Loading