Ahn–Schmidt moments¶
Download the script: nonlinear.py
The problem. When y is persistent (ρ near 1), its lagged levels say little about its changes. Difference GMM’s instruments are then weak, and its estimates imprecise. Two remedies:
System GMM adds the levels equation. But it needs the panels to start near their long-run means, a stationarity assumption.
Ahn and Schmidt (1995) showed that with serially uncorrelated errors the levels errors satisfy \(E[u_{iT}(u_{it} - u_{i,t-1})] = 0\). These are moments quadratic in the coefficients, valid without stationarity.
nl="noserial" adds them, one per period, or one with collapse=True.
These panels start far from their long-run means, so system GMM’s extra moments are invalid:
df = simulate_dynamic(5_000, 7, rho=(0.9,), stationary=False, seed=6)
difference GMM rho = 0.8608 (0.0231) Hansen p = 0.872
difference GMM + Ahn-Schmidt rho = 0.8993 (0.0166) Hansen p = 0.749
system GMM rho = 0.9095 (0.0041) Hansen p = 0.433
The true ρ is 0.9. The Ahn–Schmidt moments cut difference GMM’s standard error by about 30% and pull the estimate to the truth. System GMM’s estimate looks more precise than it is, because its moments do not hold here.
How it is fit, as xtdpdgmm’s nl():
The first step is a one-step GMM estimate with the nonlinear moments. Its weight matrix is the linear moments’ (Z’HZ)⁻¹. The nonlinear moments are treated as independent of them, each with weight 1 / (the number of panels) times
nl_weight(xtdpdgmm’sweight(), default 1). Withnl_weight=0the first step ignores them, and is the linear one-step estimate.The second step minimizes the full objective by Gauss–Newton. The objective is not convex; the result reports whether the step converged.
The standard errors have Windmeijer’s correction in its general, nonlinear form. A one-step fit (
steps=1) reports the first step’s sandwich variance.
Homoskedastic errors. nl="iid" uses Ahn and Schmidt’s moments for
errors that are also homoskedastic over time. These are
\(E[\bar u_i (u_{it} - u_{i,t-1})] = 0\) for every period, and the linear
\(E[y_{i,t-2}\Delta u_{i,t-1} - y_{i,t-1}\Delta u_{it}] = 0\). The linear ones
also need the other regressors to be predetermined or exogenous.
Matching xtdpdgmm. dpd-stream’s nl="noserial" estimates equal xtdpdgmm’s
to six digits (xtdpdgmm’s Gauss–Newton stops at about 1e-5), on balanced and on
unbalanced panels with gaps: with the default first step, with nl_weight=0,
and one-step. That checks the moments, the first-step weights, the solver and
the second step. Two rules matter in unbalanced panels, and both agree with
xtdpdgmm: the term \(u_{iT}\Delta u_{it}\) exists only if period \(t+1\) is
observed too, and every nonlinear moment has the same initial weight, 1 over
the number of panels, however many panels contribute to it. With
nl="iid" the same holds (balanced and unbalanced, to about 1e-5), once the
linear moments it adds are weighted as xtdpdgmm does: as instruments of the
differenced equation, within the linear block’s \(Z'HZ\) weight, not with the
nonlinear moments. System GMM matches too, with nl="noserial" and
nl="iid". Three differences remain:
Standard errors of the nonlinear fits differ by up to 3% (two-step; 7% one-step) on balanced panels and more on unbalanced ones (those of the linear fits agree exactly). The cause is xtdpdgmm’s: its stored second-step weight matrix equals ours entry by entry and its Hansen statistic agrees to seven digits, and our Jacobian of the moments satisfies the first-order condition at xtdpdgmm’s estimate (it is the exact derivative of the objective xtdpdgmm minimizes), but the variance xtdpdgmm reports is not the one that Jacobian gives. We keep the exact one. Treat the nonlinear standard errors as experimental when a few percent matter.
Forward orthogonal deviations: xtdpdgmm scales them by \((T-t)/(T-t+1)\), not by its square root as xtabond2 and dpd-stream do, so the two give different estimates whenever instruments are shared across periods (collapsed ones,
iv()). With one instrument per period the scale cancels. Thenlfits withtransform="fod"are therefore checked against the dense implementation, not against xtdpdgmm.Counts: xtdpdgmm reports the levels’ observations and panels, we the differenced rows and panels, and it counts the linear moments
nl(iid)adds among the linear ones.
The pdynmc package, which implements the same moments, agrees with dpd-stream’s one-step estimates once its one-moment-shorter set (it starts a period later) is matched.
When comparing with xtdpdgmm, note that its iv(w) with model(diff)
instruments with \(w\) itself; xtabond2’s, and dpd-stream’s, use \(\Delta w\).
iv(w, passthru=True) is xtdpdgmm’s.
The script
"""Ahn and Schmidt's nonlinear moment conditions, for persistent series.
python examples/nonlinear.py
When y is close to a random walk, its lagged levels are weak instruments
for its differences, and difference GMM is imprecise. Ahn and Schmidt's
moments, E[u_iT (u_it - u_i,t-1)] = 0 under no serial correlation, add
information without system GMM's stationarity assumption.
"""
from dpd_stream import dpd_stream
from dpd_stream.simulate import simulate_dynamic
# non-stationary initial conditions: system GMM's levels moments fail here
df = simulate_dynamic(5_000, 7, rho=(0.9,), stationary=False, seed=6)
P = ("id", "year")
F = "y ~ l(y, 1) + x + w | year | gmm(y, 2:4) + gmm(x, 1:3) + iv(w)"
for name, kw in [("difference GMM", {}),
("difference GMM + Ahn-Schmidt", dict(nl="noserial")),
("system GMM", dict(system=True))]:
r = dpd_stream(F if "system" not in name else F.replace("iv(w)", "iv(w, eq='diff')"),
df, panel=P, verbose=False, **kw)
print(f"{name:30s} rho = {r.beta[0]:.4f} ({r.se[0]:.4f}) Hansen p = {r.hansen['p']:.3f}")