Regresión Fama-Macbeth en Python

Mehvish Ashiq 15 febrero 2024
  1. Regresión de Fama-Macbeth y su importancia
  2. Pasos para implementar la regresión Fama-Macbeth en Python
  3. Usa LinearModels para implementar la regresión Fama-Macbeth en Python
  4. Enfoque alternativo para implementar la regresión de Fama-Macbeth en Python
Regresión Fama-Macbeth en Python

El artículo de hoy educa sobre la regresión de Fama-Macbeth, su importancia y su implementación.

Regresión de Fama-Macbeth y su importancia

En las teorías de valoración de activos, utilizamos factores de riesgo para describir los rendimientos de los activos. Estos factores de riesgo pueden ser microeconómicos o macroeconómicos.

Los factores de riesgo microeconómicos incluyen el tamaño de la empresa y las diferentes métricas financieras de la empresa, mientras que los factores de riesgo macroeconómicos son la inflación del consumidor y el desempleo.

La regresión de Fama-Macbeth es un modelo de regresión de dos pasos que se utiliza para probar los modelos de valoración de activos. Es un enfoque práctico para medir qué tan correctamente estos factores de riesgo describen los rendimientos de la cartera o de los activos.

Este modelo es útil para determinar la prima de riesgo asociada a la exposición a estos factores.

Ahora, el punto es, ¿por qué llamamos a Fama-Macbeth, un modelo de regresión de dos pasos? Descubramos estos pasos a continuación.

  1. Este paso consiste en realizar una regresión del rendimiento de cada activo frente a uno o varios factores de riesgo utilizando el enfoque de series temporales. Obtenemos la exposición de retorno a cada factor conocido como betas, cargas de factor o exposición de factor.
  2. Este paso se trata de hacer una regresión de los rendimientos de todos los activos contra los activos betas adquiridos en el paso anterior (paso 1) usando un enfoque transversal. Aquí, obtenemos una prima de riesgo para cada factor.

La prima proyectada a lo largo del tiempo para la exposición de la unidad a cada factor de riesgo se calcula promediando los coeficientes una vez para cada elemento, según Fama y Macbeth.

Pasos para implementar la regresión Fama-Macbeth en Python

Según la actualización para reflejar las circunstancias de la biblioteca para Fama-Macbeth a partir del otoño de 2018, fama_macbeth se ha erradicado del módulo pandas de Python desde hace un tiempo.

Entonces, ¿cómo podemos implementar Fama-Macbeth si estamos trabajando con Python? Tenemos los siguientes dos enfoques que aprenderemos uno por uno en este tutorial.

  1. Podemos usar la función fama_macbeth en LinearModels si usamos la versión 3 de Python.
  2. Si no estamos obligados a usar LinearModels, o si estamos usando la versión 2 de Python, lo más probable es que el mejor caso sea escribir nuestra implementación para Fama-Macbeth.

Usa LinearModels para implementar la regresión Fama-Macbeth en Python

  • Importe los módulos y bibliotecas necesarios.
    import pandas as pd
    import numpy as np
    from pathlib import Path
    from linearmodels.asset_pricing import LinearFactorModel
    from statsmodels.api import OLS, add_constant
    import matplotlib.pyplot as plt
    import pandas_datareader.data as web
    import seaborn as sns
    import warnings
    
    warnings.filterwarnings("ignore")
    sns.set_style("whitegrid")
    

    Primero, importamos todos los módulos y bibliotecas que necesitaremos para implementar Fama-Macbeth usando LinearModels. A continuación se hace una breve descripción de todos ellos:

    • Importamos pandas para trabajar con data frames y numpy para arrays.
    • El pathlib crea una ruta al archivo especificado colocando este script específico en el objeto Path.
    • Importamos LinearFactorModel desde linearmodels.asset_pricing. Los modelos factoriales lineales relacionan la rentabilidad del activo con valores de un número restringido/limitado de factores, con una relación que se describe mediante una ecuación lineal.
    • A continuación, importamos OLS para evaluar el modelo de regresión lineal y add_constant para añadir una columna de unos al array. Puede obtener más información sobre statsmodels aquí.
    • Después de eso, importamos pandas_datareader para acceder a los últimos datos remotos para usar con pandas. Funciona para varias versiones de pandas.
    • Importamos las bibliotecas matplotlib y seaborn para el trazado y visualización de datos.
    • Importamos Warnings para usar su método filterwarnings(), que ignora las advertencias.
    • Por último, utilizamos el método set_style() del módulo seaborn, que establece los parámetros que controlan el estilo general de las tramas.
  • Acceda al conjunto de datos de cartera de investigación y factor de riesgo remoto.
    ff_research_data_five_factor = "F-F_Research_Data_5_Factors_2x3"
    ff_factor_dataset = web.DataReader(
        ff_research_data_five_factor, "famafrench", start="2010", end="2017-12"
    )[0]
    

    Aquí, estamos utilizando el conjunto de datos de cartera de investigación y factores de riesgo actualizados (los cinco factores Fama-French) disponibles en su sitio web para volver a una frecuencia mensual que obtenemos para 2010-2017 como se indicó anteriormente.

    Usamos DataReader() para extraer datos del recurso de Internet especificado en el marco de datos pandas, que es ff_factor_dataset en nuestra valla de código. El DataReader() admite varias fuentes, por ejemplo, Tiingo, IEX, Alpha Vantage y más que puede leer en esta página.

    print("OUTPUT for info(): \n")
    print(ff_factor_dataset.info())
    

    A continuación, usamos los métodos df.info() y df.describe() donde info() imprime la información del marco de datos que incluye el número de columnas, tipos de datos de columnas, etiquetas de columna, índice de rango, memoria uso y el número de celdas en cada columna (valores no nulos).

    Puede ver la salida producida por info() a continuación.

    PRODUCCIÓN:

    OUTPUT for info():
    
    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 96 entries, 2010-01 to 2017-12
    Freq: M
    Data columns (total 6 columns):
    #   Column Non-Null Count Dtype
    ---  ------  --------------  -----
    0   Mkt-RF 96 non-null     float64
    1   SMB     96 non-null     float64
    2   HML     96 non-null     float64
    3   RMW     96 non-null     float64
    4   CMA     96 non-null     float64
    5   RF      96 non-null     float64
    dtypes: float64(6)
    memory usage: 5.2 KB
    None
    

    A continuación, usamos el método describe() de la siguiente manera.

    print("OUTPUT for describe(): \n")
    print(ff_factor_dataset.describe())
    

    El método describe() muestra el resumen estadístico del marco de datos; también podemos usar este método para la serie Python. Este resumen estadístico contiene la media, la mediana, el conteo, la desviación estándar, los valores percentiles de las columnas y el mínimo y el máximo.

    Puede encontrar el resultado del método describe() a continuación.

    PRODUCCIÓN:

    OUTPUT for describe():
    
    		Mkt-RF        SMB        HML        RMW        CMA         RF
    count 96.000000 96.000000 96.000000 96.000000 96.000000 96.000000
    mean    1.158438   0.060000  -0.049271   0.129896   0.047708   0.012604
    std     3.580012   2.300292   2.202912   1.581930   1.413033   0.022583
    min    -7.890000  -4.580000  -4.700000  -3.880000  -3.240000   0.000000
    25%    -0.917500  -1.670000  -1.665000  -1.075000  -0.952500   0.000000
    50%     1.235000   0.200000  -0.275000   0.210000   0.010000   0.000000
    75%     3.197500   1.582500   1.205000   1.235000   0.930000   0.010000
    max    11.350000   7.040000   8.190000   3.480000   3.690000   0.090000
    
  • Acceda a 17 carteras de la industria y reste la tasa del factor de riesgo.
    ff_industry_portfolio = "17_Industry_Portfolios"
    ff_industry_portfolio_dataset = web.DataReader(
        ff_industry_portfolio, "famafrench", start="2010", end="2017-12"
    )[0]
    ff_industry_portfolio_dataset = ff_industry_portfolio_dataset.sub(
        ff_factor_dataset.RF, axis=0
    )
    

    Aquí, usamos DataReader() para acceder a 17 carteras o activos de la industria con una frecuencia mensual y restamos la tasa sin riesgo (RF) del marco de datos devuelto por DataReader(). ¿Por qué? Es porque el modelo factorial trabaja con los rendimientos en exceso.

    Ahora, usaremos el método info() para obtener información sobre el marco de datos encadenado.

    print(ff_industry_portfolio_dataset.info())
    

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 96 entries, 2010-01 to 2017-12
    Freq: M
    Data columns (total 17 columns):
    #   Column Non-Null Count Dtype
    ---  ------  --------------  -----
    0   Food    96 non-null     float64
    1   Mines   96 non-null     float64
    2   Oil     96 non-null     float64
    3   Clths   96 non-null     float64
    4   Durbl   96 non-null     float64
    5   Chems   96 non-null     float64
    6   Cnsum   96 non-null     float64
    7   Cnstr   96 non-null     float64
    8   Steel   96 non-null     float64
    9   FabPr   96 non-null     float64
    10 Machn   96 non-null     float64
    11 Cars    96 non-null     float64
    12 Trans   96 non-null     float64
    13 Utils   96 non-null     float64
    14 Rtail   96 non-null     float64
    15 Finan   96 non-null     float64
    16 Other   96 non-null     float64
    dtypes: float64(17)
    memory usage: 13.5 KB
    None
    

    De manera similar, describimos este marco de datos utilizando el método describe().

    print(ff_industry_portfolio_dataset.describe())
    

    PRODUCCIÓN:

    		 Food       Mines      Oil        Clths      Durbl      Chems  \
    count 96.000000 96.000000 96.000000 96.000000 96.000000 96.000000
    mean    1.046771   0.202917   0.597187   1.395833   1.151458   1.305000
    std     2.800555   7.904401   5.480938   5.024408   5.163951   5.594161
    min    -5.170000 -24.380000 -11.680000 -10.000000 -13.160000 -17.390000
    25%    -0.785000  -5.840000  -3.117500  -1.865000  -2.100000  -1.445000
    50%     0.920000  -0.435000   0.985000   1.160000   1.225000   1.435000
    75%     3.187500   5.727500   4.152500   3.857500   4.160000   4.442500
    max     6.670000 21.940000 15.940000 17.190000 16.610000 18.370000
    
    		 Cnsum      Cnstr      Steel      FabPr      Machn      Cars   \
    count 96.000000 96.000000 96.000000 96.000000 96.000000 96.000000
    mean    1.186979   1.735521   0.559167   1.350521   1.217708   1.279479
    std     3.142989   5.243314   7.389679   4.694408   4.798098   5.719351
    min    -7.150000 -14.160000 -20.490000 -11.960000  -9.070000 -11.650000
    25%    -0.855000  -2.410000  -4.395000  -1.447500  -2.062500  -1.245000
    50%     1.465000   2.175000   0.660000   1.485000   1.525000   0.635000
    75%     3.302500   5.557500   4.212500   3.837500   4.580000   4.802500
    max     8.260000 15.510000 21.350000 17.660000 14.750000 20.860000
    
    		 Trans      Utils      Rtail      Finan      Other
    count 96.000000 96.000000 96.000000 96.000000 96.000000
    mean    1.463750   0.896458   1.233958   1.248646   1.290938
    std     4.143005   3.233107   3.512518   4.839150   3.697608
    min    -8.560000  -6.990000  -9.180000 -11.140000  -7.890000
    25%    -0.810000  -0.737500  -0.952500  -1.462500  -1.090000
    50%     1.480000   1.240000   0.865000   1.910000   1.660000
    75%     4.242500   2.965000   3.370000   4.100000   3.485000
    max    12.980000   7.840000 12.440000 13.410000 10.770000
    
  • Calcule los rendimientos en exceso.

    Antes de avanzar hacia el cálculo de los rendimientos en exceso, debemos realizar algunos pasos más.

    data_store = Path("./data/assets.h5")
    
    wiki_prices_df = pd.read_csv(
        "./dataset/wiki_prices.csv",
        parse_dates=["date"],
        index_col=["date", "ticker"],
        infer_datetime_format=True,
    ).sort_index()
    
    us_equities_data_df = pd.read_csv("./dataset/us_equities_data.csv")
    
    with pd.HDFStore(data_store) as hdf_store:
        hdf_store.put("quandl/wiki/prices", wiki_prices_df)
    
    with pd.HDFStore(data_store) as hdf_store:
        hdf_store.put("us_equities/stocks", us_equities_data_df.set_index("ticker"))
    

    Primero, creamos un archivo assets.h5 en una carpeta de datos que reside en el directorio actual. A continuación, usamos el método read_csv() para leer los archivos wiki_prices.csv y us_equities_data.csv en la carpeta dataset del mismo directorio.

    Después de eso, usamos HDFStore() como se indicó anteriormente para almacenar datos en formato HDF5.

    with pd.HDFStore("./data/assets.h5") as hdf_store:
        prices = hdf_store["/quandl/wiki/prices"].adj_close.unstack().loc["2010":"2017"]
        equities = hdf_store["/us_equities/stocks"].drop_duplicates()
    
    sectors = equities.filter(prices.columns, axis=0).sector.to_dict()
    prices = prices.filter(sectors.keys()).dropna(how="all", axis=1)
    
    returns_df = prices.resample("M").last().pct_change().mul(100).to_period("M")
    returns_df = returns.dropna(how="all").dropna(axis=1)
    print(returns_df.info())
    

    En la valla de código anterior, leemos /quandl/wiki/prices y /us_equities/stocks que acabamos de almacenar en el archivo assets.h5 y los guardamos en las variables prices y equities.

    Luego, aplicamos algunos filtros en “precios” y “acciones”, volvemos a muestrear y eliminamos los valores faltantes. Finalmente, imprimimos la información de un data frame returns_df usando el método info(); Puedes ver la salida a continuación.

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 95 entries, 2010-02 to 2017-12
    Freq: M
    Columns: 1986 entries, A to ZUMZ
    dtypes: float64(1986)
    memory usage: 1.4 MB
    None
    

    Ahora, ejecute el siguiente código para alinear los datos.

    ff_factor_dataset = ff_factor_dataset.loc[returns_df.index]
    ff_industry_portfolio_dataset = ff_industry_portfolio_dataset.loc[returns_df.index]
    print(ff_factor_dataset.describe())
    

    PRODUCCIÓN:

    		Mkt-RF        SMB        HML        RMW        CMA         RF
    count 95.000000 95.000000 95.000000 95.000000 95.000000 95.000000
    mean    1.206000   0.057053  -0.054316   0.144632   0.043368   0.012737
    std     3.568382   2.312313   2.214041   1.583685   1.419886   0.022665
    min    -7.890000  -4.580000  -4.700000  -3.880000  -3.240000   0.000000
    25%    -0.565000  -1.680000  -1.670000  -0.880000  -0.965000   0.000000
    50%     1.290000   0.160000  -0.310000   0.270000   0.010000   0.000000
    75%     3.265000   1.605000   1.220000   1.240000   0.940000   0.010000
    max    11.350000   7.040000   8.190000   3.480000   3.690000   0.090000
    

    Ahora, estamos listos para calcular los rendimientos en exceso.

    excess_returns_df = returns_df.sub(ff_factor_dataset.RF, axis=0)
    excess_returns_df = excess_returns_df.clip(
        lower=np.percentile(excess_returns_df, 1),
        upper=np.percentile(excess_returns_df, 99),
    )
    excess_returns_df.info()
    

    En el bloque de código anterior, restamos el factor de riesgo del ff_factor_dataset y guardamos el marco de datos devuelto en excess_returns_df.

    A continuación, usamos el método .clip() que recorta los valores en los umbrales de entrada especificados. Por último, utilice info() para imprimir la información del marco de datos excess_returns_df.

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 95 entries, 2010-02 to 2017-12
    Freq: M
    Columns: 1986 entries, A to ZUMZ
    dtypes: float64(1986)
    memory usage: 1.4 MB
    

    Antes de pasar a la primera etapa de la regresión de Fama-Macbeth, usamos el método .drop(), que elimina la etiqueta especificada de columnas o filas. Tenga en cuenta que axis=1 significa una caída desde una columna, y axis=0 significa una caída desde las filas.

    ff_factor_dataset = ff_factor_dataset.drop("RF", axis=1)
    print(ff_factor_dataset.info())
    

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 95 entries, 2010-02 to 2017-12
    Freq: M
    Data columns (total 5 columns):
    #   Column Non-Null Count Dtype
    ---  ------  --------------  -----
    0   Mkt-RF 95 non-null     float64
    1   SMB     95 non-null     float64
    2   HML     95 non-null     float64
    3   RMW     95 non-null     float64
    4   CMA     95 non-null     float64
    dtypes: float64(5)
    memory usage: 4.5 KB
    None
    
  • Implemente el paso 1 de la regresión de Fama-Macbeth: Exposición de factores.
    betas = []
    for industry in ff_industry_portfolio_dataset:
        step_one = OLS(
            endog=ff_industry_portfolio_dataset.loc[ff_factor_dataset.index, industry],
            exog=add_constant(ff_factor_dataset),
        ).fit()
        betas.append(step_one.params.drop("const"))
    
    betas = pd.DataFrame(
        betas,
        columns=ff_factor_dataset.columns,
        index=ff_industry_portfolio_dataset.columns,
    )
    print(betas.info())
    

    El fragmento de código anterior implementa el primer paso de la regresión de Fama-Macbeth y accede a las estimaciones de carga de 17 factores. Aquí, usamos OLS() para evaluar el modelo de regresión lineal y add_constant() para agregar una columna de unos a la matriz.

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    Index: 17 entries, Food to Other
    Data columns (total 5 columns):
    #   Column Non-Null Count Dtype
    ---  ------  --------------  -----
    0   Mkt-RF 17 non-null     float64
    1   SMB     17 non-null     float64
    2   HML     17 non-null     float64
    3   RMW     17 non-null     float64
    4   CMA     17 non-null     float64
    dtypes: float64(5)
    memory usage: 1.3+ KB
    None
    
  • Implemente la regresión de Fama-Macbeth paso 2: Prima de riesgo.
    lambdas = []
    for period in ff_industry_portfolio_dataset.index:
        step_two = OLS(
            endog=ff_industry_portfolio_dataset.loc[period, betas.index], exog=betas
        ).fit()
        lambdas.append(step_two.params)
    
    lambdas = pd.DataFrame(
        lambdas, index=ff_industry_portfolio_dataset.index, columns=betas.columns.tolist()
    )
    print(lambdas.info())
    

    En el segundo paso, realizamos noventa y seis regresiones de rendimientos de período para la sección cruzada de la cartera sobre cargas factoriales.

    PRODUCCIÓN:

    <class 'pandas.core.frame.DataFrame'>
    PeriodIndex: 95 entries, 2010-02 to 2017-12
    Freq: M
    Data columns (total 5 columns):
    #   Column Non-Null Count Dtype
    ---  ------  --------------  -----
    0   Mkt-RF 95 non-null     float64
    1   SMB     95 non-null     float64
    2   HML     95 non-null     float64
    3   RMW     95 non-null     float64
    4   CMA     95 non-null     float64
    dtypes: float64(5)
    memory usage: 6.5 KB
    None
    

    Podemos visualizar los resultados de la siguiente manera:

    window = 24  # here 24 is the number of months
    axis1 = plt.subplot2grid((1, 3), (0, 0))
    axis2 = plt.subplot2grid((1, 3), (0, 1), colspan=2)
    lambdas.mean().sort_values().plot.barh(ax=axis1)
    lambdas.rolling(window).mean().dropna().plot(
        lw=1, figsize=(14, 5), sharey=True, ax=axis2
    )
    sns.despine()
    plt.tight_layout()
    

    PRODUCCIÓN:

    regresión fama macbeth en python - resultados

  • Implementa la regresión de Fama-Macbeth con el módulo LinearModels.
    model = LinearFactorModel(
        portfolios=ff_industry_portfolio_dataset, factors=ff_factor_dataset
    )
    result = model.fit()
    print(result)
    

    Aquí, usamos los Modelos lineales para implementar el procedimiento Fama-Macbeth de dos pasos que produce el siguiente resultado. Podemos usar print(result.full_summary) en lugar de print(result) para obtener el resumen completo.

    PRODUCCIÓN:

    					LinearFactorModel Estimation Summary
    ================================================================================
    No. Test Portfolios:                 17   R-squared:                      0.6879
    No. Factors:                          5   J-statistic:                    15.619
    No. Observations:                    95   P-value                         0.2093
    Date:                  Mon, Oct 24 2022   Distribution:                 chi2(12)
    Time:                          20:53:52
    Cov. Estimator:                  robust
    
    						  Risk Premia Estimates
    ==============================================================================
    		  Parameter Std. Err.     T-stat    P-value    Lower CI    Upper CI
    ------------------------------------------------------------------------------
    Mkt-RF         1.2355     0.4098     3.0152     0.0026      0.4324      2.0386
    SMB            0.0214     0.8687     0.0246     0.9804     -1.6813      1.7240
    HML           -1.1140     0.6213    -1.7931     0.0730     -2.3317      0.1037
    RMW           -0.2768     0.8133    -0.3403     0.7336     -1.8708      1.3172
    CMA           -0.5078     0.5666    -0.8962     0.3701     -1.6183      0.6027
    ==============================================================================
    
    Covariance estimator:
    HeteroskedasticCovariance
    See full_summary for complete results
    

Enfoque alternativo para implementar la regresión de Fama-Macbeth en Python

Podemos usar este enfoque si no queremos usar Modelos lineales o usar la versión 2 de Python.

  • Importe los módulos y bibliotecas.
    import pandas as pd
    import numpy as np
    import statsmodels.formula.api as sm
    

    Importamos pandas para trabajar con marcos de datos, numpy para jugar con matrices y statsmodels.formula.api, que es una interfaz conveniente para especificar modelos a través de cadenas de fórmulas y marcos de datos.

  • Leer y consultar el conjunto de datos.

    Supongamos que tenemos activos/carteras de la industria francesa de Fama en el panel como se indica a continuación (también hemos calculado algunas variables, por ejemplo, beta y rendimientos pasados para utilizar como nuestras variables x)

    data_df = pd.read_csv("industry_data.csv", parse_dates=["caldt"])
    data_df.query("caldt == '1995-07-01'")
    

    PRODUCCIÓN:

    	industry      caldt    ret    beta r12to2 r36to13
    18432     Aero 1995-07-01   6.26 0.9696 0.2755   0.3466
    18433    Agric 1995-07-01   3.37 1.0412 0.1260   0.0581
    18434    Autos 1995-07-01   2.42 1.0274 0.0293   0.2902
    18435    Banks 1995-07-01   4.82 1.4985 0.1659   0.2951
    
  • Utilice groupby() para calcular el modelo de regresión transversal mes a mes.
    def ols_coefficient(x, formula):
        return sm.ols(formula, data=x).fit().params
    
    
    gamma_df = data_df.groupby("caldt").apply(
        ols_coefficient, "ret ~ 1 + beta + r12to2 + r36to13"
    )
    gamma_df.head()
    

    Aquí usamos groupby porque Fama-Macbeth implica calcular el modelo de regresión transversal exacto mes a mes. Podemos crear una función que acepte un marco de datos (que es devuelto por groupby) y una fórmula pastosa; luego se ajustará al modelo y devolverá las estimaciones de los parámetros.

    PRODUCCIÓN:

    		  Intercept      beta     r12to2   r36to13
    caldt
    1963-07-01  -1.497012 -0.765721   4.379128 -1.918083
    1963-08-01 11.144169 -6.506291   5.961584 -2.598048
    1963-09-01  -2.330966 -0.741550 10.508617 -4.377293
    1963-10-01   0.441941 1.127567   5.478114 -2.057173
    1963-11-01   3.380485 -4.792643   3.660940 -1.210426
    
  • Calcule la media y el error estándar de la media.
    def fm_summary(p):
        s = p.describe().T
        s["std_error"] = s["std"] / np.sqrt(s["count"])
        s["tstat"] = s["mean"] / s["std_error"]
        return s[["mean", "std_error", "tstat"]]
    
    
    fm_summary(gamma_df)
    

    A continuación, calculamos la media, la prueba t (puede usar las estadísticas que desee) y el error estándar en la media, que es algo como lo anterior.

    PRODUCCIÓN:

    			 mean std_error     tstat
    Intercept 0.754904   0.177291 4.258000
    beta      -0.012176   0.202629 -0.060092
    r12to2     1.794548   0.356069 5.039896
    r36to13    0.237873   0.186680 1.274230
    
  • Mejora la velocidad y utiliza la función fama_macbeth.
    def ols_np(dataset, y_var, x_var):
        gamma_df, _, _, _ = np.linalg.lstsq(dataset[x_var], dataset[y_var], rcond=None)
        return pd.Series(gamma_df)
    

    Este paso es importante si nos preocupa la eficiencia. Si es así, podemos cambiar de statsmodels a numpy.linalg.lstsq.

    Para realizar estimaciones ols, podemos escribir una función similar a la anterior. Tenga en cuenta que no estamos haciendo nada para verificar los rangos de estas matrices.

    Si está utilizando la versión anterior de pandas, entonces lo siguiente debería funcionar. Pongamos un ejemplo usando fama_macbeth en pandas.

    print(data_df)
    fm = pd.fama_macbeth(y=data_df["y"], x=data_df[["x"]])
    print(fm)
    

    Aquí, observe la estructura a continuación. El fama_macbeth quiere que x-var e y-var tengan un índice múltiple con fecha como primera variable e id de acción/empresa/entidad como segunda variable en el índice.

    PRODUCCIÓN:

    			  y    x
    date       id
    2012-01-01 1   0.1 0.4
    		 2   0.3 0.6
    		 3   0.4 0.2
    		 4   0.0 1.2
    2012-02-01 1   0.2 0.7
    		 2   0.4 0.5
    		 3   0.2 0.1
    		 4   0.1 0.0
    2012-03-01 1   0.4 0.8
    		 2   0.6 0.1
    		 3   0.7 0.6
    		 4   0.4 -0.1
    
    
    ----------------------Summary of the Fama-Macbeth Analysis-------------------------
    
    Formula: Y ~ x + intercept
    # betas :   3
    
    ----------------------Summary of the Estimated Coefficients------------------------
       Variable          Beta       Std Err        t-stat       CI 2.5%      CI 97.5%
    		(x)       -0.0227        0.1276         -0.18       -0.2728        0.2273
    (intercept)        0.3531        0.0842          4.19        0.1881        0.5181
    
    --------------------------------End of the Summary---------------------------------
    

    Tenga en cuenta que estamos llamando a fm.summary simplemente imprimiendo fm como lo hicimos en la cerca de código anterior. Además, el fama_macbeth agrega automáticamente el intercepto y x-var debe ser un marco de datos.

    Podemos hacer lo siguiente si no queremos tener “intercepción”.

    fm = pd.fama_macbeth(y=data_df["y"], x=data_df[["x"]], intercept=False)
    
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Artículo relacionado - Python Regression