簡體   English   中英

使用Python Pandas的累積OLS

[英]Cumulative OLS with Python Pandas

我正在使用Pandas 0.8.1,目前我無法更改版本。 如果新版本有助於解決以下問題,請在評論中注明,而不是回答。 此外,這是一個研究復制項目,所以即使在僅附加一個新數據點后重新運行回歸可能是愚蠢的(如果數據集很大),我仍然必須這樣做。 謝謝!

在熊貓,還有一個rolling的選項window_type參數pandas.ols但似乎暗示,這需要一個窗口大小或使用整個數據樣本為默認的一些選擇。 我希望以累積的方式使用所有數據。

我正在嘗試對按日期排序的pandas.DataFrame運行回歸。 對於每個索引i ,我想使用從索引i的最小日期到日期的可用數據運行回歸。 因此,窗口在每次迭代時有效地增加一個,所有數據從最早的觀察中累積使用,並且沒有數據從窗口中丟失。

我已經編寫了一個函數(下面),可以使用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倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM