Модель линейной регрессии Python (Pandas, statsmodels) - Ошибка значения: несоответствие размеров матриц эндогенного экзога - PullRequest
0 голосов
/ 09 июня 2018

Мой друг спросил меня об этом коде линейной регрессии, и я тоже не смог его решить, так что теперь это и мой вопрос.

Ошибка, которую мы получаем: ValueError:Матрицы endog и exog имеют разные размеры

Когда я удаляю «Tech» из ind_names, он работает нормально.Это может быть бессмысленно, но ради устранения возможных ошибок синтаксиса я попытался это сделать.

Метки технической и финансовой промышленности не распределены в DataFrame одинаково, поэтому, возможно, это вызывает несоответствие размера?Но я не мог отлаживать дальше, поэтому решил спросить вас, ребята.

Было бы очень приятно получить подтверждение об ошибках и идеях решения.Пожалуйста, найдите код ниже.

    #We have a portfolio constructed of 3 randomly generated factors (fac1, fac2, fac3). 
#Python code provides the following message 
#ValueError: The indices for endog and exog are not aligned

import pandas as pd
from numpy.random import rand
import numpy as np
import statsmodels.api as sm

fac1, fac2, fac3 = np.random.rand(3, 1000) #Generate  random factors

#Consider a collection of hypothetical stock portfolios
#Generate randomly 1000 tickers
import random; random.seed(0)
import string
N = 1000
def rands(n):
  choices = string.ascii_uppercase
  return ''.join([random.choice(choices) for _ in range(n)])


tickers = np.array([rands(5) for _ in range(N)])
ticker_subset = tickers.take(np.random.permutation(N)[:1000])

#Weighted sum of factors plus noise

port = pd.Series(0.7 * fac1 - 1.2 * fac2 + 0.3 * fac3 + rand(1000), index=ticker_subset)
factors = pd.DataFrame({'f1': fac1, 'f2': fac2, 'f3': fac3}, index=ticker_subset)

#Correlations between each factor and the portfolio 
#print(factors.corrwith(port))
factors1=sm.add_constant(factors)


#Calculate factor exposures using a regression estimated by OLS
#print(sm.OLS(np.asarray(port), np.asarray(factors1)).fit().params)

#Calculate the exposure on each industry
def beta_exposure(chunk, factors=None):
    return sm.OLS(np.asarray(chunk), np.asarray(factors)).fit().params


#Assume that we have only two industries – financial and tech

ind_names = np.array(['Financial', 'Tech'])
#Create a random industry classification 

sampler = np.random.randint(0, len(ind_names), N)
industries = pd.Series(ind_names[sampler], index=tickers, name='industry')
by_ind = port.groupby(industries)



exposures=by_ind.apply(beta_exposure, factors=factors1)
print(exposures)
#exposures.unstack()

#Determinate the exposures on each industry 

1 Ответ

0 голосов
/ 10 июня 2018

Понимание сообщения об ошибке:

ValueError: матрицы endog и exog имеют разные размеры

Хорошо, неплохо.Эндогенная матрица и экзогенная матрица имеют разные размеры.И модуль предоставляет эту страницу , которая сообщает, что эндогенные факторы внутри системы и экзогенные факторы вне ее .

Некоторая отладка

Проверьте, какие формы мы получаем для наших массивов.Для этого нам нужно разобрать этот единственный вкладыш и вывести .shape аргументов или, возможно, вывести первую горстку каждого из них.Также закомментируйте строку с ошибкой.Итак, мы обнаруживаем, что получаем:

chunk [490]
factor [1000    4]
chunk [510]
factor [1000    4]

О!Вот оно.Мы ожидали, что фактор также будет разбит на части.Это должно быть [490 4] в первый раз и [510 4] во второй раз.Примечание: поскольку категории назначаются случайным образом, они будут отличаться каждый раз.

Так что в основном у нас слишком много информации в этой функции.Мы можем использовать блок, чтобы увидеть, какие факторы выбрать, отфильтровать факторы, чтобы они были именно такими, и тогда все будет работать.

Просмотр определений функций в документах:

class statsmodels.regression.linear_model.OLS(endog, exog=None, missing='none', hasconst=None, **kwargs)

Мыпросто передают два аргумента, а остальные являются необязательными.Давайте посмотрим на два, которые мы проходим.

endog (как массив) - 1-я эндогенная переменная ответа.Зависимая переменная.

exog (в виде массива) - массив nobs xk, где nobs - количество наблюдений, а k - количество регрессоров ...

Ah, endog и exog снова.endog является 1-мерным массивом.Пока все хорошо, форма 490 работает.exog nobs? О, это число наблюдений.Таким образом, это двумерный массив, и в этом случае нам нужна форма 490 на 4.

Эта конкретная проблема:

beta_exposure должна быть:

def beta_exposure(chunk, factors=None):
    factors = factors.loc[factors.index.isin(chunk.index)]
    return sm.OLS(np.asarray(chunk), np.asarray(factors)).fit().params

Проблема в том, что вы применяете beta_exposures к каждой части списка (она рандомизирована, поэтому, скажем, 490 элементов для Financial и 510 для Tech), но factors=factors1 всегда дает вам 1000 значений (groupby код не касается этого).

См. http://www.statsmodels.org/dev/generated/statsmodels.regression.linear_model.OLS.html и http://www.statsmodels.org/dev/endog_exog.html для ссылок, которые я использовал, исследуя это.

...