Amber Memo

对数与零值:log(1+y) 不能当成百分比,以及泊松回归

PPML对数变换零值Stata

专利数、研发支出、出口额、诉讼次数、捐赠金额,这类变量都有很多零,又很偏。常见的做法是取 ln⁡(1+y)\ln(1+y),再把系数读成“增长百分之几”。这篇记这个做法的问题在哪,以及换成泊松回归之后要注意什么。

取对数的两个问题

第一个问题和零无关。把模型写成 y=μ(x) ηy = \mu(x)\,\eta,其中 E[η∣x]=1\E[\eta\mid x]=1,那么 E[y∣x]=μ(x)\E[y\mid x]=\mu(x),而

E[ln⁡y∣x]=ln⁡μ(x)+E[ln⁡η∣x].\E[\ln y\mid x] = \ln\mu(x) + \E[\ln\eta\mid x].

由于 Jensen 不等式,E[ln⁡η∣x]\E[\ln \eta\mid x] 不等于零,而且只要 η\eta 的方差随 xx 变化,它就会随 xx 变化。这时对 ln⁡y\ln y 做 OLS,斜率里混进了方差的变化,不再是 ln⁡μ(x)\ln\mu(x) 的斜率(Santos Silva and Tenreyro, 2006)。国内数据里“大企业波动小、小企业波动大”几乎是常态,方差随规模变化并不稀奇。

第二个问题是零。ln⁡0\ln 0 没有定义,ln⁡(1+y)\ln(1+y) 是一个补救,但它的系数取决于 yy 的单位。用“万元”和用“元”做因变量,ln⁡(1+y)\ln(1+y) 的回归系数就不一样;Chen and Roth(2024)证明,只要 yy 有零,任何这类变换估计出来的“百分比效应”都带有任意性,换一个单位就能得到不同的数。

模拟一:方差随 xx 变化

ln⁡y\ln y 的误差标准差是 0.7 e0.2x0.7\,e^{0.2x},y=exp⁡(1+0.2x)⋅ηy = \exp(1+0.2x)\cdot\eta,E[η∣x]=1\E[\eta\mid x]=1,真实半弹性是 0.2。5000 个观测,重复 500 次:

估计方法 系数均值 抽样标准差
对 ln⁡y\ln y 做 OLS 0.094 0.011
泊松伪极大似然(poisson, vce(robust)) 0.201 0.017

OLS 的系数只有真值的一半不到,而且这个偏差不会随样本量增大而消失。这里没有零,纯粹是第一个问题。

模拟二:有零的面板 DID

500 家企业、6 年,企业和年份固定效应,一半企业从第 4 年起受处理,yit∼Poisson(exp⁡(ai+0.1t+0.2Dit))y_{it}\sim\text{Poisson}(\exp(a_i + 0.1t + 0.2D_{it})),真实效应系数 0.2,即均值提高 e0.2−1≈22.1%e^{0.2}-1\approx 22.1\%。零值占 19.7%。重复 500 次,同一份数据用不同的因变量:

因变量 估计方法 系数均值 抽样标准差
ln⁡(1+y)\ln(1+y) reghdfe 0.143 0.036
ln⁡(1+10y)\ln(1+10y)(yy 的单位缩小 10 倍) reghdfe 0.247 0.079
ln⁡(1+100y)\ln(1+100y) reghdfe 0.341 0.132
ln⁡(1+1000y)\ln(1+1000y) reghdfe 0.433 0.187
asinh⁡(y)\operatorname{asinh}(y) reghdfe 0.179 0.046
yy ppmlhdfe 0.200 0.046
1000y1000y ppmlhdfe 0.200 0.046

同一份数据、同一个设计,只要把 yy 的单位改一下,ln⁡(1+y)\ln(1+y) 的系数就能从 0.14 到 0.43 之间任意变化,没有哪一个是“百分比效应”。反双曲正弦(asinh)只是换了一种形式,同样依赖单位,只是正好落在 0.18 附近。泊松回归的系数换单位之后一模一样(最后两行相同,只是常数项不同)。

一份样本上的输出,可以看到单位怎么影响显著性:

因变量 方法 系数 聚类到企业的标准误
ln⁡(1+y)\ln(1+y) reghdfe 0.122 0.035
ln⁡(1+1000y)\ln(1+1000y) reghdfe 0.359 0.187
yy 或 1000y1000y ppmlhdfe 0.195 0.044

PPML 怎么用,系数怎么读

泊松伪极大似然(PPML)估计的是 E[y∣x]=exp⁡(x′β)\E[y\mid x]=\exp(x'\beta),只要这个均值设定对了,它就是一致的,不要求 yy 真的服从泊松分布,也不要求是整数;有固定效应也没有附带参数问题(Hausman, Hall and Griliches, 1984;Wooldridge, 1999 中讨论了它的稳健性)。标准误要用稳健或聚类标准误。

* 高维固定效应:ppmlhdfe(ssc install ppmlhdfe;Correia, Guimarães and Zylkin, 2020)
ppmlhdfe y D, absorb(id year) vce(cluster id)
display 100*(exp(_b[D]) - 1)          // D 是 0/1 变量时,处理使 y 的均值变化的百分比

* 没有高维固定效应:Stata 自带
poisson y x i.year, vce(cluster id)

系数的读法:

  • 连续的解释变量:xx 增加一个单位,yy 的均值大约变化 100β100\beta%,更精确地说是 100(eβ−1)100(e^{\beta}-1)%。
  • 0/1 的处理变量:100(eβ−1)100(e^{\beta}-1)% 是均值的变化,比如上面一份样本里 0.195 对应 21.5%。
  • 解释变量本身取了对数:系数是弹性。

几个要注意的地方:

  1. 全为零的组会被丢掉。 ppmlhdfe 默认删掉那些在某个固定效应组内因变量全为零的观测(这种观测不影响估计,不删会让估计发散)。上面那份样本里,500 家企业里有 4 家全是零,一共 24 个观测被删,输出里会提示 “dropped 24 observations that are either singletons or separated by a fixed effect”。reghdfe 用 ln⁡(1+y)\ln(1+y) 时它们是留在样本里的,两种方法的样本量并不一样。
  2. 平行趋势变成了乘性的。 线性模型的 DID 假设处理组和对照组的水平差异的变化相同,PPML 假设的是比例变化相同。两种说法在同一份数据上不会同时成立,事件研究图的纵轴含义也跟着变。
  3. 交错处理。 把 PPML 用到分批实施的政策上,同样要当心双向固定效应在处理效应异质时的问题(见交错 DID 一篇)。非线性模型下的做法,可以看 Wooldridge(2023),它把那一篇提到的扩展 TWFE 推广到了泊松等非线性模型。
  4. 聚类。 固定效应与聚类的问题和线性回归一样,参见固定效应与聚类标准误。

什么时候 PPML 也不够

“有没有专利”和“有多少专利”是两个问题。PPML 估计的是均值的总变化,把两个渠道混在一起。如果关心的是扩展边际(从零变成非零),可以单独估计一个 0/1 结果的线性概率模型或 logit;如果关心的是集约边际(已经非零的那部分增长多少),只在 y>0y>0 的样本里取对数会碰到样本选择问题,见样本选择一篇。Chen and Roth(2024)的讨论是:先明确关心的是哪一个边际;要么把“从零变成非零”折算成集约边际的若干个百分点,把这个权衡写成显式的假设再去估计,要么只估计集约边际,并且用界去处理选择问题。

另外,如果因变量是比率(资产回报率、负债率)或者有负值,它们本来就不属于“非负且偏态”的范围,用不上这里的做法。

Cohn, Liu and Wardlaw(2022)检查了金融文献里 ln⁡(1+y)\ln(1+y) 的使用情况,同样建议在计数或接近计数的变量上用泊松回归,并指出 ln⁡(1+y)\ln(1+y) 会带来偏误。

代码

模拟一:

capture program drop sim_a
program define sim_a, rclass
    clear
    set obs 5000
    gen x = rnormal()
    gen s = 0.7*exp(0.2*x)
    gen y = exp(1 + 0.2*x) * exp(s*rnormal() - s^2/2)
    gen ly = ln(y)
    quietly reg ly x
    return scalar b_log = _b[x]
    quietly poisson y x, vce(robust)
    return scalar b_ppml = _b[x]
end
simulate b_log=r(b_log) b_ppml=r(b_ppml), reps(500) seed(20261015) nodots: sim_a
summarize

模拟二(把 ln(1+k*y) 的几种单位和 ppmlhdfe 放在一起):

capture program drop sim_b
program define sim_b, rclass
    clear
    set obs 500
    gen id = _n
    gen a = 0.3 + 0.8*rnormal()
    gen treat = (id <= 250)
    expand 6
    bysort id: gen t = _n
    gen D = treat * (t >= 4)
    gen y = rpoisson(exp(a + 0.1*t + 0.2*D))
    foreach k in 1 10 100 1000 {
        gen double lyk = ln(1 + `k'*y)
        quietly reghdfe lyk D, absorb(id t)
        return scalar b_ln`k' = _b[D]
        drop lyk
    }
    gen double ihs = asinh(y)
    quietly reghdfe ihs D, absorb(id t)
    return scalar b_ihs = _b[D]
    quietly ppmlhdfe y D, absorb(id t) vce(cluster id)
    return scalar b_ppml = _b[D]
end
simulate b_ln1=r(b_ln1) b_ln10=r(b_ln10) b_ln100=r(b_ln100) b_ln1000=r(b_ln1000) ///
    b_ihs=r(b_ihs) b_ppml=r(b_ppml), reps(500) seed(20261015) nodots: sim_b
summarize

参考文献

  • Chen, J., & Roth, J. (2024). Logs with zeros? Some problems and solutions. Quarterly Journal of Economics, 139(2), 891–936.
  • Cohn, J. B., Liu, Z., & Wardlaw, M. I. (2022). Count (and count-like) data in finance. Journal of Financial Economics, 146(2), 529–551.
  • Correia, S., Guimarães, P., & Zylkin, T. (2020). Fast Poisson estimation with high-dimensional fixed effects. Stata Journal, 20(1), 95–115.
  • Hausman, J., Hall, B. H., & Griliches, Z. (1984). Econometric models for count data with an application to the patents–R&D relationship. Econometrica, 52(4), 909–938.
  • Santos Silva, J. M. C., & Tenreyro, S. (2006). The log of gravity. Review of Economics and Statistics, 88(4), 641–658.
  • Wooldridge, J. M. (1999). Distribution-free estimation of some nonlinear panel data models. Journal of Econometrics, 90(1), 77–97.
  • Wooldridge, J. M. (2023). Simple approaches to nonlinear difference-in-differences with panel data. Econometrics Journal, 26(3), C31–C66.