【问题标题】:Filling results of linear regression into a dataframe将线性回归的结果填充到数据框中
【发布时间】:2019-10-10 01:13:26
【问题描述】:

我在两只股票之间进行回归:

(y=bank_matrix['EXO.MI']

x=bank_matrix['LDO.MI'])。

我的任务是每 20 天更新一次斜率系数(回顾)。简而言之,我想从第 20 天(我的回顾)开始列出斜率系数。所以我运行了这个名为 reg 的回归模型。

与此同时,我创建:

A)3 个空列表:Intercetta=[]、Hedge=[]、Residuals=[]

B)1 名为 Regressione 的数据框,我想在此数据框列 (['Intercept','Hedge','Residuals']) 中复制回归结果(截距、斜率和残差)。

现在是整个代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas_datareader as pdr
from sklearn.linear_model import LinearRegression
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()


tickers=['EXO.MI','LDO.MI']
end=datetime.date.today()
gap=datetime.timedelta(days=650)
start=end- gap

Bank=pdr.get_data_yahoo(tickers,start=start,end=end)
bank_matrix=Bank['Adj Close']
bank_matrix=bank_matrix.dropna()

exor=bank_matrix['EXO.MI']
leonardo=bank_matrix['LDO.MI']

Regressione=pd.DataFrame(data=np.zeros((len(exor),3)),columns=['Intercetta','Hedge','Residuals'],index=bank_matrix['EXO.MI'].index)
lookback=20
Hedge=[]
Intercetta=[]
Residuals=[]

for i in range(lookback,len(exor)):
    reg=LinearRegression().fit(bank_matrix[['LDO.MI']][i-lookback+1:i],bank_matrix[['EXO.MI']][i-lookback+1:i])
    # Regressione.iloc[Regressione[i,'Hedge']]=reg.coef_[0]
    Hedge.append(reg.coef_[0])
    Intercetta.append(reg.intercept_)
    y_pred=reg.predict(bank_matrix[['LDO.MI']][lookback:])
    Residuals.append(bank_matrix[['EXO.MI']][lookback:].to_numpy()-y_pred)
Regressione=pd.DataFrame(list(zip(Intercetta,Hedge,Residuals)),columns=['Intercetta','Hedge','Residuals'])
Regressione.set_index(bank_matrix[['EXO.MI']].index[lookback:],inplace=True)

现在是最后一个问题:为什么在我的最终数据框“Regressione”中,第三列(“Residuals”)是一个水平数组???

【问题讨论】:

  • 因为你是这样插入的。更好的问题是——你想在那里拥有什么? IE。你想要的输出是什么?
  • 我的输出就是我已经说过的:一个具有 3 列(Intercetta、Hedge、Residuals)的数据框(Regressione)。每行必须包含 3 个元素,1 个用于列。但我真的不明白为什么在将 'y_pred' 附加到 'Residuals' 时,它变成了一个水平序列。我哪里错了?
  • 好吧,不执行你的代码,你附加到每一行残差的是:bank_matrix[['EXO.MI']][lookback:].to_numpy()-y_pred 它看起来确实像一个水平列表......
  • 好的,但是如何让我的第三列(残差)看起来与其他两列(Intercetta,残差)一样????我需要残差的列向量来构建我的信号,所以我必须使用并绘制它们。
  • 好的,调查一下,exor 是什么 - 我在执行过程中收到 exor is not defined 错误

标签: python pandas


【解决方案1】:

所以,首先我认为你做错了这两行:

y_pred=reg.predict(bank_matrix[['LDO.MI']][lookback:])
Residuals.append(bank_matrix[['EXO.MI']][lookback:].to_numpy()-y_pred)

您基本上尝试对从 1 到 20、然后从 2 到 21、3 到 22 等所有点进行线性回归。然后您尝试将该回归拟合到从 20 开始的观察数据。所以你得到了模型,例如5 到 24 并根据它预测 20 到最后的观察结果,并计算该预测与实际值之间的差异(注意 bank_matrix[['EXO.MI']][lookback:].to_numpy()for 循环期间不会改变)。

我想这里更有意义的是:

y_pred=reg.predict(bank_matrix[['LDO.MI']][i-lookback+1:i])
Residuals.append(bank_matrix[['EXO.MI']][i-lookback+1:i].to_numpy()-y_pred)

所以你会接受模型的错误,或者:

y_pred=reg.predict(bank_matrix[['LDO.MI']][i:])
Residuals.append(bank_matrix[['EXO.MI']][i:].to_numpy()-y_pred)

因此,您将尝试根据当前时间跨度将预测拟合到未来的数据中。

现在第一个选项将生成每行 19 个元素的列表,而另一个选项将生成 430 个列表,每行减少 1,直到最后一行为 1。因为这些是残差 - 所以你有一条线,有一个斜率,并且每个给定的时间跨度对冲 1,但是你有这个范围内的观察数量产生每个不同的结果。因此,取决于您想如何表达它 - 您可以将其设为残差平方和,或者取平均残差 - 您只需对其进行一些进一步的转换即可使其成为一个数字。

希望这会有所帮助...

【讨论】:

  • 嗨 Gregorz 感谢您的帮助,对我的延误表示歉意。你是对的,我混淆了回归期的时间框架,但更糟糕的是,我不明白,即使每 20 天只计算 1 个对冲和 Intercetta,残差仍然是 20!所以,我认为我应该为我的每一行残差做一个平均值。我写道: res=[i.mean() for i in Residuals]。那时我只是写了: plt.hist(res) 和 plt.plot(res) 来确认我的残差的准正态分布。
  • 顺便说一句:在我的 for-loop 回归中,我将 'Residuals.append....' 替换为 'Residuals.append(reg.residues_)。 'reg.residues_' 是否与每 20 天子周期的残差平均值相同???
【解决方案2】:

来自文档:

如果传递了一个 dict/series 的列表,并且键都包含在 DataFrame 的索引中,则生成的 DataFrame 中的列顺序将保持不变。

迭代地将行附加到 DataFrame 可能比单个连接的计算量更大。更好的解决方案是将这些行附加到列表中,然后将列表与原始 DataFrame 一次性连接起来。

例如,您需要使用df.loc 来修改数据框中的数据...

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 2018-05-08
    • 2014-01-17
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多