在R语言的包tempdisagg,平移到python了。
github:
https://github.com/jaimevera1107/tempdisagg
文章目录
1 方法介绍
核心的用途:官方指标通常是低频(例如年GDP),而经济分析或预测需求每月或季度粒度。 Tempdisagg使用一致的计量经济学技术填补了这一空白,以创建尊重原始聚集体的颗粒状估计值。
方法罗列:
几个方法的快速介绍:
denton(Denton插值法)
在已知低频总量时,平滑地分配到高频,使变化最小化(差分平滑)。
实现步骤:选择差分阶数(如一阶、二阶),最小化高频数列的邻期变化(差分)平方和,同时保证聚合后等于低频。
意义:常用于季节性调整,适用于没有高频解释变量的场景。
chow-lin一族
chow-lin、chow-lin-opt、chow-lin-ecotrim、chow-lin-quilis(回归+AR(1)残差分配)
用回归模型和高频指标预测高频目标,同时采用一阶自回归(AR(1))过程分配回归残差,保证低频一致性和高频信息利用。
实现步骤:
- 高频解释变量聚合到低频,回归低频目标。
- 用高频解释变量预测高频目标。
- 拟合AR(1)模型对残差分配,使聚合约束成立。
意义:经济学中最经典的临时分解方法之一,适合有高频参考指标场景。
这类方法(尤其是chow-lin-opt)被认为是分解的“黄金标准”之一,因为它们充分利用了高频协变量的信息,并且通过对残差结构(AR(1))的建模,使得分解结果在统计上更有效率和准确。
litterman
litterman-opt
Litterman 方法假设高频时间序列遵循一个随机游走(Random Walk)或AR(1) 过程,并以此作为先验信息来指导分解。
它在没有外部协变量的情况下也能工作,或者当协变量信息不足时,它依赖于序列自身的动态特性进行插值。
实现步骤:
- 设定高频序列遵循随机游走或 AR(1) 过程的先验假设。
- 结合低频聚合约束,通过优化(通常是最小化高频序列差分或残差的加权平方和)来推断出高频序列。
意义:Litterman 方法适用于当没有合适的外部高频协变量可用时,或者当高频序列本身具有明显的随机游走特性时。它通过内在的时间序列结构来填充和分解数据。
fast:Fast approximation of Denton-Cholette
顾名思义,fast 方法是 denton-cholette 的一个快速近似版本。它旨在提供与 denton-cholette 相似的性能,但在计算上更高效,尤其适用于处理非常大的数据集。
实现步骤:采用了简化的计算策略来近似 denton-cholette 的结果。
意义:当计算资源有限或需要快速处理大量数据时,fast 方法是一个很好的选择,它在计算速度和结果质量之间取得了平衡。
uniform:Even distribution across subperiods
功效:这是最简单粗暴的分解方法。它不使用任何协变量,直接将低频数据总量平均分配到其包含的高频子周期中。
实现步骤:
- 获取低频数据。
- 确定每个低频周期包含多少个高频子周期(例如,年度到季度就是 4 个)。
- 将每个低频值除以子周期数量,并将结果分配给每个子周期。
意义:uniform 方法通常用于没有可用高频协变量的场景,或者作为基线比较。它的局限性在于完全忽略了高频数据内部的波动性和时间模式,可能导致不真实的平坦高频序列。
2 代码
pip install tempdisagg
来一个案例:
from tempdisagg import TempDisaggModel
import pandas as pd
import numpy as np
# Sample input data (monthly disaggregation of yearly total)
df = pd.DataFrame({
"Index": [2020]*12 + [2021]*12,
"Grain": list(range(1, 13)) * 2,
"y": [1200] + [np.nan]*11 + [1500] + [np.nan]*11,
"X": np.linspace(100, 200, 24)
})
# Fit model
model = TempDisaggModel(method="chow-lin-opt", conversion="sum")
model.fit(df)
# Predict high-frequency series
y_hat = model.predict()
# Adjust negatives (if any; OPTIONAL)
y_adj = model.adjust_output()
# Show results
model.summary()
model.plot()
可以看到,里面的TempDisaggModel(method="chow-lin-opt", conversion="sum")
,会定义各种模型
self.all_methods = {
"ols": self.models.ols_estimation,
"denton": self.models.denton_estimation,
"chow-lin": self.models.chow_lin_estimation,
"litterman": self.models.litterman_estimation,
"fernandez": self.models.fernandez_estimation,
"fast": self.models.fast_estimation,
"chow-lin-opt": self.models.chow_lin_opt_estimation,
"litterman-opt": self.models.litterman_opt_estimation,
"chow-lin-ecotrim": self.models.chow_lin_minrss_ecotrim,
"chow-lin-quilis": self.models.chow_lin_minrss_quilis,
"denton-cholette": self.models.denton_cholette_estimation,
"uniform": self.models.uniform_estimation
}
一些真实数据的案例:
import statsmodels.api as sm
from tempdisagg import TempDisaggModel
# Load macroeconomic dataset (quarterly)
macro = sm.datasets.macrodata.load_pandas().data
macro["Index"] = macro["year"].astype(int)
macro["Grain"] = macro["quarter"].astype(int)
macro["X"] = macro["realcons"]
# Aggregate GDP to annual level
gdp_annual = macro.groupby("Index")["realgdp"].mean().reset_index()
gdp_annual.columns = ["Index", "y"]
# Merge back into full frame
df = macro.merge(gdp_annual, on="Index", how="left")[["Index", "Grain", "y", "X"]]
# Fit model and predict
model = TempDisaggModel(method="chow-lin-opt", conversion="average")
model.fit(df)
# Get high-frequency estimates
y_hat = model.predict(full=False)
# Optional: post-estimation adjustment
y_adj = model.adjust_output(full=False)
# Summary and plot
model.summary()
model.plot()
同时也可以一次性跑了所有模型
model = TempDisaggModel(method="ensemble", conversion="sum")
model.fit(df)
model.summary()
model.plot()