如何在Python中实现向量化滚动窗口回归模型?
滚动窗口回归的高效实现:替代双重循环方案
当然可以不用显式遍历列和时间周期,通过向量化矩阵运算或结合sklearn的批量拟合能力,能大幅提升滚动窗口回归的效率,下面是具体实现思路和代码:
一、向量化矩阵运算(纯numpy实现)
OLS回归有闭式解:$\hat{\beta} = (X^T X)^{-1} X^T y$,我们可以利用numpy的滑动窗口视图把所有窗口的X和y转换成三维数组,然后批量计算所有窗口、所有y列的系数,完全避免显式循环。
import numpy as np import pandas as pd # 假设已定义 rolling_window、returns(多列y)、X(特征矩阵) rolling_window = 60 X_arr = X.values y_arr = returns.values # 生成滑动窗口视图:不复制数据,仅创建视图,内存效率极高 n_windows = len(X_arr) - rolling_window + 1 # X_windows: (窗口数, 窗口大小, 特征数) X_windows = np.lib.stride_tricks.sliding_window_view(X_arr, (rolling_window, X_arr.shape[1])).squeeze(axis=1) # y_windows: (窗口数, 窗口大小, y列数) y_windows = np.lib.stride_tricks.sliding_window_view(y_arr, (rolling_window, y_arr.shape[1])).squeeze(axis=1) # 批量计算闭式解,用lstsq替代inv避免数值稳定性问题 coeffs = np.array([np.linalg.lstsq(X_win, y_win, rcond=None)[0] for X_win, y_win in zip(X_windows, y_windows)]) # 将结果转为DataFrame方便分析 coeffs_df = pd.DataFrame( coeffs.reshape(n_windows, -1), index=returns.index[rolling_window-1:], columns=[f"{y_col}_{x_col}" for y_col in returns.columns for x_col in X.columns] )
二、结合sklearn实现批量滚动回归
如果需要用到sklearn的模型(比如带正则化的回归、流水线等),可以利用LinearRegression支持多列y拟合的特性,只需要循环窗口(或并行加速),不用遍历y列:
from sklearn.linear_model import LinearRegression from joblib import Parallel, delayed # 定义单窗口拟合函数,一次处理所有y列 def fit_single_window(X_win, y_win): model = LinearRegression(fit_intercept=False) # 与statsmodels OLS默认行为一致(若X无截距项) model.fit(X_win, y_win) return model.coef_ # 返回形状:(y列数, 特征数) # 并行处理所有窗口,提升计算速度 coeffs = Parallel(n_jobs=-1)( delayed(fit_single_window)(X_windows[i], y_windows[i]) for i in range(n_windows) ) # 转换为统一格式的数组 coeffs = np.array(coeffs).transpose(0, 2, 1) # 转为(窗口数, 特征数, y列数)
关键注意事项
- 滑动窗口视图是原数组的视图而非副本,不会额外占用内存,但若修改视图会影响原数据,需注意操作边界。
- 若数据存在缺失值,需先完成填充/删除等预处理,否则矩阵运算会报错。
- 对于超大样本,并行计算(joblib)能进一步缩短耗时;若窗口数量少,单线程计算即可。
- 若需要拟合值、R²等指标,可在拟合函数中一并返回,批量收集结果。
内容的提问来源于stack exchange,提问作者Guillaume Favre
相关产品推荐
相关产品推荐

