Skip to content

VAR 模型

向量自回归模型估计与滞后阶数选择。

核心代码

py
    def _fit_var(self, decimals: int, title: str) -> None:
        """
        执行 VAR 向量自回归模型分析。
        输出内容:
        1. 滞后阶数选择表(AIC/BIC/HQIC/FPE)
        2. 各方程的回归系数表
        3. 模型整体统计量
        支持对变量进行差分处理后再建模。
        """
        from statsmodels.tsa.api import VAR

        target_cols = self.x_vars
        if not target_cols or len(target_cols) < 2:
            raise ValueError(_('VAR 模型至少需要选择 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 行)。'))

        max_lags = self.ts_options.get('var_max_lags', 8)
        if max_lags is not None:
            max_lags = int(max_lags)
        ic = self.ts_options.get('var_ic', 'aic')
        trend = self.ts_options.get('var_trend', 'c')

        # 差分处理
        diff_order = int(self.ts_options.get('var_diff_order', 0))
        if diff_order > 0:
            for _step in range(diff_order):
                df_clean = df_clean.diff().dropna()
            if df_clean.shape[0] < 20:
                raise ValueError(_('经过 %(diff_order)s 阶差分后数据行数不足(至少需要 20 行)。') % {'diff_order': diff_order})

        # 构建 VAR 模型
        model = VAR(df_clean)

        # 1. 滞后阶数选择
        try:
            lag_order_result = model.select_order(maxlags=max_lags)
        except Exception as e:
            raise ValueError(_('滞后阶数选择失败: %(error)s') % {'error': str(e)})

        # 获取最优滞后阶数
        ic_map = {'aic': 'aic', 'bic': 'bic', 'hqic': 'hqic', 'fpe': 'fpe'}
        selected_ic = ic_map.get(ic, 'aic')
        optimal_lag = getattr(lag_order_result, selected_ic, None)
        if optimal_lag is None or optimal_lag == 0:
            optimal_lag = 1

        # 2. 拟合 VAR 模型
        try:
            var_result = model.fit(maxlags=optimal_lag, trend=trend)
        except Exception as e:
            raise ValueError(_('VAR 模型拟合失败: %(error)s') % {'error': str(e)})

        # 3. 生成 HTML 输出
        diff_note = _('(%(diff_order)s阶差分)') % {'diff_order': diff_order} if diff_order > 0 else ""
        overall_title = title if title else _('VAR 向量自回归模型%(diff_note)s') % {'diff_note': diff_note}
        html = f'<div class="table-editable-container">'
        html += render_table_title_editor(overall_title)

        # 3.1 模型概要信息(含各方程概要)
        # 保存 display_names 供 summary 使用
        display_names = [f'D{diff_order}.{c}' for c in valid_cols] if diff_order > 0 else valid_cols
        self._var_display_names = display_names
        html += self._build_var_summary(var_result, df_clean, optimal_lag, trend, diff_order, decimals)

        # 3.2 滞后阶数选择表(使用 Stata 兼容的固定样本计算)
        html += self._build_lag_selection_table_stata(df_clean, max_lags, selected_ic, trend, decimals)

        # 3.3 各方程回归系数表
        html += self._build_var_coefficients_table(var_result, valid_cols, display_names, decimals)

        html += '</div>'
        self.custom_html = html

Released under the AGPL-3.0 License.