documentacion - pandas python install
Pandas de regresiĆ³n rodante: alternativas al looping (1)
MovingOLS
un módulo MovingOLS
diseñado para imitar los MovingOLS
obsoletos de los MovingOLS
; esta here
Tiene tres clases principales:
-
OLS
: regresión de mínimos cuadrados ordinaria estática (ventana única). Las salidas son matrices NumPy. -
RollingOLS
: regresión de mínimos cuadrados ordinarios (ventana múltiple). Los resultados son matrices NumPy de dimensión superior. -
PandasRollingOLS
: envuelve los resultados deRollingOLS
en pandas Series & DataFrames. Diseñado para imitar el aspecto del módulo de pandas en desuso.
Tenga en cuenta que el módulo es parte de un package (que ahora está en PyPI) y requiere una importación entre paquetes.
Las dos primeras clases anteriores se implementan completamente en NumPy y utilizan principalmente el álgebra matricial. RollingOLS
aprovecha la difusión ampliamente también. Los atributos imitan en gran medida los statsmodels OLS RegressionResultsWrapper
.
Un ejemplo:
# 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 OLS, RollingOLS, 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
MovingOLS
buen uso de la clase MovingOLS
de pandas (fuente here ) dentro del módulo de stats/ols
obsoleto. Desafortunadamente, fue destruido completamente con pandas 0.20.
La pregunta de cómo ejecutar la regresión OLS rodante de manera eficiente se ha planteado varias veces ( here , por ejemplo), pero expresada de forma un poco amplia y sin una gran respuesta, en mi opinión.
Aquí están mis preguntas:
¿Cómo puedo imitar mejor el marco básico de los pandas ''
MovingOLS
? La característica más atractiva de esta clase fue la capacidad de ver múltiples métodos / atributos como series de tiempo separadas, es decir, coeficientes, r cuadrado, t-estadística, etc. sin necesidad de volver a ejecutar la regresión. Por ejemplo, podría crear algo comomodel = pd.MovingOLS(y, x)
y luego llamar a.t_stat
,.rmse
,.std_err
y similares. En el siguiente ejemplo, a la inversa, no veo una forma de ser forzado a computar cada estadística por separado. ¿Hay algún método que no implique crear "bloques" deslizantes / rodantes (zancadas) y ejecutar regresiones / usar álgebra lineal para obtener los parámetros del modelo para cada uno?En términos más generales, ¿qué sucede bajo el capó en pandas que hace que
rolling.apply
no pueda realizar funciones más complejas? * Cuando creas un objeto.rolling
, en términos simples, lo que está pasando internamente, es fundamentalmente diferente al bucle ¿Cada ventana y creando una matriz de mayor dimensión como lo estoy haciendo a continuación?
* Es decir, func
pasó a .apply
:
Debe generar un solo valor desde una entrada ndarray * args y ** kwargs se pasan a la función
Aquí es donde actualmente me encuentro con algunos datos de muestra, regresando los cambios porcentuales en el dólar ponderado por el comercio en los diferenciales de tasas de interés y el precio del cobre. (Esto no tiene mucho sentido; simplemente los seleccioné al azar). Lo saqué de una implementación basada en clase y traté de reducirlo a un script más simple.
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