Introduction¶
Panel data includes observations on multiple entities – individuals, firms, countries – over multiple time periods. In most classical applications of panel data the number of entities, N, is large and the number of time periods, T, is small (often between 2 and 5). Most asymptotic theory for these estimators has been developed under an assumption that N will diverge while T is fixed.
Most panel models are designed to estimate the parameters of a model which can be described
where i indexes the entities and t indexes time. \(\beta\) contains the parameters of interest. \(\alpha_i\) are entity-specific components that are not usually identified in the standard setup, and so cannot be consistently estimated and \(\epsilon_{it}\) are idiosyncratic errors uncorrelated with \(\alpha_i\) and the covariates \(x_{it}\).
All models require two inputs
dependent- The variable to be modeled, \(y_{it}\) in the modelexog- The regressors, \(x_{it}\) in the model.
and use different techniques to address the presence of \(\alpha_i\).
In particular,
PanelOLSuses fixed effect (i.e., entity effects) to eliminate the entity specific components. This is mathematically equivalent to including a dummy variable for each entity, although the implementation does not do this for performance reasons.BetweenOLSaverages within an entity and then regresses the time-averaged values using OLS.FirstDifferenceOLStakes the first difference to eliminate the entity specific effect.RandomEffectsuses a quasi-difference to efficiently estimate \(\beta\) when the entity effect is independent from the regressors. It is, however, not consistent when there is dependence between the entity effect and the regressors.PooledOLSignores the entity effect and is consistent but inefficient when the effect is independent of the regressors.
PanelOLS is somewhat more general than the
other estimators and can be used to model 2 effects (e.g., entity and time
effects).
Model specification is similar to statsmodels. This example estimates a fixed effect regression on a panel of the wages of working men modeling the log wage as a function of squared experience, a dummy if the man is married and a dummy indicating if the man is a union member.
from linearmodels.panel import PanelOLS
from linearmodels.datasets import wage_panel
import statsmodels.api as sm
data = wage_panel.load()
data = data.set_index(['nr','year'])
dependent = data.lwage
exog = sm.add_constant(data[['expersq','married','union']])
mod = PanelOLS(dependent, exog, entity_effects=True)
res = mod.fit(cov_type='unadjusted')
res
While the result contains many properties containing specific quantities of
interest (e.g., params or tstats), the string representation of the
result is a summary table.
PanelOLS Estimation Summary
================================================================================
Dep. Variable: lwage R-squared: 0.1365
Estimator: PanelOLS R-squared (Between): -0.0674
No. Observations: 4360 R-squared (Within): 0.1365
Date: Wed, Apr 19 2017 R-squared (Overall): 0.0270
Time: 17:48:58 Log-likelihood -1439.0
Cov. Estimator: Unadjusted
F-statistic: 200.87
Entities: 545 P-value 0.0000
Avg Obs: 8.0000 Distribution: F(3,3812)
Min Obs: 8.0000
Max Obs: 8.0000 F-statistic (robust): 200.87
P-value 0.0000
Time periods: 8 Distribution: F(3,3812)
Avg Obs: 545.00
Min Obs: 545.00
Max Obs: 545.00
Parameter Estimates
==============================================================================
Parameter Std. Err. T-stat P-value Lower CI Upper CI
------------------------------------------------------------------------------
const 1.3953 0.0123 113.50 0.0000 1.3712 1.4194
expersq 0.0037 0.0002 19.560 0.0000 0.0033 0.0041
married 0.1073 0.0182 5.8992 0.0000 0.0717 0.1430
union 0.0828 0.0198 4.1864 0.0000 0.0440 0.1215
==============================================================================
F-test for Poolability: 9.3360
P-value: 0.0000
Distribution: F(544,3812)
Included effects: Entity
Like statsmodels, panel models can be specified using a R-like formula. This model
is identical to the previous. Note the use of the special variable EntityEffects
to include the fixed effects.
mod = PanelOLS.from_formula('lwage ~ 1 + expersq + union + married + EntityEffects',data)
Models with Only Effects¶
A PanelOLS model can have effects and no
regressors, \(y_{it} = \alpha_i + \epsilon_{it}\). The formula has no
regressors, or exog has the index of dependent and no columns.
import pandas as pd
mod = PanelOLS.from_formula('lwage ~ EntityEffects', data)
# The same model, without a formula
mod = PanelOLS(dependent, pd.DataFrame(index=data.index), entity_effects=True)
res = mod.fit()
The model has no parameters, so that params, cov and the other tables
of the parameters are empty. estimated_effects are the means of the dependent
variable of the entities (of the periods, with TimeEffects), and resids are
the deviations from them. f_pooled is the test that the effects are zero, which
for entity effects is the F-test of a one-way analysis of variance. The tests of
the coefficients, f_statistic and f_statistic_robust, are not defined. The
R-squared of the model is 0 (NaN if the dependent variable does not vary once the
effects are removed), and rsquared_inclusive is the share of the variation of the
dependent variable that the effects explain. See
PanelOLS for all of the results.
Specification Tests¶
The results of the panel models contain two specification tests. The Hausman test compares the random effects estimates with those of a model that is consistent if the effects are correlated with the regressors. The Pesaran CD test examines whether the idiosyncratic shocks are correlated across entities.
Hausman Test¶
The Hausman test [Hausman78] examines whether the effects are uncorrelated with the regressors, which is the assumption that random effects needs to be consistent. If the assumption is true, the random effects estimator is consistent and efficient, and the fixed effects estimator is consistent but not efficient. If it is not true, only the fixed effects estimator is consistent. The test statistic is a Wald statistic of the difference between the two sets of estimates,
where \(b_0\) and \(V_0\) are the coefficients and covariance of the model that is consistent whether or not the assumption is true, and \(b_1\) and \(V_1\) are those of the model that is efficient if it is true. The statistic has a \(\chi^2_k\) distribution, where \(k\) is the number of coefficients that are compared.
The test is a method of the results of a random effects model,
hausman(). Its argument
is the results of the other model, which is usually a fixed effects model.
from linearmodels.panel import RandomEffects
fe_res = PanelOLS(dependent, exog, entity_effects=True).fit()
re_res = RandomEffects(dependent, exog).fit()
re_res.hausman(fe_res)
Hausman specification test
H0: No systematic difference in coefficients between models
Statistic: 112.1182
P-value: 0.0000
Distributed: chi2(3)
Coefficients (b0: consistent under H0 and H1, b1: efficient under H0)
b0 b1 b0-b1 Std. Err.
expersq 0.003699 0.003192 0.000507 0.000054
married 0.107343 0.131555 -0.024212 0.006791
union 0.082762 0.103451 -0.020688 0.007007
The test rejects the null in this example, so there is evidence that the effects
are correlated with the regressors and that random effects is not consistent.
The test returns a
HausmanTestResults, which is a named tuple
with the fields statistic and estimates. They can be unpacked,
statistic, estimates = re_res.hausman(fe_res), or read as attributes. The
statistic is a WaldTestStatistic, and
estimates is a DataFrame. Its columns b0 and b1 contain the
coefficients of the other model and of the random effects model, and
Std. Err. is the standard error of their difference.
The test has requirements, which are checked.
Both models must use the unadjusted covariance estimator, which is the default in
fit. The variance of the difference of the estimates is the difference of their variances only if the random effects estimator is efficient, which requires homoskedastic errors. ATypeErroris raised if either model uses another covariance estimator.The models must be estimated using the same observations, the same dependent variable and the same weights. A
ValueErroris raised otherwise. The regressors are not compared. Only the coefficients that have the same name in both models are tested, and the constant is not included unlessinclude_constant=True.The covariance of the difference has to be positive definite. A warning is issued, and a generalized inverse is used, if it is not. If the statistic is negative or is not finite, an
InvalidTestStatisticis returned as the statistic. This can happen if the other model is a pooled model, whose unadjusted covariance ignores the effects.
By default, each model’s covariance is based on its own estimate of the error
variance. As in Stata’s hausman, sigmamore=True bases both covariances
on the estimate of the random effects model, and sigmaless=True bases both
on the estimate of the other model. They cannot be used together.
Effects that the other model has and the random effects model does not are not tested separately. If the other model has time effects and the random effects model does not, the null is that the regressors are uncorrelated with the entity effects and with the time effects, and the test can reject because of the time effects. To test the entity effects only, include dummy variables for the time periods as regressors in the random effects model. Their coefficients are not part of the test, since the other model does not have them.
This is not the Wu-Hausman test of the endogeneity of regressors in IV models,
wu_hausman().
Pesaran CD Test¶
The Pesaran CD test [Pesaran21] examines the null that the idiosyncratic shocks
are not correlated across entities. The statistic is the scaled sum of the
correlations between the shocks of each pair of entities, which are computed
using the periods that both have. It is asymptotically standard normal under
the null. The test is the property
pesaran_cd.
fe_res.pesaran_cd
Pesaran CD test
H0: Idiosyncratic shocks are cross-sectionally independent
Statistic: 7.8113
P-value: 0.0000
Distributed: N(0,1)
The statistic is computed from the idiosyncratic shocks of the model, which are
idiosyncratic in the results. The weights of a weighted model are not applied
to them. FirstDifferenceOLS is the exception.
It uses resids, the residuals of the differenced equation, as plm::pcdtest
does for a regression of the differenced data. Its idiosyncratic shocks are
in levels, and they are as persistent as the errors in levels, for example a
random walk, which is when first differences are used. The correlations are
computed over time, and so the test assumes that the shocks are not serially
correlated. It over-rejects if they are persistent.
The test is not valid for every model. For the following models
pesaran_cd returns an
InapplicableTestStatistic, and its
string says why.
BetweenOLS. The model is fitted to the entity means, so it has no residuals that vary over time.FamaMacBeth. The errors of the model are the residuals of the cross-sectional regressions of each period. The series that are implied by the average of the coefficients contain a common, time-varying term, so they are cross-sectionally dependent by construction. The inference of Fama-MacBeth is already robust to cross-sectional dependence.Models with time effects, and models with other effects that change over time for some entity and that have a group of several entities missing from some periods, for example period or industry-by-period effects. These effects demean the residuals across the entities that are observed in the same periods, which makes the residuals negatively correlated across entities and biases the statistic downwards [JuodisReese]. When the errors are independent and the model has time effects, the statistic is centered near \(-\sqrt{T/2}\) and its standard deviation is far below 1, where \(T\) is the number of periods. Effects that do not change over time for an entity, or that are present in every period, do not have this effect.
te_res = PanelOLS(dependent, exog, entity_effects=True, time_effects=True).fit()
print(te_res.pesaran_cd)
Irrelevant test statistic
The Pesaran CD test is not applicable to models with time effects. These effects demean the residuals across entities that are observed in the same periods, which makes the residuals negatively correlated across entities and biases the statistic downwards, away from its null distribution (Juodis and Reese, 2022).
Pesaran CD test
The statistic is computed from dense \(N\) by \(N\) matrices of the pairwise correlations and of the numbers of periods that the pairs have in common, where \(N\) is the number of entities. The memory that is needed is proportional to \(N^2\). It is about 450 MB when \(N\) is 4,000.