我的一个朋友问我有关线性回归代码的问题,但我也无法解决,所以现在这也是我的问题。
我们得到的错误:
ValueError:Endog和Exog矩阵的大小不同
当我从ind_names中删除“ Tech”时,它可以正常工作。这可能没有意义,但是为了消除语法错误的可能性,我尝试这样做。
技术和金融行业标签在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
最佳答案
了解错误消息:
ValueError:Endog和Exog矩阵的大小不同
好吧,还不错。内源矩阵和外源矩阵的大小不同。并且模块提供了此page,它告诉我们,内源性是系统内的因素,外源性是系统外的因素。
一些调试
检查数组获得的形状。要做到这一点,我们需要拆开那个单行并打印.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(类似数组)–一维内源性响应变量。因变量。
exog(类似数组)–一个nobs x k数组,其中nobs是观测值的数量,k是回归器的数量...
嗯,又是
endog
和exog
。 endog
是一维数组状的。到目前为止,形状490
仍然有效。 exog
点头?哦,它的观察数。所以它是一个二维数组,在这种情况下,我们需要用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应用于列表的每个部分(它是随机的,因此,假设
Financial
的元素为490个元素,Tech
的元素为510个),但是factors=factors1
总是为您提供1000个值(groupby
代码不会碰那个)。请参阅http://www.statsmodels.org/dev/generated/statsmodels.regression.linear_model.OLS.html和http://www.statsmodels.org/dev/endog_exog.html以获取我用于研究此内容的参考。
关于python - Python线性回归模型(Pandas,statsmodels)-值错误:endog exog矩阵大小不匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50776985/