Python错误索引器中的OLS滚动回归:索引超出范围
对于我的评估,我想对在()中找到的数据集运行一个滚动的3窗口Python错误索引器中的OLS滚动回归:索引超出范围,python,python-3.x,numpy,scikit-learn,statsmodels,Python,Python 3.x,Numpy,Scikit Learn,Statsmodels,对于我的评估,我想对在()中找到的数据集运行一个滚动的3窗口OLS回归估计,如下所示。数据集中的第三列(Y)是我的真实值——这就是我想要预测(估计)的值 使用一个简单的OLS回归估计,我用下面的脚本进行了尝试 # /usr/bin/python -tt import numpy as np import matplotlib.pyplot as plt import pandas as pd df = pd.read_csv('estimated_pred.csv') model = pd
OLS回归估计
,如下所示。数据集中的第三列(Y)是我的真实值——这就是我想要预测(估计)的值
使用一个简单的OLS回归估计
,我用下面的脚本进行了尝试
# /usr/bin/python -tt
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('estimated_pred.csv')
model = pd.stats.ols.MovingOLS(y=df.Y, x=df[['X']],
window_type='rolling', window=3, intercept=True)
df['Y_hat'] = model.y_predict
print(df['Y_hat'])
print (model.summary)
df.plot.scatter(x='X', y='Y', s=0.1)
然而,使用statsmodels
或scikit-learn
似乎是一个很好的选择,用于简单回归之外的事情。我尝试使用statsmodels
使以下脚本正常工作,但使用更高的数据集子集(例如,对于数据集的1000多行)重新执行索引器:索引超出范围
最后,我想做一个Y
(即,根据X
的前3个滚动值预测Y
的当前值。我们如何使用statsmodels
或scikit learn
对pd.stats.ols.MovingOLS
进行预测?因为我找不到任何参考,我想我发现了您的问题:
从sm.add_constant
的中,有一个名为has_constant
的参数,您需要将其设置为add
(默认值为skip
)
has_常量:str{'raise','add','skip'}
如果``data'已经有一个常量,则返回默认值
不添加其他常量的数据。如果“raise”,将引发
如果存在常量,则出错。使用“添加”将复制
常量(如果存在)。对结构化或
重新排列。在这种情况下不检查常量
基本上,对于循环的迭代,变量time
在子集中是常量,因此函数没有添加常量,因此RollOLS.params只有2个条目
temp
Out[12]:
time X Y a b1 b2
541 0.16182 13 20.0 19.49 3.15289 -1.26116e-05
542 0.16182 14 20.0 20 0 7.10543e-15
543 0.16182 15 20.0 20 -7.45058e-09 0
sm.add_constant(temp.loc[:,['time','X']])
Out[13]:
time X
541 0.16182 13
542 0.16182 14
543 0.16182 15
sm.add_constant(temp.loc[:,['time','X']], has_constant = 'add')
Out[14]:
const time X
541 1 0.16182 13
542 1 0.16182 14
543 1 0.16182 15
因此,如果在sm.add\u constant
函数中有has\u constant='add'
,错误就会消失,但是解释变量中会有两个线性相关列,这使得矩阵不可逆,因此回归没有意义。你能报告错误的完整跟踪吗?当然。下面是完整的数据l错误跟踪。文件
用于新行:回溯(最后一次调用):文件“./Desktop/rolling\u regression/rolling\u regression2.py”,第26行,在df.iloc[i,df.columns.get\u loc('b2')]=RollOLS.params[2]文件中“./anaconda/lib/python3.5/site packages/pandas/index/base.py”,第1986行,在pandas.tslib.get_值_框(s,key)文件“pandas/tslib.pyx”第777行,在pandas.tslib.get_值_框(pandas/tslib.c:17017)文件“pandas/tslib.pyx”第793行,在pandas.tslib.get_值_框(pandas/tslib.c:16774)中IndexError:index out bounds
对sm.OLS的调用似乎成功。请检查/显示rolols.params以确保它实际上有3个条目。是的。它实际上只对数据集的几行有效(例如:500行)-当我使用更高的数据集子集(比如1000)尝试时,会出现索引器:索引越界错误。我可以建议使用%debug和“u”进行跟踪,这样您可以看到在执行以下操作时是否会发生错误:RollOLS.params[2]或执行df.iloc[i,df.columns.get_loc('b2')]。无论如何,错误发生在循环的最后一行,这是一个与使用错误索引访问相关的错误,与sm.OLSThank you FLab无关。我仍然无法理解为什么它只在数据集的100行中工作,而没有错误。您所说的是什么意思,但您将有两个线性相关的列解释变量中的ns,这使得矩阵不可逆,因此回归没有意义
?我想df['a']
是我脚本中的常量。我认为索引541-543是时间在3次观察中第一次是常量。在第二点上,查看代码片段的最后输出。本质上,时间=0.16182*常量,因此矩阵的秩是2(而不是3)。这个问题称为多重共线性(在本例中为完美):啊哈,太好了,谢谢你。当我们做打印(temp)
它只打印最后3个预测,怎么样?我们想打印所有的预测?你是说到那时为止的所有预测吗?如果有帮助,你可以从数据中检索它们。通常使用OLS,你的回归是:y=常数+b1*时间+b2*x。因此,如果你有一个新的观察(t*,x*)您可以使用OLS估计的系数,通过在公式中插入值来估计y*值。现在您正在进行滚动回归,因此您可以重新估计系数。您通常这样做是为了查看y、时间和X之间的关系是否随时间变化。顺便说一句,3个观察值看起来太短了哦,让我抓住一个稳定的关系。
# /usr/bin/python -tt
import pandas as pd
import numpy as np
import statsmodels.api as sm
df=pd.read_csv('estimated_pred.csv')
df=df.dropna() # to drop nans in case there are any
window = 3
#print(df.index) # to print index
df['a']=None #constant
df['b1']=None #beta1
df['b2']=None #beta2
for i in range(window,len(df)):
temp=df.iloc[i-window:i,:]
RollOLS=sm.OLS(temp.loc[:,'Y'],sm.add_constant(temp.loc[:,['time','X']])).fit()
df.iloc[i,df.columns.get_loc('a')]=RollOLS.params[0]
df.iloc[i,df.columns.get_loc('b1')]=RollOLS.params[1]
df.iloc[i,df.columns.get_loc('b2')]=RollOLS.params[2]
#The following line gives us predicted values in a row, given the PRIOR row's estimated parameters
df['predicted']=df['a'].shift(1)+df['b1'].shift(1)*df['time']+df['b2'].shift(1)*df['X']
print(df['predicted'])
#print(df['b2'])
#print(RollOLS.predict(sm.add_constant(predict_x)))
print(temp)
temp
Out[12]:
time X Y a b1 b2
541 0.16182 13 20.0 19.49 3.15289 -1.26116e-05
542 0.16182 14 20.0 20 0 7.10543e-15
543 0.16182 15 20.0 20 -7.45058e-09 0
sm.add_constant(temp.loc[:,['time','X']])
Out[13]:
time X
541 0.16182 13
542 0.16182 14
543 0.16182 15
sm.add_constant(temp.loc[:,['time','X']], has_constant = 'add')
Out[14]:
const time X
541 1 0.16182 13
542 1 0.16182 14
543 1 0.16182 15