gpt4 book ai didi

python - 使用 Python Pandas 的累积 OLS

转载 作者:太空宇宙 更新时间:2023-11-03 12:08:53 25 4
gpt4 key购买 nike

我正在使用 Pandas 0.8.1,目前无法更改版本。如果较新的版本将有助于解决以下问题,请在评论中注明,而不是在答案中注明。此外,这是一个研究复制项目,因此即使在仅附加一个新数据点后重新运行回归可能很愚蠢(如果数据集很大),我仍然必须这样做。谢谢!

在 Pandas 中,pandas.olswindow_type 参数有一个 rolling 选项,但这似乎暗示这需要一些选择窗口大小或使用整个数据样本作为默认值。我希望以累积方式使用所有数据。

我正在尝试对按日期排序的 pandas.DataFrame 进行回归。对于每个索引 i,我想使用从最小日期到索引 i 的日期的可用数据运行回归。因此窗口在每次迭代中有效地增长 1,从最早的观察开始累积使用所有数据,并且没有数据从窗口中丢失。

我已经编写了一个函数(如下)与 apply 一起执行此操作,但速度慢得令人无法接受。相反,有没有办法使用 pandas.ols 直接执行这种累积回归?

这里有一些关于我的数据的更多细节。我有一个 pandas.DataFrame,其中包含一列标识符、一列日期、一列左侧值和一列右侧值。我想使用groupby根据标识符进行分组,然后对由左侧和右侧变量组成的每个时间段进行累积回归。

这是我可以在标识符分组对象上使用 apply 的函数:

def cumulative_ols(
data_frame,
lhs_column,
rhs_column,
date_column,
min_obs=60
):

beta_dict = {}
for dt in data_frame[date_column].unique():
cur_df = data_frame[data_frame[date_column] <= dt]
obs_count = cur_df[lhs_column].notnull().sum()

if min_obs <= obs_count:
beta = pandas.ols(
y=cur_df[lhs_column],
x=cur_df[rhs_column],
).beta.ix['x']
###
else:
beta = np.NaN
###
beta_dict[dt] = beta
###

beta_df = pandas.DataFrame(pandas.Series(beta_dict, name="FactorBeta"))
beta_df.index.name = date_column
return beta_df

最佳答案

根据评论中的建议,我创建了自己的函数,该函数可与 apply 一起使用,并依赖于 cumsum 来累积表达所需的所有单独术语OLS 单变量回归的矢量系数。

def cumulative_ols(
data_frame,
lhs_column,
rhs_column,
date_column,
min_obs=60,
):
"""
Function to perform a cumulative OLS on a Pandas data frame. It is
meant to be used with `apply` after grouping the data frame by categories
and sorting by date, so that the regression below applies to the time
series of a single category's data and the use of `cumsum` will work
appropriately given sorted dates. It is also assumed that the date
conventions of the left-hand-side and right-hand-side variables have been
arranged by the user to match up with any lagging conventions needed.

This OLS is implicitly univariate and relies on the simplification to the
formula:

Cov(x,y) ~ (1/n)*sum(x*y) - (1/n)*sum(x)*(1/n)*sum(y)
Var(x) ~ (1/n)*sum(x^2) - ((1/n)*sum(x))^2
beta ~ Cov(x,y) / Var(x)

and the code makes a further simplification be cancelling one factor
of (1/n).

Notes: one easy improvement is to change the date column to a generic sort
column since there's no special reason the regressions need to be time-
series specific.
"""
data_frame["xy"] = (data_frame[lhs_column] * data_frame[rhs_column]).fillna(0.0)
data_frame["x2"] = (data_frame[rhs_column]**2).fillna(0.0)
data_frame["yobs"] = data_frame[lhs_column].notnull().map(int)
data_frame["xobs"] = data_frame[rhs_column].notnull().map(int)
data_frame["cum_yobs"] = data_frame["yobs"].cumsum()
data_frame["cum_xobs"] = data_frame["xobs"].cumsum()
data_frame["cumsum_xy"] = data_frame["xy"].cumsum()
data_frame["cumsum_x2"] = data_frame["x2"].cumsum()
data_frame["cumsum_x"] = data_frame[rhs_column].fillna(0.0).cumsum()
data_frame["cumsum_y"] = data_frame[lhs_column].fillna(0.0).cumsum()
data_frame["cum_cov"] = data_frame["cumsum_xy"] - (1.0/data_frame["cum_yobs"])*data_frame["cumsum_x"]*data_frame["cumsum_y"]
data_frame["cum_x_var"] = data_frame["cumsum_x2"] - (1.0/data_frame["cum_xobs"])*(data_frame["cumsum_x"])**2
data_frame["FactorBeta"] = data_frame["cum_cov"]/data_frame["cum_x_var"]
data_frame["FactorBeta"][data_frame["cum_yobs"] < min_obs] = np.NaN
return data_frame[[date_column, "FactorBeta"]].set_index(date_column)
### End cumulative_ols

我已经在大量测试用例中验证了这与我以前的函数的输出和 NumPy 的 linalg.lstsq 函数的输出相匹配。我还没有对时间进行完整的基准测试,但据传闻,在我处理的案例中它快了大约 50 倍。

关于python - 使用 Python Pandas 的累积 OLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15095740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com