Skip to content

固定效应模型 ​

吸收法(AbsorbingLS)估计的多维固定效应模型 yit=β′xit+αi+εit:个体效应 αi 不进入回归矩阵,可吸收个体、时间、行业等任意多维固定效应,结果与 Stata reghdfe 一致。

核心代码 ​

py
    def _fit_fixed_effects(
        self,
        df: pd.DataFrame,
        entity_col: str,
        time_col: str
    ) -> Any:
        """
        执行固定效应回归

        参数:
            df: 清洗后的数据框
            entity_col: 个体标识列
            time_col: 时间标识列

        返回:
            吸收式固定效应拟合结果
        """
        absorb_vars = [item for item in self._unique_preserve_order(self.fe_vars) if item in df.columns]
        if not absorb_vars:
            absorb_vars = [item for item in self._unique_preserve_order([entity_col, time_col]) if item and item in df.columns]
        if not absorb_vars:
            raise ValueError(_('固定效应回归至少需要选择 1 个固定效应变量。'))

        fit_info = self._fit_linear_model(
            df,
            self.y_var,
            [item for item in self.x_vars if item != self.y_var],
            model_kind='fe',
            absorb_vars=absorb_vars,
            header='Fixed Effects Results',
        )

        self.result = fit_info['result']
        self.model_stats = dict(fit_info['stats'])
        self.raw_output = fit_info['raw_output']
        self.display_x_vars = [item for item in self.x_vars if item != self.y_var]
        self.table_custom_rows = self._base_custom_rows(absorb_vars)
        return self.result

固定效应与聚类标签 ​

固定效应及聚类变量支持数值、文本和两者混合的标签。估计前按首次出现顺序编码为整数,避免底层排序比较整数与字符串;原始数据不变,缺失值继续按估计样本清洗规则处理。数字 1 与文本 "1" 保持不同分组,不会因统一转成字符串而被合并。已有字符串首尾空白规范化规则保持一致。

固定效应编码后再转换成分类变量,聚类标准误使用相同的分组编码规则:

py
def encode_grouping_series(series: pd.Series) -> pd.Series:
    """按首次出现顺序编码分组标签,保留缺失值以及数字与同形文本的区别。"""
    normalized = normalize_grouping_series(series)
    codes, _levels = pd.factorize(normalized, sort=False)
    encoded = pd.Series(codes, index=series.index, name=series.name)
    return encoded.where(encoded >= 0)
py
    def _absorbing_fit_kwargs(self, df: pd.DataFrame) -> Dict[str, Any]:
        se_type = str(self.se_options.get('type', 'iid') or 'iid').lower()
        if se_type == 'iid':
            return {'cov_type': 'unadjusted'}
        if se_type == 'cluster':
            cluster_var = self.se_options.get('cluster_var')
            if not cluster_var:
                raise ValueError(_('聚类标准误必须指定聚类变量。'))
            if cluster_var not in df.columns:
                raise ValueError(_('聚类变量未进入当前估计样本。'))
            # 与固定效应及自由度计算采用相同的分组语义,避免混合标签排序失败。
            return {'cov_type': 'clustered', 'clusters': encode_grouping_series(df[cluster_var])}
        return {'cov_type': 'robust'}

下载包中的 tests/test_fixed_effects_mixed_labels.py 覆盖混合标签、分类列、缺失值和原始数据保留,并比较编码前后的系数、协方差与自由度。

极小样本复现 ​

样本 fe_panel.csv 共 60 行(10 家企业 × 6 年),数据生成过程 y=0.6x1−0.4x2+αi+ε(真实系数 0.6 / -0.4)。

bash
python examples/run_fixed_effects.py

期望输出:

============================================================
固定效应模型(个体固定效应: firm)
============================================================
样本量 N = 60(10 家企业 × 6 年)
------------------------------------------------------------
变量                   系数          标准误
Constant     -0.6587***     (0.0966)
x1            0.6309***     (0.0573)
x2           -0.4010***     (0.0447)
------------------------------------------------------------
(数据生成过程真实系数: x1 = 0.6, x2 = -0.4)

Released under the AGPL-3.0 License.