📚 基础知识库 · EXACT HAT ALGEBRA(帽代数反事实求解)

本页是 QSGE 的基础知识库页面:它不绑定某一个模型分支,而是所有量化贸易 / 空间模型做"反事实分析"时共用的数值求解范式。只要你学会本页的通用不动点迭代器,把它的份额方程换成对应分支的形式(CES 份额、Fréchet 份额、Pareto 门槛份额、RRH 通勤份额),就能在 Armington / EK / Melitz / RRH / 贸易+迁移+土地 之间无缝切换。

在哪些模型分支中使用 →
01 · Armington(CES 帽子份额) 02 · Eaton-Kortum(Fréchet 帽子份额) 08 · Melitz(Pareto 门槛帽子份额) 06 · RRH 空间 GE(嵌套:通勤 + 贸易) 07 · 贸易+迁移+土地(多市场帽子)

配套福利公式:04 · 福利分解 (ACR)——帽代数给出新份额 $\hat\lambda_{nn}$,ACR 公式一句话给出福利变化 $\hat W = \hat\lambda_{nn}^{-1/\theta}$。

前置条件与学习依赖 · PREREQUISITES
数学/统计基础
Exact hat algebra(帽子变换):$\hat x = x'/x$ 的运算规则($\widehat{xy}=\hat x\hat y$、$\widehat{x/y}=\hat x/\hat y$);不动点迭代算法(Jacobi 型同步更新 vs Gauss-Seidel 型异步更新)、阻尼因子与收敛性分析(contraction mapping 直觉)、矩阵求逆的替代(迭代避免显式求逆)、归一化约束。
经济学理论前置
比较静态分析(comparative statics)、政策评估(关税/贸易成本变化的福利效应)、一般均衡反事实(counterfactual GE)。需理解"为什么只需变化率而不需水平值"——模型齐次性带来的 identification 便利。
软件/计算前置
Python(numpy 矩阵迭代 + scipy.optimize.fixed_point 的 Anderson 加速)或 MATLAB。本页求解器与 Armington/EK 的关键差异:迭代变量是帽子 $\hat w_i$ 而非水平 $w_i$,分母用基准份额 $\lambda_{nk}$ 做权重,完全不需要知道 $T_i$ 或 $w_i$ 的水平值。
站内前置页面
先学 04-福利分解(ACR) + 02-Eaton-Kortum。帽子代数是 ACR 公式的"求解版":ACR 告诉你福利变化的 sufficient statistic,帽子代数告诉你如何从观测份额反算出新份额。
难度分级
进阶   算法为主,2 周。核心是掌握"只迭代帽子"的范式与收敛加速技巧。

01 为什么需要帽子代数

做反事实的朴素思路是:(1) 校准所有外生参数 $\{T_i, L_i, \tau_{ni}\}$;(2) 求解基准均衡 $\{w_i, P_i, \lambda_{ni}\}$;(3) 修改 $\tau_{ni}$ 为 $\tau'_{ni}$;(4) 重新求解新均衡 $\{w'_i, P'_i, \lambda'_{ni}\}$。问题出在第 (1) 步:$\{T_i, \tau_{ni}\}$ 的水平值通常不可观测,且很难校准——你怎么知道中国的 Fréchet 绝对效率参数 $T_{CHN}$ 是多少?

Dekle-Eaton-Kortum (2007) 的洞察是:你不需要知道水平值。因为模型的均衡条件在 CES / Fréchet 结构下是齐次的,所有方程都可以用"变化率"重新写。给定:

  • 观测到的基准贸易份额 $\lambda_{ni}$(这是数据);
  • 外生冲击 $\hat{\tau}_{ni} = \tau'_{ni}/\tau_{ni}$(这是反事实情景);

我们就能直接求解 $\hat{w}_i, \hat{P}_i, \hat{\lambda}_{ni}$,完全绕开水平值。这就是 exact hat algebra(帽子代数)——"exact"指的是这个变换是模型的精确改写,不是线性近似。

02 帽子变换与齐次性

定义帽子变量:

帽子变换
$$\hat{x} \equiv \frac{x'}{x}$$

即"反事后值 ÷ 基准值"。几个常用性质:

$$\widehat{x \cdot y} = \hat{x} \cdot \hat{y}, \qquad \widehat{x/y} = \hat{x}/\hat{y}, \qquad \widehat{x^\alpha} = \hat{x}^{\alpha}$$

关键洞察:如果一个均衡条件是齐次方程(例如 $\sum_i A_i = 1$ 或 $A_i = \sum_j B_{ij} C_j$),它可以拆成"基准均衡"+"帽子均衡"两部分。基准均衡从数据读出来,帽子均衡待解。

03 EK 模型的帽子代数推导

回顾 EK 贸易份额:

$$\lambda_{ni} = \frac{T_i (w_i \tau_{ni})^{-\theta}}{\sum_k T_k (w_k \tau_{nk})^{-\theta}}$$

反事实下(加 '):

$$\lambda'_{ni} = \frac{T_i (w'_i \tau'_{ni})^{-\theta}}{\sum_k T_k (w'_k \tau'_{nk})^{-\theta}}$$

两式相除($\lambda'_{ni}/\lambda_{ni}$):

$$\hat{\lambda}_{ni} = \frac{\lambda'_{ni}}{\lambda_{ni}} = \frac{(w'_i \tau'_{ni})^{-\theta} / (w_i \tau_{ni})^{-\theta}}{\sum_k \frac{T_k (w'_k \tau'_{nk})^{-\theta}}{\sum_l T_l (w_l \tau_{nl})^{-\theta}}} = \frac{(\hat{w}_i \hat{\tau}_{ni})^{-\theta}}{\sum_k \lambda_{nk} (\hat{w}_k \hat{\tau}_{nk})^{-\theta}}$$

最后一步的关键是:分母中的 $\sum_k T_k(w_k\tau_{nk})^{-\theta}$ 正好是 $1/\lambda_{nn}$ 之类的基准对象,约掉后剩下 $\lambda_{nk}$。最终的帽子份额方程:

★ EK 帽子贸易份额
$$\boxed{\;\hat{\lambda}_{ni} = \frac{(\hat{w}_i \hat{\tau}_{ni})^{-\theta}}{\sum_{k=1}^{N} \lambda_{nk} (\hat{w}_k \hat{\tau}_{nk})^{-\theta}}\;}$$

注意:分母里用的是基准份额 $\lambda_{nk}$(观测值),分子里全是帽子。$T_i$ 完全消失了!这就是帽子代数的威力——你不需要知道 $T_i$ 的水平。

贸易平衡的帽子形式

基准贸易平衡:$w_i L_i = \sum_n \lambda_{ni} w_n L_n$。反事实:$w'_i L_i = \sum_n \lambda'_{ni} w'_n L_n$。相除:

★ EK 帽子贸易平衡
$$\boxed{\;\hat{w}_i = \frac{1}{w_i L_i} \sum_n \lambda_{ni} \hat{\lambda}_{ni} \hat{w}_n w_n L_n\;}$$

右边的 $w_i L_i, \lambda_{ni}, w_n L_n$ 都是基准均衡对象(可从数据读出,或从 $X_i = w_i L_i$ 得到),只有 $\hat{w}_i$ 是待解未知。这就是一个关于 $\hat{w}$ 的不动点方程。

福利变化

由 ACR 公式(04 页):

福利变化(直接读帽子)
$$\hat{W}_i = \frac{W'_i}{W_i} = \hat{\lambda}_{ii}^{\,-1/\theta}$$

解出 $\hat{w}_i$ 后,$\hat{\lambda}_{ii}$ 立刻可算,福利变化立刻可报。

04 不动点迭代算法(伪代码)

输入
基准贸易份额矩阵 $\Lambda \in \mathbb{R}^{N\times N}$(观测);基准支出 $X_n = w_n L_n$(观测);贸易成本冲击 $\hat{\tau}_{ni}$(外生给定);参数 $\theta$。
Step 0:初始化
$\hat{w}_i^{(0)} = 1$ 对所有 $i$(即假设无变化)。
Step 1:计算帽子份额
对每个 $(n,i)$,计算 $\hat{\lambda}_{ni}^{(t)} = \dfrac{(\hat{w}_i^{(t)} \hat{\tau}_{ni})^{-\theta}}{\sum_k \lambda_{nk} (\hat{w}_k^{(t)} \hat{\tau}_{nk})^{-\theta}}$。
Step 2:计算隐含销售
对每个 $i$,$sales_i^{(t)} = \sum_n \lambda_{ni} \hat{\lambda}_{ni}^{(t)} \hat{w}_n^{(t)} X_n$。
Step 3:更新工资
$\hat{w}_i^{(t+1)} = \hat{w}_i^{(t)} \cdot \left(\dfrac{sales_i^{(t)}}{X_i}\right)^{\omega}$,$\omega \in (0,1]$ 是阻尼因子。
Step 4:标准化
$\hat{w}_i^{(t+1)} \leftarrow \hat{w}_i^{(t+1)} / \sum_j \hat{w}_j^{(t+1)} X_j / \sum_j X_j$(保持基准总工资不变)。
Step 5:收敛判据
若 $\max_i |sales_i^{(t)}/X_i - 1| < 10^{-8}$,停;否则 $t \leftarrow t+1$,回 Step 1。
输出
$\hat{w}_i^*$、$\hat{\lambda}_{ni}^*$、$\hat{W}_i = \hat{\lambda}_{ii}^{*,-1/\theta}$。

05 N=10 国完整 Python 实现

python
"""
Exact Hat Algebra 求解器(EK 模型)
- N=10 国例子
- 输入: 基准贸易份额矩阵 Lambda、基准支出 X、贸易成本冲击 tau_hat
- 输出: 工资变化 hat_w、福利变化 hat_W
- 不需要知道 T_i、w_i 的水平值!
"""
import numpy as np

def hat_ek(Lambda, X, tau_hat, theta, tol=1e-9, max_iter=50000, damp=0.5):
    """
    Lambda   : (N,N) 基准贸易份额,Lambda[n,i] = X_{ni}/X_n(观测)
    X        : (N,)   基准总支出(=w_i*L_i,观测)
    tau_hat  : (N,N)  贸易成本变化率,hat tau_{ni}
    theta    : scalar,Fréchet 形状参数
    返回:
      hat_w    : (N,) 工资变化
      hat_lam  : (N,N) 贸易份额变化
      hat_W    : (N,) 福利变化
    """
    N = len(X)
    hat_w = np.ones(N)

    for it in range(max_iter):
        # Step 1: 帽子份额
        # num[n,i] = (hat_w[i] * tau_hat[n,i])^(-theta)
        num = (hat_w[None, :] * tau_hat) ** (-theta)        # (N,N)
        # 分母: sum_k Lambda[n,k] * num[n,k]
        denom = (Lambda * num).sum(axis=1, keepdims=True)   # (N,1)
        hat_lam = num / denom                                # (N,N)

        # Step 2: 隐含销售 sales[i] = sum_n Lambda[n,i] * hat_lam[n,i] * hat_w[n] * X[n]
        # 注意 X[n] 是 n 国总支出
        weighted = Lambda * hat_lam * (hat_w[None, :] * X[None, :])  # (N,N)
        sales = weighted.sum(axis=0)   # 对 n 求和,得到 i 国销售  (N,)

        # Step 3: 过剩销售
        excess = sales / X

        # Step 4: 更新 hat_w(带阻尼)
        hat_w_new = hat_w * excess ** damp

        # 标准化:保持 sum(hat_w * X) = sum(X)(去掉工资的整体缩放)
        hat_w_new = hat_w_new * X.sum() / (hat_w_new * X).sum()

        # 收敛
        if np.max(np.abs(excess - 1.0)) < tol:
            hat_w = hat_w_new
            break
        hat_w = hat_w_new
    else:
        print("Warning: 未收敛")

    # 最终 hat_lam
    num = (hat_w[None, :] * tau_hat) ** (-theta)
    denom = (Lambda * num).sum(axis=1, keepdims=True)
    hat_lam = num / denom

    # 福利变化(ACR 公式)
    hat_W = np.diag(hat_lam) ** (-1.0 / theta)
    return hat_w, hat_lam, hat_W


# ============ 1. 构造 N=10 国例子 ============
np.random.seed(42)
N = 10
country_names = [f"国家{i}" for i in range(N)]

# 模拟基准贸易份额 Lambda(行=进口国,列=出口国,行和=1)
# 方法:先生成一个"吸引力"矩阵,再按行归一化
attract = np.random.uniform(0.1, 1.0, size=(N, N))
np.fill_diagonal(attract, np.random.uniform(2, 5, N))  # 国内偏好
Lambda = attract / attract.sum(axis=1, keepdims=True)

# 基准支出 X(GDP,对数正态)
X = np.exp(np.random.normal(10, 1.0, N))

# 贸易弹性
theta = 5.0

print("=" * 60)
print("基准贸易份额矩阵(前 5 行 × 5 列):")
print(np.round(Lambda[:5, :5], 3))
print(f"\n基准支出 X(前 5 国): {np.round(X[:5], 1)}")
print(f"国内份额 lambda_nn(前 5 国): {np.round(np.diag(Lambda)[:5], 3)}")

# ============ 2. 反事实:所有跨国贸易成本下降 10% ============
tau_hat_free = np.ones((N, N))
tau_hat_free[~np.eye(N, dtype=bool)] = 0.9   # 跨国成本 *0.9(下降 10%)

hat_w, hat_lam, hat_W = hat_ek(Lambda, X, tau_hat_free, theta)
print("\n" + "=" * 60)
print("反事实:跨国贸易成本下降 10%")
print(f"  工资变化 hat_w(前 5 国): {np.round(hat_w[:5], 4)}")
print(f"  福利变化 hat_W(前 5 国): {np.round(hat_W[:5], 4)}")
print(f"  平均福利变化: {np.mean(hat_W):.4f}")

# ============ 3. 反事实:贸易战(大国加关税 25%) ============
# 假设 0 号国家对所有其他国家加 25% 关税
tau_hat_war = np.ones((N, N))
tau_hat_war[0, 1:] = 1.25   # 国家 0 从 j!=0 进口成本 *1.25
hat_w_war, hat_lam_war, hat_W_war = hat_ek(Lambda, X, tau_hat_war, theta)
print("\n" + "=" * 60)
print("反事实:国家 0 对所有他国加 25% 关税")
print(f"  国家 0 福利变化: {hat_W_war[0]:.4f} (即 {(hat_W_war[0]-1)*100:.2f}%)")
print(f"  其他国家平均福利变化: {np.mean(hat_W_war[1:]):.4f}")
print(f"  世界平均福利变化: {np.mean(hat_W_war):.4f}")
# 经典预测:加关税国自身福利下降(大国有利论在小模型里不成立),全球福利下降

# ============ 4. 反事实:完全自给自足 ============
tau_hat_autarky = np.ones((N, N))
tau_hat_autarky[~np.eye(N, dtype=bool)] = 1e6   # 跨国成本无穷大
hat_w_auto, hat_lam_auto, hat_W_auto = hat_ek(Lambda, X, tau_hat_autarky, theta)
print("\n" + "=" * 60)
print("反事实:完全自给自足(跨国成本 -> ∞)")
print(f"  福利变化 hat_W(应 < 1): {np.round(hat_W_auto[:5], 4)}")
# 注意:hat_W_auto = hat_lam_nn^(-1/theta),自给自足下 hat_lam_nn -> 1/lam_nn,所以 hat_W_auto = lam_nn^(1/theta) < 1
# 与 04 页 ACR 公式一致:W_trade/W_autarky = lam_nn^(-1/theta)
运行说明

这个代码可以直接跑,不需要 $T_i$ 或 $w_i$ 的水平值。它只用了观测到的贸易份额 $\Lambda$ 和支出 $X$。这正是帽子代数相对于"先校准水平值再求解"范式的巨大优势。

06 关税反事实案例

把贸易成本冲击 $\hat{\tau}_{ni}$ 解释成关税变化:若 $n$ 国对 $i$ 国从价关税从 $t_{ni}$ 升到 $t'_{ni}$,则:

关税变化的帽子
$$\hat{\tau}_{ni} = \frac{1 + t'_{ni}}{1 + t_{ni}}$$

例如从 0% 升到 25%:$\hat{\tau}_{ni} = 1.25$;从 10% 降到 0%:$\hat{\tau}_{ni} = 1/1.1 \approx 0.909$。把这个放进上面的 tau_hat 矩阵,就能算关税战的福利后果。

NAFTA 案例(Caliendo-Parro 2015 简化版)

假设 NAFTA 把美国-加拿大-墨西哥之间的关税从平均 5% 降到 0%:

$$\hat{\tau}_{US,CA} = \hat{\tau}_{CA,US} = \hat{\tau}_{US,MX} = \cdots = \frac{1+0}{1+0.05} \approx 0.952$$

把这个放进帽子代数迭代,就得到三国工资与福利变化。Caliendo-Parro (2015) 的完整多部门版本发现 NAFTA 让墨西哥福利上升约 1.5%,美国上升约 0.3%,加拿大几乎不变。

07 收敛性与加速

上面的简单 Jacobi 迭代在 $N$ 大或 $\theta$ 大时可能慢或震荡。实用技巧:

  • 阻尼 $\omega$:从 0.1 起步,逐步升到 0.5–1.0。阻尼小=稳但慢,阻尼大=快但可能震荡。
  • Anderson 加速scipy.optimize.fixed_point(..., method='anderson') 通常能把迭代次数从几千降到几十。
  • 对数空间迭代:在 $\ln \hat{w}$ 空间做更新,可以保证 $\hat{w}>0$,数值更稳。
  • 归一化:每轮必须归一化,否则工资向量会整体漂移。
python
# 用 scipy.optimize.fixed_point + Anderson 加速
from scipy.optimize import fixed_point

def hat_ek_fast(log_hat_w, Lambda, X, tau_hat, theta):
    hat_w = np.exp(log_hat_w)
    num = (hat_w[None, :] * tau_hat) ** (-theta)
    denom = (Lambda * num).sum(axis=1, keepdims=True)
    hat_lam = num / denom
    weighted = Lambda * hat_lam * (hat_w[None, :] * X[None, :])
    sales = weighted.sum(axis=0)
    excess = sales / X
    # 不动点:log(hat_w_new) = log(hat_w) + log(excess)
    return np.log(hat_w) + np.log(excess)

log_hat_w_star = fixed_point(
    hat_ek_fast, np.zeros(N),
    args=(Lambda, X, tau_hat_free, theta),
    method='anderson', xtol=1e-10, maxiter=1000
)
hat_w_star = np.exp(log_hat_w_star)
print("Anderson 加速后的 hat_w:", np.round(hat_w_star[:5], 4))

07+ 在各模型分支中的应用差异

帽代数的骨架(不动点迭代 + 阻尼 + 标准化)在所有分支中完全一样;差异只在"份额方程"和"均衡条件"两块。下表是迁移对照表——把本页 hat_ek() 函数里的相应行替换掉即可。

分支帽子份额方程迭代变量均衡条件特殊点
01 Armington $\hat\lambda_{ni} = \dfrac{(\hat w_i \hat\tau_{ni})^{1-\sigma}}{\sum_k \lambda_{nk}(\hat w_k \hat\tau_{nk})^{1-\sigma}}$ $\hat w_i$ 贸易平衡 $\sigma-1$ 替代 $\theta$;最简单的入门版本
02 Eaton-Kortum $\hat\lambda_{ni} = \dfrac{(\hat w_i \hat\tau_{ni})^{-\theta}}{\sum_k \lambda_{nk}(\hat w_k \hat\tau_{nk})^{-\theta}}$ $\hat w_i$ 贸易平衡 本页代码的原型;Ricardian 技术差异
08 Melitz-Pareto 同 EK(Pareto 下结构相同) $\hat w_i$ 贸易平衡 + 自由进入零利润 份额方程看似一样,但 $\theta$ 是 Pareto 形状;多了 cutoff 的帽子形式 $\hat{\varphi}^*_{ni}$
06 RRH 空间 GE 贸易份额(同 EK)+ 通勤份额 $\hat m_{ni} = \dfrac{(\hat w_i \hat u_i)^{\varepsilon}}{\sum_k (\hat w_k \hat u_k)^{\varepsilon}}$ $\hat w_i$ + $\hat L_i$(劳动分布) 贸易平衡 + 通勤均衡 + 住房市场出清 嵌套迭代:外层迭代 $\hat L_i$,内层跑贸易帽子代数;收敛更慢,阻尼要更小
07 贸易+迁移+土地 贸易份额 + 迁移份额 + 土地/住房份额 $\hat w_i$ + $\hat L_i$ + 地租/房价 多市场出清(贸易、迁移、土地) 帽子向量维度翻倍;常需 Anderson 加速 + 多阻尼因子
迁移口诀

从 EK 迁到 Armington:把 $-\theta$ 全部换成 $1-\sigma$。从 EK 迁到 Melitz:方程不变,把 $\theta$ 解释为 Pareto 形状参数即可(ACR 保证福利公式一样)。从 EK 迁到 RRH:在工资迭代外面再套一层劳动分布 $\hat L_i$ 的迭代。从 RRH 迁到 07:再套一层地租 / 房价的迭代。

08 论文案例与常见错误

EN · 经典
Quantitative Trade Models: Developments and Challenges
Dekle, R., J. Eaton & S. Kortum, in NBER Macroeconomics Annual, 2007
帽子代数的原始论文。展示如何用观测到的贸易份额做"中国冲击"、"关税战"反事实,而无需校准所有外生水平参数。
EN · 经典
Estimates of the Trade and Welfare Effects of NAFTA
Caliendo, L. & F. Parro, Review of Economic Studies, 82(1), 2015, 1–44
多部门帽子代数的代表作。20 个行业 + 跨国投入产出表,用 exact hat algebra 算 NAFTA 福利。是现代 QSGE 论文的模板。
EN · 经典
An Autopsy of the World Trade System
Caliendo, L., R. C. Feenstra, J. Romalis & A. Taylor, NBER WP / 后续 AER 论文
用帽子代数模拟"全球贸易崩溃":假设所有国家把贸易成本提高到 autarky 水平,估计全球福利损失。
CN · 中文顶刊
中美贸易摩擦的福利效应:基于多部门帽子代数的反事实分析
李春顶、陆琳等,《经济研究》相关主题
把 Caliendo-Parro 多部门帽子代数用于中美 2018 年关税战:模拟双方加征 25% 关税对两国福利、就业、行业产出的影响。
CN · 中文顶刊
RCEP 的贸易与福利效应:结构引力 + 帽子代数
肖皓、祝树金等,《经济研究》/《世界经济》相关主题
用帽子代数模拟 RCEP 关税削减对中国、东盟、日韩澳新的福利影响,分解贸易创造与贸易转移。
错误 1:把水平值和帽子值混进同一个方程

帽子代数的全部威力来自"只迭代帽子"。如果你在 Step 2 把水平 $w_i$ 带进去(例如写成 $w_i \cdot$hat_w_i),就必须同时知道 $w_i$ 的水平——而你正是为了避免这个才用帽子代数。

错误 2:忘记基准份额出现在分母

帽子贸易份额方程分母是 $\sum_k \lambda_{nk} (\hat{w}_k \hat{\tau}_{nk})^{-\theta}$,基准份额 $\lambda_{nk}$ 是权重。漏掉它,分母退化为 $\sum_k (\hat{w}_k \hat{\tau}_{nk})^{-\theta}$,模型就不对了——这相当于"每国初始贸易份额相同",与数据矛盾。

错误 3:忘记标准化工资

帽子方程只识别 $\hat{w}$ 的相对变化。若不显式归一化(例如 $\sum_i \hat{w}_i X_i = \sum_i X_i$),迭代会漂移到整体缩放。

警告:帽子代数的"exact"是相对模型而言

"exact" 指它对模型均衡条件是精确改写,不是对现实的精确预测。模型本身的设定(单一部门、贸易平衡、无中间品)会引入误差。现代 QSGE 论文通常会做多个模型版本对比(单一部门 vs 多部门 vs 投入产出),报告福利区间。

进阶资料

  • Dekle-Eaton-Kortum (2007) NBER Macro Annual 论文。
  • Caliendo-Parro (2015) RES。
  • Costinot-Rodriguez-Clare (2014) Handbook Chapter 4(反事实章节)。