【问题标题】:Speeding up rolling regressions in Stata加快Stata中的滚动回归
【发布时间】:2011-12-05 12:50:12
【问题描述】:

我应该避免rolling 并手动编写滚动回归代码吗?还是我最好创建一个包含重叠条目的巨型面板并使用statsby?即,给每个窗口自己的by 条目。在 R 中,我可以将数据预先拆分为日期框架列表,我认为这可以加快后续操作。

当我一个月前第一次从 R 切换到 Stata 时,我 asked this on Statalist 并且一致认为它应该需要很长时间。我在 Mata 中对 OLS 进行编码和编译,发现速度并没有提高(实际上是稍微变差了)。

这似乎滚动回归是一种常见的技术,Stata 似乎相当复杂;大多数研究人员是否将这些回归运行了 1 天以上?或者他们是否使用 SAS 进行这些计算?例如,我在 Compustat 数据库上从 1975 年到 2010 年(大约 30,000 次回归)运行以下内容,大约需要 12 个小时。

rolling arbrisk = (e(rss) / e(N)), window(48) stepsize(12) ///
         saving(arbrisk, replace) nodots: regress r1 ewretd

【问题讨论】:

    标签: regression stata rolling-computation


    【解决方案1】:

    asreg community-contributed 命令执行速度如此之快,甚至都不好笑。我在36 小时内运行了通常的循环代码,然后在不到5 分钟内使用asreg 运行了同样的代码。

    显然,每次回归的大部分时间都浪费在选择要运行回归的观​​测子集上,即o(N)N 是数据集中的观测总数.似乎 asreg 在 Mata 中实现了这个烂摊子。

    这将实现标准 CAPM 滚动回归:

    bysort permno: asreg mret_rf mkt_rf, wind(month 60)
    

    permno 是公司标识符,mret_rf 是每月公司回报减去无风险利率,mkt_rf 是每月市场回报减去无风险利率,month 是标识月份的日期变量的名称,以及60 滚动窗口的大小,以月为单位。

    在Stata中安装asreg

    ssc install asreg
    

    【讨论】:

    • rangestat (SSC) 是另一个社区贡献的替代方案。
    【解决方案2】:

    使用求和“手动”回归确实比使用rollingregress 快得多。下面的代码运行速度比rollingregress 快​​大约400 倍。当然,rolling 的可扩展性更高,但如果您只需要 beta、alpha、R^2 和 sigma^2,那么这将解决问题。

    program rolling_beta
        version 11.2
        syntax varlist(numeric), window(real)
    
        * get dependent and indpendent vars from varlist
        tempvar x y x2 y2 xy xs ys xys x2s y2s covxy varx vary
        tokenize "`varlist'"
        generate `y' = `1' 
        generate `x' = `2' 
        local w = `window' 
    
        * generate products
        generate `xy' = `x'*`y'
        generate `x2' = `x'*`x'
        generate `y2' = `y'*`y'
    
        * generate cumulative sums
        generate `xs' = sum(`x')
        generate `ys' = sum(`y')
        generate `xys' = sum(`xy')
        generate `x2s' = sum(`x2')
        generate `y2s' = sum(`y2')
    
        * generate variances and covariances
        generate `covxy' = (s`w'.`xys' - s`w'.`xs'*s`w'.`ys'/`w')/`w'
        generate `varx' = (s`w'.`x2s' - s`w'.`xs'*s`w'.`xs'/`w')/`w'
        generate `vary' = (s`w'.`y2s' - s`w'.`ys'*s`w'.`ys'/`w')/`w'
    
        * generate alpha, beta, r2, s2
        generate beta = `covxy'/`varx'
        generate alpha = (s`w'.`ys' - beta*s`w'.`xs')/`w'
        generate r2 = `covxy'*`covxy'/`varx'/`vary'
        generate s2 = `vary'*`w'*(1 - r2)/(`w' - 2)
    
    end
    

    【讨论】:

      【解决方案3】:

      我认为来自 Statalist 的人说这需要很长时间是对的。您正在对重要数量的观察值运行 30000 次回归。

      如果您想知道 Stata 将时间花在哪里,可以使用 profiler 命令。

      profiler clear
      profiler on
      rolling arbrisk = (e(rss) / e(N)), window(48) stepsize(12) ///
           saving(arbrisk, replace) nodots: regress r1 ewretd
      profiler off
      profiler report
      

      我想知道创建一个巨大的面板是否会有所帮助。您很可能会遇到内存问题。您应该事先检查您的面板有多大以及需要多少内存:

      http://www.stata.com/support/faqs/data/howbig.html

      使用自编码 OLS 例程并没有提高性能,我并不感到惊讶。 regress 命令是所谓的内置命令,已经非常高效了。很难做得更好。

      就 SAS 而言,在 SAS 中运行几个回归并检查需要多少时间。在Stata中做同样的事情。我的经验是 Stata 的 regress 比 SAS 中的 proc reg 快一点。

      【讨论】:

      • 谢谢!我知道国家主义者是对的,但我不希望他们是对的 :)。 profiler 只是发现rolling 中存在大量开销的技巧。我认为关键是使用while 循环和求和手动编码回归。
      • 开销如此之大我并不感到惊讶。 rolling 是一个通用工具,应该相当健壮。它会花一些时间检查您的数据。此外,它旨在使用大量统计命令。如果您对数据结构有把握,并且考虑到了特定的技术,那么应该可以提高性能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多