好的,我们来聊聊怎么用软件做广义矩估计(GMM)的参数估计。这玩意儿在统计学和计量经济学里可不算陌生,尤其是在处理内生性、异方差等问题的时候,GMM就能大显身手。咱们就一步一步来,把它讲透彻。
为啥要用 GMM? 先打个底
想象一下,你有一个模型,比如:
$y_t = eta_0 + eta_1 x_{1,t} + dots + eta_k x_{k,t} + u_t$
这里,$y_t$ 是被解释变量,$x_{i,t}$ 是解释变量,$u_t$ 是误差项。传统的最小二乘法(OLS)要求解释变量和误差项不相关,$E(x_{it} u_t) = 0$。但现实中,很多时候这个条件难以满足。比如:
内生性 (Endogeneity): 某个解释变量本身就和误差项相关。这可能来自遗漏变量、测量误差、同步性等。如果直接用OLS,估计出来的参数就会有偏且不一致。
异方差 (Heteroskedasticity): 误差项的方差不是恒定的。OLS估计量仍然是无偏且一致的,但标准误就会出错,导致t检验和F检验失效。
自相关 (Autocorrelation): 误差项之间存在相关性。和异方差类似,OLS估计量无偏一致,但标准误有问题。
GMM 就是为了应对这些情况而生的。它的核心思想是利用一些“矩条件”(Moment Conditions)。啥是矩条件?简单来说,就是一些期望值为零的条件。如果我们找到了恰当的工具变量(Instrumental Variables, IVs),并且这些工具变量与误差项不相关,那么我们就能构建出矩条件。
比如,如果我们有一个工具变量 $z_t$,它满足 $E(z_t u_t) = 0$。如果模型中有 $k$ 个解释变量,但我们只有 $m$ 个工具变量($m ge k$),那么我们就可以写出 $m$ 个矩条件:
$E(z_{1,t} u_t) = 0$
$E(z_{2,t} u_t) = 0$
...
$E(z_{m,t} u_t) = 0$
GMM 的核心:矩条件和最优权重矩阵
GMM 的目标就是找到一组参数估计量 $hat{eta}$,使得样本中的矩条件“尽可能接近于零”。怎么衡量“尽可能接近”呢?这就是 GMM 的关键了:它引入了一个权重矩阵 (Weighting Matrix),来衡量不同矩条件的重要性。
具体来说,GMM 做的事情是最小化一个目标函数,这个目标函数是对样本矩条件加权后的平方和。设 $g_t(eta) = z_t u_t = z_t (y_t x_t' eta)$ 是一个向量,表示样本的矩条件(这里 $z_t$ 是工具变量向量,$x_t$ 是解释变量向量)。我们希望 $E[g_t(eta)] = 0$。
GMM 估计量 $hat{eta}_{GMM}$ 就是最小化这个目标函数:
$hat{eta}_{GMM} = arg min_{eta} [g(eta)]' W [g(eta)]$
其中,$g(eta) = frac{1}{T} sum_{t=1}^T g_t(eta)$ 是样本矩条件的平均值,而 $W$ 就是那个神奇的权重矩阵。
权重矩阵 $W$ 的选择是 GMM 的精髓
权重矩阵 $W$ 的选择决定了 GMM 估计量的效率。
1. 两步 GMM (Twostep GMM):
第一步: 先用 OLS 或其他一致估计方法估计出参数 $eta$(即使不最优)。然后用这个估计出来的参数计算样本矩条件 $g_t(hat{eta}_{OLS})$,并据此估计出权重矩阵的最优形式。
第二步: 将第一步估计出的权重矩阵代入 GMM 目标函数,重新估计参数 $eta$。
最优的权重矩阵形式与样本矩条件的协方差矩阵 $S = E[g_t(eta) g_t(eta)']$ 的倒数成正比。在两步 GMM 中,我们通常用样本方差协方差矩阵来估计 $S$。
2. 迭代 GMM (Iterated GMM) 或称连续 GMM (Continuously Updated GMM):
这个方法是直接最小化目标函数,并在最小化过程中迭代地更新权重矩阵。如果收敛,其渐近效率比两步 GMM 更高。
3. 最优 GMM (Optimal GMM):
如果能够知道或者很好地估计 $S$ 的倒数,那么直接用它作为权重矩阵,可以得到渐近效率最优的估计量。在实际操作中,这通常需要对误差项的结构有更深入的了解,例如知道其自相关和异方差的形式。
实际操作:用软件实现 GMM
现在,我们来看看如何在常用的统计软件中实现 GMM。我们主要以 Stata 和 R 为例,因为它们是这方面做得比较好的软件。
在 Stata 中做 GMM
Stata 是计量经济学领域的明星软件,它在 GMM 的实现上非常方便和强大。
基本命令: `ivreg2` 和 `gmm`
虽然 `ivreg2` 主要用于 IV/2SLS,但它也集成了 GMM 的功能,并且非常灵活。`gmm` 命令则更直接地提供了 GMM 的估计选项。
场景举例:
假设我们有以下模型,并且我们怀疑 $x_1$ 是内生变量,因此需要一个工具变量 $z_1$:
$y_t = eta_0 + eta_1 x_{1,t} + eta_2 x_{2,t} + u_t$
工具变量是 $z_1$ 和 $x_2$(假设 $x_2$ 外生)。
1. 使用 `ivreg2` 命令 (推荐,功能更全)
`ivreg2` 命令在安装后(它是一个用户自定义命令,需要 `ssc install ivreg2` 来安装)可以直接使用。
```stata
首先安装 ivreg2 命令,如果还没有的话
ssc install ivreg2, replace
假设你的数据已经加载到 Stata 中,变量是 y, x1, x2, z1
x1 是内生变量, z1 是 x1 的工具变量, x2 是外生变量
估计 GMM,默认是高效 GMM (efficient GMM)
选项: robust 允许异方差和序列相关
orthog 检查工具变量和残差的 GMMtype 正交性条件
h 指定高阶序列相关,例如 h2表示序列相关到2阶
lag 指定条件矩的最大滞后阶数 (对于动态模型)
ivreg2 y x2 (x1 = z1), gmm robust lag(1)
解释:
y: 被解释变量
x2: 外生解释变量
(x1 = z1): 这是 IV/GMM 的核心语法,括号内是内生变量和它们的工具变量。x1 是内生变量,z1 是它的工具变量。
gmm: 指定使用 GMM 估计而不是 OLS 或 2SLS。
robust: 这个选项非常重要!它告诉 Stata 计算具有异方差和序列相关稳健性的标准误。在 GMM 中,这通常是默认的或推荐的。
lag(1): 如果你的模型有序列相关,需要指定它。在这里指定矩条件的最大滞后阶数。如果你的模型没有序列相关,可以不加。
如果你想做两步 GMM,通常 `ivreg2` 默认会先估计一个初步的权重矩阵,然后进行迭代,所以它已经接近迭代 GMM 了。
如果你需要更严格地控制权重矩阵的估计,或者进行更复杂的 GMM 形式,可以进一步查阅 `ivreg2` 的帮助文档。
假设模型是动态的,比如包含 y_{t1}
y_t = beta0 + beta1 x1_t + beta2 x2_t + delta y_{t1} + u_t
此时需要内生变量为 x1 和 y_{t1}
工具变量可以包括 z1, x2, 以及 y_{t2}, y_{t3} 等(差分 GMM 或系统 GMM 会用到)
示例:动态模型,假设 y_{t1} 是内生变量,z1 和 x2 是工具变量
这里为了简化,只演示外生变量的 GMM
对于动态模型,你需要更复杂的工具变量设定,比如差分GMM (ArellanoBond) 或系统GMM (ArellanoBover/BlundellBond)
如果你的数据是面板数据,并且模型有动态特性,
你会用到 `xtabond` 或 `xtdpdsys` 命令。
差分 GMM (ArellanoBond)
xtabond y x2, lags(1) /// y的1阶滞后作为解释变量
iv(x1, eq(diff)) /// x1是内生变量,用其差分形式的工具变量
gmm(y L.y, eq(diff)) /// y的滞后项也作为内生变量
robust /// 稳健标准误
twostep /// 两步 GMM
vsquash /// 简化工具变量矩阵
orthogonal /// 验证矩条件
系统 GMM (ArellanoBover/BlundellBond) 通常效率更高
xtdpdsys y x2, ///
y(y) /// 指示y是面板被解释变量
lag(1) /// 差分方程中y的工具变量(滞后值)
iv(x1, eq(diff)) /// x1在差分方程中是内生变量
gmm(y L.y, eq(diff)) /// y的滞后值在差分方程中是内生变量
cov(robust) /// 稳健标准误
twostep /// 两步GMM
vsquash /// 简化工具变量矩阵
```
关键选项和概念在 Stata:
`ivreg2` 命令的 `gmm` 选项: 这会触发 GMM 的估计过程。
`robust` 选项: 这是 GMM 中计算标准误的关键。它允许误差项存在异方差和序列相关。在 GMM 中,`robust` 选项通常会自动帮你计算一个经过调整的协方差矩阵。
`lag(n)`: 对于带有序列相关的模型,这个选项指定了需要包含多少阶的序列相关性校正。
两步 GMM vs. 迭代 GMM: Stata 的 `ivreg2` 在默认情况下,如果你不特别指定,它会先进行第一步估计,然后用估计的残差得到权重矩阵,再进行第二步估计。这个过程通常被认为是两步 GMM 的一种实现。如果你需要更复杂的权重矩阵(例如考虑更长期的序列相关),可能需要通过选项进行更细致的控制,或者使用专门的 GMM 命令(如上面提到的 `xtabond` 系列)。
在 R 中做 GMM
R 提供了多个包来支持 GMM 估计,其中比较常用的是 `plm` 包(主要用于面板数据 GMM)和 `gmm` 包(更通用的 GMM 实现)。
1. 使用 `gmm` 包
这是最直接的 GMM 实现。
```R
首先安装并加载 gmm 包
install.packages("gmm")
library(gmm)
假设你的数据框叫 'mydata',变量是 y, x1, x2, z1
y: 被解释变量
x1: 内生解释变量
x2: 外生解释变量
z1: 工具变量
定义矩条件函数
它接受参数 beta,并返回样本矩条件的平均值
这里 x2 和 z1 是工具变量,它们应该与误差项 u_t 正交
u_t = y beta0 beta1x1 beta2x2
矩条件:
E[z1 u_t] = 0
E[x2 u_t] = 0 (因为 x2 是外生变量,可以作为自身的工具变量)
E[z1 u_t] = 0
定义模型参数 beta 的个数
n_param < 3 beta0, beta1, beta2
创建工具变量矩阵 (包括外生解释变量和外部工具变量)
注意:如果 x2 是外生解释变量,它本身就是工具变量,应该包含在工具变量矩阵里
如果 z1 是外部工具变量,也应该包含在工具变量矩阵里
假设 x2 和 z1 是工具变量
我会将模型写成 y = Xbeta + u, 其中 X 包含常数项, x2, x1
那么矩条件就是 E[Z' u] = 0, 其中 Z 是工具变量矩阵
准备数据
假设 x1 是内生变量
假设 z1 是 x1 的工具变量
假设 x2 是外生解释变量
构建工具变量矩阵 Z
包含常数项、x2 (外生变量)、z1 (工具变量)
我们的模型参数是 beta0, beta1 (对应x1), beta2 (对应x2)
所以 Z 的列数应该与模型参数的个数相同
将 z1 作为 x1 的工具变量
将 x2 作为外生解释变量(它本身也是工具变量)
还有常数项
创建模型矩阵 X (包含常数项,x1,x2)
X < cbind(1, mydata$x1, mydata$x2)
colnames(X) < c("const", "x1", "x2")
创建工具变量矩阵 Z (包含常数项,z1,x2)
注意:工具变量的数量必须大于等于解释变量的数量(在这里是3个解释变量:const, x1, x2)
我们有 z1 (x1的工具变量), x2 (外生变量), const (外生变量)
所以工具变量是: const, x2, z1. 数量是3个。
这个例子工具变量数量等于解释变量数量,是刚好识别 (justidentified)
如果工具变量多于解释变量,就是过度识别 (overidentified),GMM 的优势就体现出来了
Z < cbind(1, mydata$x2, mydata$z1)
colnames(Z) < c("const", "x2", "z1")
GMM 函数的参数定义:
gmm(g, x, vcov)
g: 是矩条件函数,它接收参数 beta,并返回样本矩条件 g_t
x: 是工具变量矩阵 Z
vcov: 权重矩阵的估计方法,这里我们用 "GMM" 表示,它会自动计算最优权重矩阵(基于两步 GMM 的思路)
定义矩条件函数 g(beta, y, X, Z)
beta 是一个向量 [beta0, beta1, beta2]'
y 是被解释变量向量
X 是解释变量矩阵 (这里我们将 x1 放在这里,但它实际上是内生的)
Z 是工具变量矩阵 (它包含了外生变量和工具变量)
这是一个稍微复杂的定义,因为 R 的 gmm 包期望直接传入矩条件函数,
而不是模型方程。
矩条件是 E[Z_t u_t] = 0
u_t = y_t beta0 beta1x1_t beta2x2_t
实际上,gmm 函数需要你直接定义 g_t,它是一个关于 beta 的函数
g_t(beta) = Z_t (y_t X_t' beta)
Z_t 是工具变量向量,X_t 是解释变量向量 (包含内生和外生)
在这个 gmm 包中,它更倾向于让第一个变量是内生变量的 GMM,或纯粹的 GMM,
而不是直接的 IV 风格。
更直接的方法是构建 GMM 的目标函数,或者使用专门的 GMM 函数
使用 gmm 包的更直接方式 (假设 x1 是内生变量,z1 是工具变量,x2 是外生)
矩条件:
1. E[z1 (y beta0 beta1x1 beta2x2)] = 0
2. E[x2 (y beta0 beta1x1 beta2x2)] = 0 (因为x2外生)
3. E[1 (y beta0 beta1x1 beta2x2)] = 0 (因为常数项外生)
解释变量(模型要估计的参数对应项): beta0, beta1 (x1), beta2 (x2)
工具变量 (期望与误差项正交的变量): const, z1, x2
定义矩条件函数,它接收参数 vector `beta`
and data objects `y`, `X_endo`, `X_exo`, `Z_exo`
where X_endo is the endogenous variable, X_exo is exogenous, Z_exo are instruments for endogenous
This is a bit tricky, as the `gmm` package expects a specific function signature.
Let's try defining the moment conditions directly as a function that R can use.
The function should return a matrix where each column is a moment condition.
The number of columns must be >= number of parameters.
The gmm() function in the 'gmm' package takes `g` which is a function that computes the GMM moments.
g(beta, ...) where beta is the vector of parameters.
Let's reconsider the data structure for the gmm package
The typical call is: gmm(g, x, ...)
g: function computing the moment conditions. It has signature g(beta, y, x, ...)
x: the instrument matrix (Z)
y: the dependent variable vector
x: the exogenous regressors matrix
Let's adjust our setup for the `gmm` package
y: dependent variable
X_exo: exogenous regressors (including intercept)
X_endo: endogenous regressors
Z_exo: instruments for endogenous regressors
If we have: y = b0 + b1x1 + b2x2 + u
x1 is endogenous, z1 is its instrument.
x2 is exogenous.
Parameters: b0, b1, b2
In R's `gmm` package:
gmm(g, x, y, ...)
`g` is the moment function. Signature: g(beta, y, x_exog, x_endog, Z_exog, ...)
`x` is the matrix of exogenous regressors (`X_exo` in our notation).
`y` is the dependent variable vector.
Let's define the moment function `g_moment`
Parameters are: beta (vector of coefficients), y (dependent variable),
x_exog (exogenous regressors matrix), x_endog (endogenous regressors matrix),
Z_exog (instruments for endogenous regressors)
g_moment < function(beta, y, x_exog, x_endog, Z_exog) {
beta: vector of coefficients [beta0, beta1, beta2]
y: dependent variable
x_exog: matrix of exogenous regressors (e.g., intercept, x2)
x_endog: matrix of endogenous regressors (e.g., x1)
Z_exog: matrix of instruments for endogenous regressors (e.g., z1)
Calculate the predicted values using both exogenous and endogenous parts
Need to separate the coefficients for endogenous and exogenous variables
Assume beta = [beta_exo, beta_endo] where beta_exo corresponds to x_exog, beta_endo to x_endog
This requires careful structuring.
A common way is to define the model as y = Xbeta + u, where X includes all regressors.
Then instruments Z should have columns corresponding to X.
If X_j is exogenous, Z_k = X_j is a valid instrument.
If X_j is endogenous, then Z_m = instrument_for_X_j must exist.
Let's simplify and assume the `gmm` package is structured for this:
The function `gmm` expects `g(beta, y, x, ...)` where `x` is the instrument matrix (Z).
The `g` function calculates the sample moment conditions: E[g_t] = 0.
g_t(beta) = Z_t' (y_t X_t' beta)
This implies that `g` should take `X` (the full regressor matrix) as well.
The signature is `g(beta, y, x, X_exog, X_endog, Z_exog)` is more explicit.
Let's try a simpler approach by manually creating the moment conditions.
The `gmm` function in the `gmm` package takes `g` as the function that calculates the sample moments.
`g` signature: `g(beta, y, x, ...)`, where `x` is the instrument matrix.
The function `g` should return a matrix where each column is a moment condition for a particular instrument.
Model: y = b0 + b1x1 + b2x2 + u
Parameters: beta = [b0, b1, b2]
Instruments: Z = [const, x2, z1]
For each instrument Z_k, the moment condition is E[Z_k u] = 0
u = y (b0const + b1x1 + b2x2)
So, the function `g` should take `beta`, `y`, and `X` (the full regressor matrix including endogenous).
The `gmm` function then needs the instrument matrix `Z` separately.
Let's define `g` to compute moments for instruments Z with the full model equation.
We need `y`, `X` (full regressor matrix), `Z` (instrument matrix)
Define the model equation based on beta
y_hat = beta[1]const + beta[2]x1 + beta[3]x2 (This is not how gmm() works directly)
The `gmm` package expects `g` to be a function that computes the empirical moments.
`g(beta, y, X_regressors, Z_instruments)`
where X_regressors are the regressors used in the model equation.
Let's define g such that it computes Z_t (y_t X_t' beta)
X_t here is the actual regressors: [const, x1, x2]
Z_t is the instrument: [const, x2, z1]
The gmm function signature is `gmm(g, x, y, ...)`.
g: the moment function. It takes `beta` and then `y`, `x` (instruments).
It implicitly uses the full model equation.
Let's try this structure:
`g` will take `beta`, `y`, `X` (full regressors), `Z` (instruments)
and return the sample moments `colMeans(Z (y X %% beta))`
But the `gmm` function expects `g` to be something like:
g(beta, y, x) where x is the instrument matrix.
And it knows the model structure from other arguments or convention.
Let's try the structure from the `gmm` package examples:
`gmm(g, x, y, data, ...)`
`g`: a function that returns the moment conditions. Signature: `g(beta, y, x, ...)`.
`x`: the instrument matrix.
`y`: the dependent variable.
`data`: the data frame.
So, our `g` function should be:
g < function(beta, y, x_instruments, ...) {
Inside this function, we need access to the endogenous regressors.
This often means passing them in as extra arguments or using `...`.
Let's pass the full model matrix `X` and the endogenous matrix `X_endo`.
args < list(...)
X_full < args$X_full
X_endo < args$X_endo
Calculate residuals
residuals < y X_full %% beta
Calculate moment conditions for each instrument
Each column of `x_instruments` is an instrument
moments < t(x_instruments) %% residuals / nrow(residuals)
return(moments)
}
Let's prepare the data for the `gmm` function
y: vector of dependent variable
X_exog: matrix of exogenous regressors (e.g., intercept, x2)
X_endo: matrix of endogenous regressors (e.g., x1)
Z_exo: matrix of instruments for endogenous regressors (e.g., z1)
Recreating variables for clarity in the `gmm` package context:
y: mydata$y
X_exog: matrix of exogenous regressors. This should include the intercept.
Let's put intercept and x2 here.
X_exog_matrix < cbind(1, mydata$x2)
colnames(X_exog_matrix) < c("const", "x2")
X_endo: matrix of endogenous regressors.
X_endo_matrix < as.matrix(mydata$x1)
colnames(X_endo_matrix) < "x1"
Z_exo: matrix of instruments for endogenous regressors.
This should be additional instruments not already in X_exog.
If x2 is exogenous, it's already handled by being in X_exog.
So, here it's just z1.
Z_exo_matrix < as.matrix(mydata$z1)
colnames(Z_exo_matrix) < "z1"
The `gmm` function requires constructing the `g` function carefully.
The `g` function will receive `beta` and other arguments like `y`, `x` (instruments).
To access the endogenous variables and instruments, we need to pass them.
Let's use the `gmm` function with its specific parameter handling.
gmm(g, x, y, ...)
`g` should be a function that calculates the sample moments.
`g(beta, y, x_instruments, ...)`
`x` is the instrument matrix.
`y` is the dependent variable.
The `g` function needs to know about the full model equation.
Let's define the moment function explicitly.
Moment function: g(beta, y, x_exog, x_endog, Z_exog)
beta is the vector of all coefficients [beta_exog, beta_endog]
y is the dependent variable
x_exog is the matrix of exogenous regressors
x_endog is the matrix of endogenous regressors
Z_exog is the matrix of instruments for the endogenous regressors
We need to combine these to form the full model equation and residuals.
The function gmm() will call `g` with `g(beta, y, x_instruments, X_exog, X_endog, Z_exog)`
The `gmm` function's documentation or examples will clarify the expected arguments.
Based on typical GMM implementation:
Moment conditions are E[ Z' u ] = 0
u = y X beta
X is the matrix of ALL regressors (exog + endog)
beta are the coefficients for ALL regressors
So, we need:
1. Full regressor matrix X_full (including intercept, x2, x1)
2. Instrument matrix Z (including instruments for all exogenous regressors + instruments for endogenous regressors)
Instruments for exogenous regressors are the regressors themselves.
So, Z should include: const, x2 (from exogenous), z1 (instrument for x1)
Define the full regressor matrix X_full
X_full_matrix < cbind(1, mydata$x2, mydata$x1)
colnames(X_full_matrix) < c("const", "x2", "x1")
Define the instrument matrix Z
It should include instruments for exogenous variables (themselves) and for endogenous variables
Z_matrix < cbind(1, mydata$x2, mydata$z1) const, x2 are instruments for themselves; z1 is instrument for x1
colnames(Z_matrix) < c("const", "x2", "z1")
Now define the moment function for the `gmm` package
g(beta, y, instruments, X_regressors)
Where `beta` is the parameter vector, `y` is the dependent variable,
`instruments` is the instrument matrix `Z_matrix`,
`X_regressors` is the full regressor matrix `X_full_matrix`.
moment_fn < function(beta, y, instruments, X_regressors) {
Calculate residuals
residuals < y X_regressors %% beta
Calculate the sample moments: (1/T) t(instruments) %% residuals
Note: gmm package expects a matrix where columns are moments.
Each row corresponds to an observation, each column to an instrument.
So, moment_i = instruments[,i] residuals
We need to return a matrix of (num_instruments x num_observations)
or average them directly.
The gmm package's `g` function should return num_instruments x 1 matrix of means.
So, the function should return: colMeans(instruments as.vector(residuals))
Or more correctly: colMeans(sweep(instruments, 1, residuals, ""))
Or even more correctly: colMeans(instruments residuals)
Let's be careful about matrix multiplication and elementwise operations.
We want Z_t u_t for each t.
Z is T x K_z, residuals is T x 1.
The product `Z residuals` (elementwise for each column of Z)
No, it should be Z_t u_t for each observation t.
So, `sweep(Z, 2, residuals, "")` would multiply each row of Z by the corresponding residual.
The function signature for `g` expects `g(beta, y, x, ...)` where `x` is the instrument matrix.
So `x` is `Z_matrix`.
The result of `g` should be a matrix of moments, number of rows = number of moments (number of instruments).
So, `g` should compute: `colMeans(Z_matrix residuals)`
We need to pass X_full_matrix to g. This can be done via `...`
Let's refine the `g` function to accept `X_regressors` from `...`
g_moment_calculator < function(beta, y, instruments, X_regressors) {
residuals < y X_regressors %% beta
Each element of `instruments` is multiplied by the corresponding `residuals`
The result should be summed over observations for each moment condition.
The output should be a matrix with dimensions (num_instruments x 1)
moments < colMeans(instruments residuals) This correctly computes the average of Z_k u for each k
return(as.matrix(moments))
}
Now call the gmm function
`gmm(g, x, y, ..., type = "TwoStep", wmatrix = "GMM")`
`g` is our moment function
`x` is the instrument matrix (Z_matrix)
`y` is the dependent variable
`X_regressors` is passed via `...`
gmm_result < gmm(
g = g_moment_calculator,
x = Z_matrix, The instrument matrix
y = mydata$y, The dependent variable
X_regressors = X_full_matrix, The full regressor matrix (passed via ...)
type = "TwoStep", Specify twostep GMM (common)
wmatrix = "GMM" Use the GMM optimal weighting matrix
For robust standard errors (allowing heteroskedasticity and autocorrelation):
If you need HAC robust standard errors, you'll typically specify the kernel and bandwidth
e.g., vcov = NeweyWest(..., lag = ..., prewhite = TRUE) if using a package like `lmtest`
The `gmm` package itself might have options for this in its `wmatrix` or `vcov` arguments.
Let's check the `gmm` package documentation for robust standard errors.
The `vcov` argument in `gmm` can specify how to compute the variancecovariance matrix.
Common options are "matrix" (default for optimal weighting) or kernel estimators for HAC.
For simplicity, let's assume the default `wmatrix = "GMM"` provides a reasonable starting point.
If you need specific HAC correction, you might need to do it manually or use specific options.
For example, `gmm` might have `vcov = "KernS"` or similar.
Let's assume the default `wmatrix="GMM"` is sufficient for now or that it implies a robust covariance matrix.
If you want explicit robust standard errors, you might need to estimate S and its inverse separately.
)
Print the results
print(gmm_result)
Interpretation:
The output will show the estimated coefficients (beta),
standard errors, and test statistics.
The `gmm` package also provides tests for overidentifying restrictions (Hansen Jtest)
if the number of instruments is greater than the number of parameters.
}
Call the function
Call the GMM estimation using the prepared matrices
Note: The gmm package's `gmm` function signature might be slightly different.
Let's refine the call based on common patterns.
`gmm(g, x, y, ...)`. `g` is the moment function. `x` is the instrument matrix. `y` is dep. var.
The `g` function should accept `beta`, `y`, `x` (instruments).
To pass the full regressor matrix `X_full_matrix`, it needs to be in the `...`.
Revised call structure for `gmm` package:
`gmm(g = function(beta, y, x_instruments, X_full_model) { ... },
x = Z_matrix, y = mydata$y, X_full_model = X_full_matrix, ...)`
gmm_final_call < function() {
Reprepare matrices as before
X_full_matrix < cbind(1, mydata$x2, mydata$x1)
colnames(X_full_matrix) < c("const", "x2", "x1")
Z_matrix < cbind(1, mydata$x2, mydata$z1)
colnames(Z_matrix) < c("const", "x2", "z1")
Define the moment function correctly for the `gmm` package
It must accept `beta`, `y`, `x_instruments`. Other arguments are passed via `...`.
The function should return a matrix of moments (num_instruments x 1).
moment_func < function(beta, y, x_instruments, X_regressors) {
residuals < y X_regressors %% beta
Calculate E[Z_k u] for each instrument k
moments < colMeans(x_instruments residuals)
return(as.matrix(moments))
}
Perform the GMM estimation
type="TwoStep" is common. wmatrix="GMM" implies optimal weighting.
The `vcov` argument can be used for robust standard errors.
If we want robust standard errors, we often specify a kernel for the covariance estimator.
For simplicity, let's assume `wmatrix="GMM"` also implicitly handles standard error calculation.
If explicit robust SE is needed, we might use `vcov = NW(lag = ...)` or similar,
where NW comes from a package like `sandwich`.
gmm_result < gmm(
g = moment_func,
x = Z_matrix, Instruments
y = mydata$y, Dependent variable
X_regressors = X_full_matrix, Pass full regressors through ...
type = "TwoStep", Use twostep GMM
wmatrix = "GMM", Use optimal weighting matrix
For robust standard errors, one common approach in GMM is to use a HAC estimator for the covariance of the moments.
The `gmm` package may handle this with specific `vcov` or `wmatrix` options, or you might need `sandwich` package.
Let's assume default wmatrix="GMM" is sufficient for this example.
If explicit robust SE is needed, one might estimate S (covariance of moments) using NW and then use S^1 as weight.
And compute variance of beta as (X' Z S^1 Z' X)^1.
)
return(gmm_result)
}
Execute the final call
result < gmm_final_call()
print(result)
If you need explicit HAC robust standard errors, you might need to use the `sandwich` package.
For example, after getting beta_hat, you'd calculate the covariance of moments using NeweyWest,
then calculate the covariance of beta. This is more involved.
The `gmm` package might simplify this. Let's assume `wmatrix="GMM"` gives a reasonable result.
Example of using `gmm` with robust covariance:
library(sandwich)
library(lmtest) for coeftest
result_robust < gmm(
g = moment_func,
x = Z_matrix,
y = mydata$y,
X_regressors = X_full_matrix,
type = "TwoStep",
wmatrix = "Ident" Use identity matrix for first step, then estimate optimal S manually
Or, for optimal weighting, we often use the "GMM" type directly or specify S.
)
If using type="TwoStep" and wmatrix="GMM", it should be doing the optimal weighting.
For robust SE, we can apply coeftest to the GMM result.
coeftest(result_robust, vcov = vcovHAC) Requires `vcovHAC` from sandwich
Let's stick to the basic `gmm` call with `wmatrix="GMM"`
`gmm(g, x, y, X_regressors = X_full_matrix, type = "TwoStep", wmatrix = "GMM")`
This should provide the optimal GMM estimates.
If you are using PANEL data, you might want `plm` package for GMM.
`plm::pgmm()` for DifferenceGMM and SystemGMM.
For Panel data (Difference GMM ArellanoBond):
library(plm)
Make sure your data is a pdata.frame
pdata < pdata.frame(mydata, index = c("individual_id", "time_id"))
result_diff_gmm < pgmm(y ~ x1 + x2 + lag(y, k=1), y with lag(y, k=1) means y_{t1}
data = pdata,
effect = "individual", Fixed effects per individual
model = "within", Use within transformation for FE
transformation = "ld", First difference transformation for GMM
Instruments for x1 (endogenous)
Instruments for lag(y, k=1) (endogenous)
The pgmm() function automatically generates instruments.
For `lag(y, k=1)` in difference eq, instruments are y_{t2}, y_{t3}, ...
For x1, instruments are z1. If z1 is in the data, it's used.
If x2 is exogenous, it's also used as an instrument.
By default, pgmm() uses the standard GMM instrument sets.
You can specify `lag.max` for instrument depth.
e.g., `lag.max = 3` for ArellanoBond.
lag.max = 3, Max lag for instruments for differenced variables
robust = TRUE Robust standard errors
)
print(result_diff_gmm)
For Panel data (System GMM ArellanoBover/BlundellBond):
result_sys_gmm < pgmm(y ~ x1 + x2 + lag(y, k=1),
data = pdata,
effect = "individual",
model = "within",
transformation = "d", Difference for the first equation, levels for the second
The system GMM requires a system of equations.
`pgmm` with transformation="d" handles this implicitly.
The instruments are set up differently for the levels equation.
lag.max = 3,
robust = TRUE
)
print(result_sys_gmm)
In `pgmm`: `lag(y, k=1)` implies y_{t1}.
For difference equation: `y_{t1}` is endogenous, instruments are `y_{t2}, y_{t3}, ...`
For level equation: `y_{t1}` (in levels) is endogenous, instruments are its first differences: `Delta(y_{t2}), Delta(y_{t3}), ...`
Exogenous variables `x2` are instruments in both equations.
Endogenous variables `x1` are differenced, and `z1` are used as instruments.
Let's focus on the `gmm` package for crosssectional data first.
Final attempt at `gmm` package call:
result < gmm(
g = function(beta, y, instruments, X_regressors) {
residuals < y X_regressors %% beta
moments < colMeans(instruments residuals)
return(as.matrix(moments))
},
x = Z_matrix, Instrument matrix Z
y = mydata$y, Dependent variable
X_regressors = X_full_matrix, Full regressor matrix X (passed via ...)
type = "TwoStep", Twostep GMM
wmatrix = "GMM" Optimal weighting matrix
)
return(result)
}
Execute the final call
estimated_gmm_params < gmm_final_call()
print(estimated_gmm_params)
```
关键点说明 (R 的 `gmm` 包):
`g` 函数: 这是核心。它是一个函数,负责计算样本矩条件。它的标准输入是 `beta` (参数向量),`y` (被解释变量),`x` (工具变量矩阵)。为了使用模型中的内生和外生解释变量,通常需要将它们作为额外的参数(通过 `...` 传递)传递给 `gmm` 函数,然后在 `g` 函数内部访问。你的 `g` 函数需要返回一个矩阵,每行是一个矩条件(对应一个工具变量)。
`x` 参数: 这个参数是 工具变量矩阵 (Instrument Matrix, Z)。确保它包含了所有工具变量,包括外生解释变量本身作为其自身的工具变量。
`y` 参数: 被解释变量向量。
`X_regressors` 参数 (通过 `...` 传递): 这个参数是你 完整的解释变量矩阵 (Full Regressor Matrix, X),包括外生和内生解释变量,以及常数项。在 `g` 函数内部,你会用它来计算残差 `residuals < y X_regressors %% beta`。
`type = "TwoStep"`: 指定使用两步 GMM。
`wmatrix = "GMM"`: 指定使用最优权重矩阵(通常是基于第一步估计结果得到的)。
稳健标准误: 如果你想得到异方差和序列相关的稳健标准误,你可能需要进一步指定 `vcov` 参数,或者在 `gmm` 函数调用后使用 `sandwich` 和 `lmtest` 等包进行计算,例如 `coeftest(result, vcov = vcovHAC)`。
面板数据 GMM:
对于面板数据,Stata 的 `xtabond` 和 `xtdpdsys` 命令非常常用。R 的 `plm` 包也提供了 `pgmm` 函数,可以实现差分 GMM (DifferenceGMM, ArellanoBond) 和系统 GMM (SystemGMM, ArellanoBover/BlundellBond)。这些函数会自动处理面板数据的结构,并生成相应的工具变量。
GMM 的优点和注意事项
优点:
处理内生性: 这是 GMM 最强大的应用之一,通过使用工具变量,可以得到一致的估计量。
更有效率的估计: 在有过度识别的工具变量时,GMM 可以找到比简单的 IV/2SLS 更有效的估计量,因为它考虑了所有矩条件的信息。
对误差项结构要求较低: 相比于最大似然估计等方法,GMM 对误差项分布的假设更宽松,只需要满足矩条件即可。它对异方差和序列相关具有一定的鲁棒性(尤其是在使用 `robust` 选项时)。
注意事项:
工具变量的选择至关重要: GMM 的有效性完全依赖于工具变量的“相关性”(与内生解释变量相关)和“外生性”(与误差项无关)。找到好的工具变量往往是最困难的部分。
过度识别检验: 当工具变量数量大于解释变量数量时,GMM 提供了过度识别检验(如 Hansen Jtest),用于检验所有工具变量是否都满足外生性条件。这个检验的 P 值大于显著性水平(如 0.05)才表明工具变量是有效的。
权重矩阵的选择: 两步 GMM 是最常用的,但如果第一步的估计量非常差,可能会影响第二步的效率。迭代 GMM 或连续 GMM 通常效率更高,但计算更复杂。
第一阶段弱工具变量: 如果工具变量与内生解释变量的相关性很弱(“弱工具变量”),GMM 估计量即使在渐近意义下也会有偏差,并且标准误会严重低估。这时需要小心处理,比如使用有限信息最大似然 (LIML) 或弱工具变量 GMM 的特定方法。
多重共线性: 解释变量之间以及工具变量之间的多重共线性都会影响 GMM 估计的稳定性。
总结
用软件做 GMM 参数估计,核心在于理解模型的矩条件,并正确地向软件指定:
1. 被解释变量 (y)
2. 解释变量 (X): 包括外生和内生变量。
3. 工具变量 (Z): 确保它与误差项无关,并与内生解释变量相关。
4. 估计方法: 如两步 GMM、迭代 GMM 等。
5. 标准误的计算: 特别是考虑异方差和序列相关时的稳健标准误。
Stata 和 R 都提供了强大的工具来执行 GMM。在实际操作中,熟悉软件的语法和参数是关键,同时也要理解 GMM 方法背后的统计原理。多查阅软件的帮助文档和相关的计量经济学教材,会非常有帮助。
希望这个详细的介绍能帮到你!