tutorial documentacion python pandas numpy linear-regression statsmodels

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 de RollingOLS 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:

  1. ¿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 como model = 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?

  2. 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