Option rolling window obsolète dans OLS from Pandas to Statsmodels

comme le titre l'indique, où l'option fonction de roulement de la commande ols dans Pandas a-t-elle migré dans les modèles de statistiques? Je n'arrive pas à le trouver. Pandas me dit que la ruine est en cours:

FutureWarning: The pandas.stats.ols module is deprecated and will be removed in a future version. We refer to external packages like statsmodels, see some examples here: http://statsmodels.sourceforge.net/stable/regression.html
  model = pd.ols(y=series_1, x=mmmm, window=50)

en fait, si vous faites quelque chose comme:

import statsmodels.api as sm

model = sm.OLS(series_1, mmmm, window=50).fit()

print(model.summary())

vous obtenez des résultats (la fenêtre n'altère pas le fonctionnement du code) mais vous obtenez seulement les paramètres de l'exécution de régression sur l'ensemble de la période, pas la série de paramètres pour chacun des la période de roulement sur laquelle il devrait être censé travailler.

11
demandé sur Asher11 2016-05-19 11:22:53

3 réponses

j'ai créé un ols module conçu pour imiter pandas' déprécié MovingOLS ; il est ici .

elle comporte trois classes principales:

  • OLS : statique (guichet unique) ordinaire de la régression des moindres carrés. La sortie sont des tableaux NumPy
  • RollingOLS : régression des moindres carrés ordinaires par laminage (fenêtres multiples). La sortie sont des tableaux NumPy de dimension supérieure.
  • PandasRollingOLS : enveloppe les résultats de RollingOLS dans la série pandas & DataFrames. Conçu pour imiter l'apparence du module pandas déprécié.

notez que le module fait partie d'un package (que je suis en train de télécharger vers PyPi) et qu'il nécessite une importation inter-package.

les deux premières classes ci-dessus sont entièrement implémentées dans NumPy et utilisent principalement la matrice algèbre. RollingOLS tire aussi largement parti de la radiodiffusion. Les attributs imitent largement les OLS de stats-modèles RegressionResultsWrapper .

un exemple:

# Pull some data from fred.stlouisfed.org
from pandas_datareader.data import DataReader

syms = {'TWEXBMTH' : 'usd', 
        'T10Y2YM' : 'term_spread', 
        'PCOPPUSDM' : 'copper'
       }
data = (DataReader(syms.keys(), 'fred', start='2000-01-01')
        .pct_change()
        .dropna())
data = data.rename(columns=syms)
print(data.head())
                # usd  term_spread   copper
# DATE                                     
# 2000-02-01  0.01260     -1.40909 -0.01997
# 2000-03-01 -0.00012      2.00000 -0.03720
# 2000-04-01  0.00564      0.51852 -0.03328
# 2000-05-01  0.02204     -0.09756  0.06135
# 2000-06-01 -0.01012      0.02703 -0.01850

# Rolling regressions

from pyfinance.ols import PandasRollingOLS

y = data.usd
x = data.drop('usd', axis=1)

window = 12  # months
model = PandasRollingOLS(y=y, x=x, window=window)

print(model.beta.head())  # Coefficients excluding the intercept
            # term_spread   copper
# DATE                            
# 2001-01-01      0.00010  0.05568
# 2001-02-01      0.00047  0.06271
# 2001-03-01      0.00147  0.03576
# 2001-04-01      0.00161  0.02956
# 2001-05-01      0.00158 -0.04497

print(model.fstat.head())
# DATE
# 2001-01-01    0.28121
# 2001-02-01    0.42602
# 2001-03-01    0.38802
# 2001-04-01    0.39230
# 2001-05-01    0.41706
# Freq: MS, Name: fstat, dtype: float64

print(model.rsq.head())  # R-squared
# DATE
# 2001-01-01    0.05882
# 2001-02-01    0.08648
# 2001-03-01    0.07938
# 2001-04-01    0.08019
# 2001-05-01    0.08482
# Freq: MS, Name: rsq, dtype: float64
7
répondu Brad Solomon 2017-11-01 14:33:24

le déploiement de la bêta, avec sklearn

import pandas as pd
from sklearn import linear_model

def rolling_beta(X, y, idx, window=255):

    assert len(X)==len(y)

    out_dates = []
    out_beta = []

    model_ols = linear_model.LinearRegression()

    for iStart in range(0, len(X)-window):        
        iEnd = iStart+window

        model_ols.fit(X[iStart:iEnd], y[iStart:iEnd])

        #store output
        out_dates.append(idx[iEnd])
        out_beta.append(model_ols.coef_[0][0])

    return pd.DataFrame({'beta':out_beta}, index=out_dates)


df_beta = rolling_beta(df_rtn_stocks['NDX'].values.reshape(-1, 1), df_rtn_stocks['CRM'].values.reshape(-1, 1), df_rtn_stocks.index.values, 255)
4
répondu citynorman 2016-11-20 16:02:58

ajout pour complétude d'une solution numpy -seulement rapide qui limite les calculs seulement aux coefficients de régression et à l'estimation finale

Numpy roulant fonction de régression

import numpy as np

def rolling_regression(y, x, window=60):
    """ 
    y and x must be pandas.Series
    """
# === Clean-up ============================================================
    x = x.dropna()
    y = y.dropna()
# === Trim acc to shortest ================================================
    if x.index.size > y.index.size:
        x = x[y.index]
    else:
        y = y[x.index]
# === Verify enough space =================================================
    if x.index.size < window:
        return None
    else:
    # === Add a constant if needed ========================================
        X = x.to_frame()
        X['c'] = 1
    # === Loop... this can be improved ====================================
        estimate_data = []
        for i in range(window, x.index.size+1):
            X_slice = X.values[i-window:i,:] # always index in np as opposed to pandas, much faster
            y_slice = y.values[i-window:i]
            coeff = np.dot(np.dot(np.linalg.inv(np.dot(X_slice.T, X_slice)), X_slice.T), y_slice)
            estimate_data.append(coeff[0] * x.values[window-1] + coeff[1])
    # === Assemble ========================================================
        estimate = pandas.Series(data=estimate_data, index=x.index[window-1:]) 
        return estimate             

Notes

dans certaines utilisations spécifiques, qui ne nécessitent que l'estimation finale de la régression, x.rolling(window=60).apply(my_ols) semble être assez lent

pour rappel, les coefficients pour une régression peuvent être calculés comme un produit de matrice, comme vous pouvez le lire sur page des moindres carrés de wikipedia . Cette approche via la multiplication matricielle de numpy peut accélérer quelque peu le processus vs En utilisant les ols dans statsmodels . Ce produit est exprimé dans la ligne commençant par coeff = ...

0
répondu Pythonic 2017-05-01 06:41:32