简介:动态面板空间杜宾模型是空间计量经济学中处理时空动态依赖的重要方法,相比传统静态模型,可同时捕捉空间溢出与时间滞后效应。这套资源面向经济学、地理学等领域从事空间回归分析的研究者与高年级学生,适合需要估计动态杜宾模型、检验空间交互作用的实证场景。压缩包共19个文件,大小337KB,以MATLAB脚本为主,包含模型估计、极大似然算法、空间权重矩阵构建与示例运行代码;另配有多份xlsx格式的实证数据(如高技术产业生产率与集聚数据)和PDF格式的模型推导说明,便于对照学习。目前已有1949人浏览学习,资源结构紧凑、代码注释较完整,可直接在MATLAB中调用或改编用于自己的面板数据。通过学习可掌握动态空间杜宾模型的设定、编程实现及与传统静态模型的区别,并可借助自带示例快速验证代码效果,节省自行编写程序的时间。
1. 动态面板空间杜宾模型:一张面板表里被忽略的时间与空间记忆
你手里有一份 30 个地区、15 年的面板数据,分别跑普通 OLS、静态空间杜宾模型和动态面板空间杜宾模型,会得到三套完全不同的解释。动态面板空间杜宾模型是在同一个回归方程里同时放进了时间惯性(Y_{t-1})、同期空间滞后(WY_t)、时间-空间滞后(WY_{t-1}),以及邻居解释变量的溢出项(WX_t),专门处理污染跨界、房价联动、区域金融溢出这类既有空间传播又有时间记忆的场景。不少同行把下载来的动态面板空间杜宾模型 rar 压缩包解压后直接复制代码,结果估计值和自己预想差得很远。问题大多不在代码本身,而在权重矩阵是否行标准化、面板样本排序有没有对齐、动态项选没选对。下面按“公式结构 → 最小复现 → 排查 → 检验”的顺序,把这条落地路径讲透。
2. 空间回归视角下的动态面板空间杜宾模型:三个滞后项分别代表什么
2.1 一个方程看懂四项:时间惯性、空间滞后、时空滞后与外生溢出
动态面板空间杜宾模型的标准写法是:
$$y_t = \tau y_{t-1} + \rho W y_t + \eta W y_{t-1} + X_t \beta + W X_t \theta + \alpha_i + \lambda_t + \epsilon_t$$
其中 $W$ 是行标准化的空间权重矩阵,$\alpha_i$ 是个体固定效应,$\lambda_t$ 是时间固定效应。很多入门者以为“动态”只是在面板回归里加一个滞后被解释变量,这是最大误解。真正把动态面板空间杜宾模型和静态 SDM 区分开的,是 $\eta W y_{t-1}$ 这一项:邻居上一期的 $y$ 值,通过空间权重矩阵加权后,传导到本地区本期的 $y$。这一项捕捉的是空间扩散过程中的滞后反馈,比如污染企业上一年在邻市排放,今年才随风向和水流影响到本市。
四个核心参数各有各的角色。$\tau$ 是时间惯性系数,衡量“去年高、今年也高”的惯性强弱;$\rho$ 是同期空间自回归系数,衡量本期邻居 $y$ 的平均水平对本地本期 $y$ 的影响;$\eta$ 是时空滞后系数,衡量邻居上一期 $y$ 对本地本期 $y$ 的影响;$\theta$ 是外生交互项系数,衡量邻居 $X$ 对本地 $y$ 的溢出。$\beta$ 则是本地解释变量的直接效应。
为什么偏偏选 SDM 而不是 SAR 或 SEM?因为 SAR 只放 $W y$,把邻居解释变量对被解释变量的影响全部吸收进空间自回归系数;SEM 则把空间相关性全部塞进误差项。SDM 同时放 $W y_t$、$W y_{t-1}$ 和 $W X_t$,是更完整的“上界模型”:当 $\theta = 0$ 时退化为 SAR,当 $\theta = -\rho \beta$ 时退化为 SEM。实际工作中我先估计 SDM,再用 LR 检验判断能否退化,而不是一上来就拍脑袋选 SAR。
2.2 权重矩阵怎么选:反距离、k 近邻、经济距离与行标准化
权重矩阵是空间回归里最容易翻车的部件,它的设定直接影响 $\rho$、$\eta$、$\theta$ 的估计和收敛性。常见做法是三类:反距离矩阵、k 近邻矩阵、经济距离矩阵。反距离矩阵设定 $w_{ij} = 1/d_{ij}$,超过某个阈值的邻居权重置为零,适合空气污染、流行病传播这类随地理距离衰减的场景;k 近邻矩阵只保留距离最近的 k 个邻居,权重可以等权也可以用距离倒数加权,适合交通流、零售网点分析;经济距离矩阵用 GDP 差距或贸易流强度构造权重,适合区域经济溢出研究。
选哪类矩阵不是玄学,核心依据是空间相关性的来源。比如研究城市房价联动,地理距离近的城市未必联动强,更多是“同等级城市”之间的模仿效应,这时经济权重或复合权重更合理。我一般先对 $y$ 做 Moran's I 检验和散点图,确认空间相关性存在后,再试 k=4 到 k=8 的几套权重矩阵做稳健性对比,不把宝押在一套矩阵上。
行标准化这一步最容易被忽略。行标准化的意思是让权重矩阵每一行之和都等于 1,这样 $W y$ 的含义就变成“邻居 $y$ 的加权平均值”,$\rho$ 的取值也自然落在可解释的区间。如果某一行三个邻居的原始权重是 0.2、0.1、0.5,行标准化后就是 0.25、0.125、0.625;如果忘了这步,大城市因为邻居多、权重总和远大于 1,会把 $\rho$ 硬生生往 1 推。后面避坑章节会专门展开。
2.3 为什么不能直接用普通面板回归再加个 W:内生性与 Nickell 偏误
一个听起来省事的做法是:用普通面板回归,把 $Wy$ 和 $Wy_{t-1}$ 当普通解释变量加进去,再用固定效应估计。这条路在动态面板空间杜宾模型里走不通,原因有二。第一是同期空间滞后项 $W y_t$ 与 $y_t$ 之间存在反向因果:本地本期 $y$ 受邻居本期 $y$ 影响,邻居本期 $y$ 也受本地本期 $y$ 影响,这就产生反射问题,$W y_t$ 是内生解释变量。第二是个体固定效应与滞后项共同作用会带来 Nickell 偏误:差分掉固定效应后,$y_{t-1}$ 与差分后的残差项仍然相关,在小 T 面板下 $\tau$ 会被系统性低估。
因此动态面板空间杜宾模型的估计通常走两条路。大 T 面板用极大似然估计,把 $\rho$ 作为参数放进对数似然函数里处理行列式 $\det(I_N - \rho W)$;小 T 面板常用空间 GMM 或工具变量法,给 $W y_t$ 找合适的工具变量。Stata 的 xsmle 命令对静态 SDM 支持得很好,但动态版本需要 MATLAB 或 R 配合专门脚本。这也是为什么压缩包里通常既有 .dta 数据文件,又有 .m 或 .R 估计脚本——这类模型本来就不是一条 xsmle 命令能收尾的。
3. 跑通最小复现路径:权重矩阵、MATLAB 动态 SDM 与 Stata 静态基准
3.1 数据清单与权重矩阵构建:从经纬度到行标准化的 W
动态面板空间杜宾模型的数据准备有两块硬要求:一是平衡面板,每个截面个体必须有完全相同的年份数,缺一年都会让矩阵堆叠出错;二是样本量下限,N 尽量不小于 30,T 不小于 10,否则 ML 估计的渐近性质很难兑现。拿到 rar 包后我习惯先看数据长什么样:一列个体 id、一列年份、若干解释变量、一个被解释变量,再加上每个个体的经纬度或距离文件。
下面是一段常用的权重矩阵构建代码,把经纬度转成 k 近邻反距离权重矩阵,并做行标准化。我用 Python 是因为在发布脚本时更容易可视化检查,生成 CSV 后再拿到 Stata 或 MATLAB 里读取。
import numpy as np import pandas as pd # 读入面板数据,至少包含 id、lon、lat 三列 df = pd.read_csv("panel_cities.csv") coord = df[["lon", "lat"]].values n = len(df) # 截面个体数 # 计算两两之间的欧氏距离,对角线置空 dist = np.sqrt(((coord[:, None, :] - coord[None, :, :]) ** 2).sum(-1)) np.fill_diagonal(dist, np.nan) k = 4 # 近邻个数,我一般从 4 开始,逐次试 6、8 W = np.zeros((n, n)) for i in range(n): # argsort 得到距离由近到远的邻居索引,取前 k 个 nbrs = np.argsort(dist[i])[:k] # 用距离倒数加权,距离越近权重越大 W[i, nbrs] = 1.0 / dist[i, nbrs] # 行标准化:每一行之和变为 1 W = W / W.sum(axis=1, keepdims=True) # 检查最大特征值绝对值,后面估计 rho 时有用 eig_max = np.max(np.abs(np.linalg.eigvals(W))) print("max abs eigenvalue:", round(eig_max, 4)) pd.DataFrame(W).to_csv("W_dynamic.csv", index=False)代码逻辑不复杂,但有三个参数需要你根据数据特征调整。k 的取值决定每个个体考虑多少个邻居:城市群研究 k=4 太少,省域面板 k=6 更常见;如果 N 有 100 个,k 在 4 到 10 之间。距离倒数加权的分母不能为零,所以坐标数据里不能有重复点在位。行标准化的目的是让 $W y_t$ 真正成为“邻居均值的空间滞后”,便于解释 $\rho$ 的数值。
生成 W_dynamic.csv 后,在 Stata 里导入并转成矩阵,供后续 xsmle 使用:
// 导入权重矩阵 CSV,变量名是 v1-vN import delimited using W_dynamic.csv, clear mkmat v1-vN, matrix(W) // 用 spmat 检查行标准化是否生效 spmat putW W, matrix(W) spmat summarize W这里最容易踩的坑是样本排序:Spreg 模型要求 W 的每一行和每一列都对应面板数据中相同顺序的个体。如果 panel_cities.dta 里的城市顺序和生成 W 时的顺序不一致,估计结果会完全乱掉。我处理这类问题时的固定套路是先用 id 排序,再在生成权重矩阵时把同样的排序规则复制一遍。
3.2 用 MATLAB 估计动态 SDM:核心似然结构与调参逻辑
Stata 的 xsmle 不支持动态面板空间杜宾模型的完整估计,常见的做法是转到 MATLAB,在空间计量工具箱的基础上自己写估计脚本。下面是最小可运行的动态 SDM 核心似然结构,我把它当作一个模板,实际估计时再用 fminsearch 或 fmincon 包一层优化。
% 输入: Y 是 N×T 矩阵, X 是 N×T×K 数组, W 是 N×N 行标准化矩阵 N = size(Y,1); T = size(Y,2); % 构造动态项: Y_{t-1} 与 W*Y_{t-1} Ylag = NaN(N, T-1); Ylag(:,2:end) = Y(:,1:end-1); % 时间滞后一期 WY = W * Y; % 同期空间滞后 WYlag = NaN(N, T-1); WYlag(:,2:end) = W * Y(:,1:end-1); % 时空滞后: 邻居上一期 % 堆叠成面板样本, 丢掉第一期 % 解释变量矩阵 = [Ylag, WY(第2期起), WYlag, X(第2期起), W*X] % 得到参数 beta 的估计后, 集中对数似然为: % LL = -0.5*N*T*log(sigma2) + T*log(det(I_N - rho*W)) + 常数 A = speye(N) - rho * W; [L, U] = lu(A); logdet = sum(log(diag(U))); % 用 LU 分解算行列式对数, 防止溢出 LL = -0.5 * N * T * log(sigma2) + T * logdet;这段代码不贴出完整优化循环,但核心思路已经够了:把 $y_{t-1}$、$W y_t$、$W y_{t-1}$ 都当作解释变量放进回归,然后用集中似然对 $\rho$ 做搜索。$\rho$ 的初始值我一般取 0.5,$\tau$ 的初始值取 0.6,搜索范围限制在 $(-1, 1)$ 内。矩阵规模大时,行列式 $\det(I_N - \rho W)$ 直接用 det 函数会爆内存,LU 分解取对角线的对数和是稳妥做法。
面板时间维度 T 对动态项的识别影响很大。T 在 15 年以上时,$\tau$ 和 $\eta$ 都容易收敛;T 只有 5 到 8 年时,$\eta$ 的估计方差会明显变大,这时候我更倾向于把模型简化成“静态 SDM + 时间滞后 y”,至少把时间记忆保留住。另外还要注意时空滞后项的权重矩阵使用的是同一个 W,不能给 $\rho$ 和 $\eta$ 分别用两套不同标准化的矩阵。
3.3 用 Stata 跑静态基准模型:xsmle 与效应分解
动态模型跑通之前,先跑一个静态 SDM 基准非常有用。它的价值在于帮你确认数据里确实存在空间溢出,也方便后续对比加入动态项后 $\rho$ 的变化。Stata 里的 xsmle 命令直接支持 SDM:
use panel_cities.dta, clear // 解释变量: ln_gdp ln_pop den 是常见控制组合 global xlist ln_gdp ln_pop den // model(sdm) 指定空间杜宾模型, fe 固定效应, type(both) 双向固定 xsmle y $xlist, wmat(W) model(sdm) fe type(both) effectsxsmle 估计完成后,报告里有几列值得关注。Wx 对应的系数就是 $\theta$,说明邻居解释变量对本地的影响;W 对应的系数是 $\rho$,说明同期空间溢出强度。effects 选项会输出直接效应、间接效应和总效应。直接效应是本地 $x$ 对本地 $y$ 的平均影响,间接效应是邻居 $x$ 通过空间网络对本地 $y$ 的传播影响,总效应是两者之和。这三个效应才是论文里能直接写结论的东西,原始回归系数在 SDM 里不能直接解读。
我发现不少场景下 $\rho$ 的估计值高得离谱,比如 0.85 以上。如果静态 SDM 已经出现这种信号,动态模型要格外小心:要么是权重矩阵没有行标准化,要么是时间惯性被错误地吸收进了同期空间滞后。这也是为什么我坚持先跑静态基准再上动态模型——如果静态模型就异常,动态模型的结果基本不能用。
3.4 动态模型结果解读:τ、ρ、η 三个系数怎么翻译成结论
动态面板空间杜宾模型的估计结果出来,我最先看三个数字:$\tau$、$\rho$、$\eta$。$\tau$ 大于 0.5 说明时间惯性很强,政策效应会持续多年;$\rho$ 大于 0.5 说明同期空间溢出显著,本地变化会明显带动邻居;$\eta$ 的符号和大小则说明空间溢出是否有时滞。如果 $\eta$ 显著为负,通常意味着邻居上一期的高水平对本地产出是挤压效应,比如产业竞争;如果 $\eta$ 显著为正,说明存在正向扩散,比如技术溢出要滞后一年才传导到邻市。
这三个数字加起来还决定一个隐含的动态收敛性质:当 $|\tau| + |\rho| + |\eta|$ 明显小于 1 时,系统受到冲击后最终会回到稳态;如果接近或超过 1,模型可能不存在有限稳态,解释时就必须谨慎,不能把长期总效应写成一个大数字。
4. 动态面板空间杜宾模型排查手册:四个高频翻车场景
4.1 权重矩阵没行标准化:rho 硬冲到 0.99
现象:静态 SDM 和动态 SDM 估计出的 $\rho$ 都超过 0.95,甚至靠近 0.99,但 Moran's I 检验显示空间相关性并没有这么强。W 的系数看起来极其显著,可一旦换成另一套权重矩阵,结果又完全不同。
原因:权重矩阵没有行标准化。当大城市邻居数量多,每一行的权重之和远大于 1,$W y_t$ 的数值被放大,$\rho$ 必须取接近 1 才能抵消这种放大效应。这是空间回归新手最容易踩的坑,也是各类压缩包代码里最常见的隐性 bug。
解决:生成权重矩阵后,先检查每一行之和。如果行和不是 1,用每行原始值除以该行总和。Stata 里可以用spmat summarize W查看行和;Python 里就是W.sum(axis=1)。我再提醒一句:行标准化必须在你做完所有距离计算之后进行,不能在距离矩阵上先标准化再取倒数,那会破坏距离权重比例。
4.2 动态项缺失:时空滞后混进残差,rho 被高估
现象:模型只放同期空间滞后 $W y_t$,不放 $y_{t-1}$ 和 $W y_{t-1}$,结果 $\rho$ 显著且数值偏大;加上 $y_{t-1}$ 后 $\rho$ 明显回落。残差诊断还显示残差存在时间自相关,但 LM 检验同时提示空间相关。
原因:面板数据里时间惯性是常态。如果模型漏掉 $y_{t-1}$,时间维度上的自相关会被空间滞后项部分吸收,导致 $\rho$ 虚高。这是“遗漏变量导致内生性”在空间面板里的典型表现,尤其当被解释变量是 GDP、房价这类强惯性变量时,影响非常明显。
解决:把时间滞后项加到模型里重新估计,看 $\rho$ 的变化幅度。如果 $\rho$ 从 0.7 降到 0.3,说明原来那 0.4 的“空间效应”其实是时间惯性造成的虚假溢出。动态面板空间杜宾模型的意义就是同时控制这两类效应,不要在静态模型上死磕。
4.3 海塞矩阵奇异:rho 越界与收敛失败
现象:优化器迭代几次后报错“Hessian is singular”,或者 $\rho$ 的搜索直接撞到 1.0001,对数似然函数在边界不收敛。有些情况下模型给出估计结果,但 $\rho$ 的标准误大得离谱。
原因:两个方向都有可能。一是权重矩阵的最大特征值大于 1,在 $\rho$ 接近 1 时 $\det(I_N - \rho W)$ 趋于零,对数似然函数出现不可导点;二是面板数据存在很强的共同时间趋势,而模型没有控制双向固定效应,导致 $\rho$ 和目标函数关系失真。
解决:先检查权重矩阵最大特征值,计算 $1 / \lambda_{\max}(W)$,把 $\rho$ 的搜索上界设定在这个值以内。同时检查数据是否包含时间虚拟变量,缺失就补上。优化器初始值从 0.3 到 0.6 的网格开始,不要一上来就用 0.9。如果还是无法收敛,再考虑改用网格搜索 $\rho$:在 0 到 0.95 之间按 0.05 步长计算对数似然,画出曲线找极大点。
4.4 小样本强行上动态模型:Nickell 偏误叠加空间反射
现象:时间维度很短(T 只有 5 到 8 年)时,$\tau$ 的估计值明显低于文献中的合理范围,比如别人都是 0.5,你估计出 0.2 还显著;$\eta$ 的置信区间宽到失去意义。
原因:动态面板本身存在 Nickell 偏误,T 越小偏误越大。再加空间滞后项,偏误进一步叠加。有人用一个 rar 包里默认的 ML 估计直接跑自己 T=5 的样本,结果自然不可靠。这不是代码问题,是估计方法与样本规模不匹配。
解决:T 小于 10 时优先考虑空间 GMM 或系统 GMM,把空间滞后项和动态项都当作内生变量处理。如果坚持用 ML,就把 $\tau$ 的解释限定为“短期惯性”,不配合长期动态乘数做预测。另一个实用做法是增加时间维度的时间聚合,比如把季度数据合并成半年度或年度,换取更长的滞后期。
5. 上保险:LR 检验与特征值边界让空间回归结果可辩护
5.1 LR 检验锁定模型族:SAR、SEM、SDM 三选一
动态面板空间杜宾模型跑完,还要回答一个审稿人必问的问题:你为什么不用更简单的 SAR 或 SEM?这个问题的标准回答是 LR 检验或 Wald 检验。SDM 作为上界模型,嵌套了 SAR($\theta = 0$)和 SEM($\theta = -\rho \beta$),可以用 LR 统计量直接判断能否退化。
在 Stata 中估计静态 SDM 后,再用无约束模型和约束模型的对数似然值做 lrtest。LR 统计量等于 $2(LL_{unrestricted} - LL_{restricted})$,自由度等于约束个数。流程如下:先估计 SDM,再分别估计 SAR 和 SEM,然后两两做 LR 检验。如果拒绝 $\theta = 0$,说明邻居解释变量的外生溢出显著存在,保留 SDM;如果拒绝 $\theta = -\rho \beta$,同样说明 SDM 优于 SEM。两个约束都不能拒绝时,选参数更少的模型,SAR 或 SEM 更合适。这个小表格是我常用的决策依据:
| 检验 | 原假设 | 拒绝原假设时的选择 | 不拒绝时的选择 |
|---|---|---|---|
| LR 检验(SDM vs SAR) | $\theta = 0$ | SDM | SAR |
| LR 检验(SDM vs SEM) | $\theta = -\rho \beta$ | SDM | SEM |
5.2 收敛边界:特征值上限与动态系统有界性
动态面板空间杜宾模型不是把参数估计出来就完事,还要检查系统是否具备收敛性。我对模型的底线要求是:$\rho$ 必须严格小于 $1 / \lambda_{\max}(W)$,同时 $|\tau|$ 与 $|\eta|$ 的绝对值之和不能接近 1。如果不满足,长期乘数会出现爆炸性增长,这时候报告的间接效应和总效应都没有实际意义。
实际操作很简单:估计前用 Python 或 MATLAB 打印权重矩阵最大特征值,估计后把 $\rho$ 估计值与上限比较。如果 $\rho$ 接近上限,我会先怀疑权重矩阵设定过密,比如 k 取太大导致每个个体都有几十个邻居,$\lambda_{\max}$ 变大,$\rho$ 的可接受区间被压缩。把 k 调小或改用稀疏的阈值距离矩阵,往往能解决一大半收敛问题。
我的个人习惯是每个动态面板空间杜宾模型做完,都附上一张“权重矩阵特征值上限 + 三个滞后项系数”汇总表,这比在正文里反复解释“结果稳健”更有说服力。这也是以前踩过拿 $\rho=0.98$ 的结果硬写论文的坑后养成的习惯,一套模型跑不出有界性特征,参数再好看也不值得投入。希望这篇笔记能帮你少走这几步弯路。
本文还有配套的精品资源,点击获取