外观
向量误差修正模型
VECM 估计与协整关系分析。
核心代码
py
def _fit_vecm(self, decimals: int, title: str) -> None:
"""
执行 VECM 向量误差修正模型估计。
输出内容:
1. 模型概要信息
2. 协整方程(beta 向量 + 常数项)
3. 调整系数(alpha,误差修正项系数)
4. 短期动态系数(gamma,差分滞后项系数)
"""
from statsmodels.tsa.vector_ar.vecm import VECM
target_cols = self.x_vars
if not target_cols or len(target_cols) < 2:
raise ValueError(_('VECM 模型至少需要选择 2 个变量。'))
valid_cols = [c for c in target_cols if c in self.data.columns]
if len(valid_cols) < 2:
raise ValueError(_('有效的数值型变量不足 2 个。'))
df_clean = self.data[valid_cols].select_dtypes(include=[np.number]).dropna()
if df_clean.shape[0] < 20:
raise ValueError(_('有效数据行数不足(至少需要 20 行)。'))
# 获取参数
var_lags = int(self.ts_options.get('vecm_var_lags', 2))
k_ar_diff = max(var_lags - 1, 1)
coint_rank = int(self.ts_options.get('vecm_coint_rank', 1))
det_order = int(self.ts_options.get('vecm_det_order', 0))
# det_order 转换为 statsmodels deterministic 参数
# -1: 'n' (无确定性项), 0: 'ci' (受限常数项), 1: 'li' (受限线性趋势)
det_map = {-1: 'n', 0: 'ci', 1: 'li'}
deterministic = det_map.get(det_order, 'ci')
n_vars = len(valid_cols)
if coint_rank >= n_vars:
raise ValueError(_('协整秩 (%(coint_rank)s) 必须小于变量数 (%(n_vars)s)。') % {'coint_rank': coint_rank, 'n_vars': n_vars})
# 拟合 VECM 模型
try:
model = VECM(df_clean, k_ar_diff=k_ar_diff, coint_rank=coint_rank,
deterministic=deterministic)
result = model.fit()
except Exception as e:
raise ValueError(_('VECM 模型估计失败: %(error)s') % {'error': str(e)})
n_obs = result.nobs
overall_title = title if title else _('VECM 向量误差修正模型')
html = f'<div class="table-editable-container">'
html += render_table_title_editor(overall_title)
# 1. 模型概要信息
det_labels = {-1: _('无确定性趋势'), 0: _('含截距项(受限常数)'), 1: _('含线性趋势(受限)')}
det_label = det_labels.get(det_order, str(det_order))
html += '<table class="academic-table" style="width: auto; margin: 10px auto; min-width: 60%;">'
html += '<thead><tr>'
html += _('<th style="border-bottom: 1px solid black; text-align: center;" colspan="4">模型信息</th>')
html += '</tr></thead><tbody>'
info_rows = [
(_('观测数'), str(n_obs), _('变量数'), str(n_vars)),
(_('滞后阶数'), str(var_lags), _('协整秩'), str(coint_rank)),
(_('趋势项'), det_label, _('对数似然值'), f'{result.llf:.{decimals}f}'),
]
for r in info_rows:
html += '<tr>'
html += f'<td style="text-align: center; font-weight: bold; width: 20%;">{r[0]}</td>'
html += f'<td style="text-align: center; width: 30%;">{r[1]}</td>'
html += f'<td style="text-align: center; font-weight: bold; width: 20%;">{r[2]}</td>'
html += f'<td style="text-align: center; width: 30%;">{r[3]}</td>'
html += '</tr>'
html += '</tbody></table>'
# 2. 协整方程
html += self._build_vecm_cointegration_eq(result, valid_cols, det_order, decimals)
# 3. 调整系数(alpha)
html += self._build_vecm_alpha_table(result, valid_cols, decimals)
# 4. 短期动态系数(gamma)
html += self._build_vecm_gamma_table(result, valid_cols, k_ar_diff, decimals)
html += '</div>'
self.custom_html = html