J'ai eu la bonne utilisation de pandas' MovingOLS
classe (source ici) dans le obsolète stats/ols
module. Malheureusement, il a été vidé complètement avec les pandas de 0,20.
La question de l'exécution de roulement de la régression MCO de manière efficace a été demandé à plusieurs reprises (ici, par exemple), mais formulé de manière un peu large et à gauche sans une grande réponse, à mon avis.
Voici mes questions:
Comment puis-je mieux imiter le cadre de base de pandas'
MovingOLS
? La caractéristique la plus attrayante de cette classe a la possibilité d'afficher plusieurs méthodes/attributs de séries chronologiques distinctes--c'est à dire les coefficients de r-squared, des t-statistiques, etc ... sans avoir besoin de ré-exécuter la régression. Par exemple, vous pouvez créer quelque chose commemodel = pd.MovingOLS(y, x)
puis appelez.t_stat
,.rmse
,.std_err
, et la comme. Dans l'exemple ci-dessous, à l'inverse, je ne vois pas un moyen de contourner être obligé de calculer chaque statistique séparément. Est-il une méthode qui n'implique pas de créer de glissement ou de roulement "blocs" (progrès) et la course des régressions/à l'aide de l'algèbre linéaire pour obtenir les paramètres du modèle pour chaque?De façon plus générale, ce qui se passe sous le capot dans les pandas qui fait
rolling.apply
pas en mesure de prendre des fonctions plus complexes?* Lorsque vous créez un.rolling
objet, en d'autres termes, ce qui se passe en interne-est-il fondamentalement différent de boucler sur chaque fenêtre et la création d'une plus-dimensions tableau comme je le fais ci-dessous?
*À savoir, func
passée de .apply
:
Doit produire une valeur unique à partir d'un ndarray d'entrée *args et **kwargs sont passés à la fonction
Voici où j'en suis actuellement à la, avec quelques données, la régression de la variation en pourcentage dans le commerce pondéré du dollar sur les écarts de taux d'intérêt et le prix du cuivre. (Ce qui n'est pas de faire une tonne de sens; juste pris ces au hasard.) Je l'ai pris d'une classe basée sur la mise en œuvre et a essayé de la bande vers le bas pour un simple script.
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