Pandas滚动回归:循环的替代方案
Pandas滚动回归:循环的替代方案
我充分利用了pandas的MovingOLS类(源代码在这里)在已弃用的stats/ols模块中。不幸的是,随着pandas 0.20的发布,该类被完全删除。
关于如何以高效的方式运行滚动OLS回归的问题已经被提出多次(例如在这里),但问题表述得比较宽泛,并未得到令人满意的答案。
以下是我的问题:
- 我如何最好地模仿pandas的MovingOLS的基本框架?这个类最吸引人的特点是能够将多个方法/属性视为单独的时间序列,例如系数、R平方、t统计量等,而无需重新运行回归。例如,您可以创建类似于model = pd.MovingOLS(y, x)的东西,然后调用.t_stat、.rmse、.std_err等。相反,在下面的示例中,我看不到避免强制创建滑动/滚动“块”(步幅)和为每个块运行回归/使用线性代数来获取模型参数的方法。是否有一种不涉及创建滑动/滚动“块”(步幅)和为每个块运行回归/使用线性代数来获取模型参数的方法?
- 更广泛地说,是什么让pandas的rolling.apply方法不能接受更复杂的函数?当您创建一个.rolling对象时,在非专业术语中,内部发生了什么,它是否与循环遍历每个窗口并创建更高维数组的方法有根本区别?
*即传递给.apply的func:
必须从ndarray输入产生单个值*args和**kwargs传递给函数
以下是我目前在一些示例数据中所做的工作,将贸易加权美元的百分比变化回归到利率差和铜价上。(这没有太多意义;只是随机选择的。)我已经将其从基于类的实现中取出,并尝试将其简化为一个更简单的脚本。
from datetime import date from pandas_datareader.data import DataReader import statsmodels.formula.api as smf syms = {'TWEXBMTH' : 'usd', 'T10Y2YM' : 'term_spread', 'PCOPPUSDM' : 'copper' } start = date(2000, 1, 1) data = (DataReader(syms.keys(), 'fred', start) .pct_change() .dropna()) data = data.rename(columns = syms) data = data.assign(intercept = 1.) # required by statsmodels OLS def sliding_windows(x, window): """Create rolling/sliding windows of length ~window~. Given an array of shape (y, z), it will return "blocks" of shape (x - window + 1, window, z).""" return np.array([x[i:i + window] for i in range(0, x.shape[0] - window + 1)]) data.head(3) Out[33]: usd term_spread copper intercept DATE 2000-02-01 0.012573 -1.409091 -0.019972 1.0 2000-03-01 -0.000079 2.000000 -0.037202 1.0 2000-04-01 0.005642 0.518519 -0.033275 1.0 window = 36 wins = sliding_windows(data.values, window=window) y, x = wins[:, :, 0], wins[:, :, 1:] coefs = [] for endog, exog in zip(y, x): model = smf.OLS(endog, exog).fit() # The full set of model attributes gets lost with each loop coefs.append(model.params) df = pd.DataFrame(coefs, columns=data.iloc[:, 1:].columns, index=data.index[window - 1:]) df.head(3) # rolling 36m coefficients Out[70]: term_spread copper intercept DATE 2003-01-01 -0.000122 -0.018426 0.001937 2003-02-01 0.000391 -0.015740 0.001597 2003-03-01 0.000655 -0.016811 0.001546