Skip to content

空间模型诊断

执行 LM、SDM 简化 Wald、固定效应类型 LR 与稳健 Hausman 检验。

核心代码

py
    def _fit_diagnostics(self, *, decimals: int, title: str) -> None:
        prepared = self._prepare_panel(require_x=True)
        diagnostic = str(self.spatial_options.get('diagnostic_type') or 'lm').lower()
        if diagnostic == 'wald' and str(self.se_options.get('type') or 'iid').lower() not in {'iid', 'oim'}:
            raise ValueError(_('SDM Wald 当前仅基于 OIM 协方差开放'))
        if diagnostic == 'lm':
            payload = self._lm_diagnostics(prepared)
            tests = list(payload['tests'])
            notes = [payload['note']]
        elif diagnostic == 'wald':
            model_type = 'sdm'
            result, arrays = self._fit_estimation(
                prepared,
                estimator='fe',
                effect_type=str(self.spatial_options.get('effect_type') or 'both'),
                model_type=model_type,
            )
            payload = self._sdm_wald_tests(result, arrays)
            tests = [
                {
                    'name': _('Wald:SDM 简化为 SAR'),
                    **payload['sar'],
                },
                {
                    'name': _('Wald:SDM 简化为 SEM'),
                    **payload['sem'],
                },
            ]
            notes = [_('Wald 检验基于完整 Durbin 项的双向固定效应 SDM 与 OIM 协方差。')]
        elif diagnostic == 'lr':
            payload = self._lr_diagnostics(prepared)
            tests = list(payload['tests'])
            notes = [payload['note']]
        elif diagnostic == 'hausman':
            payload = self._robust_hausman_diagnostic(prepared)
            tests = [{
                'name': _('Hausman:固定效应与随机效应'),
                'statistic': payload['statistic'],
                'df': payload['df'],
                'p': payload['p'],
            }]
            notes = [payload['note']]
        else:
            raise ValueError(_('当前空间诊断支持 LM、Wald、LR 与 Hausman 检验'))
        self.result_payload = {
            'diagnostic_type': diagnostic,
            'tests': tests,
            'notes': notes,
            diagnostic: payload,
            'alignment_report': self.alignment_report,
        }
        self.custom_html = self.render_diagnostic_table(tests, notes, decimals, title)
        self.model_stats = {'N': int(prepared['n'] * prepared['t']), 'Groups': prepared['n'], 'Periods': prepared['t']}
        self.raw_output = json_like_text(self.result_payload)

Released under the AGPL-3.0 License.