时间序列中的线性回归 Pandas

6
我想用时间序列作为预测变量进行回归分析,并尝试按照此SO答案(OLS with pandas: datetime index as predictor)的建议来操作,但据我所知,这种方法似乎已经不再可行了。
请问我有什么遗漏或者是否有新的方法可以使用?
import pandas as pd

rng = pd.date_range('1/1/2011', periods=4, freq='H')       
s = pd.Series(range(4), index = rng)                                                                      
z = s.reset_index()

pd.ols(x=z["index"], y=z[0]) 

我遇到了这个错误。虽然这个错误信息很明确,但我想知道重新实现之前的解决方案时漏掉了什么。

类型错误:无法将 datetimelike 从 [datetime64[ns]] 转换为 [float64]


理想情况下,您不需要使用 reset_index()pd.ols(y=s, x=s) 对您是否有用? - Zero
1
是的,它可以!谢谢。你是否碰巧知道它是如何工作的,或者为什么从日期时间转换到我假设的浮点数会没有错误? - canyon289
算了,这似乎失败了。它只是对同一系列进行回归。 - canyon289
1个回答

3

我不确定为什么pd.ols如此挑剔(在我看来,您确实按照示例正确地操作了)。我怀疑这是由于pandas处理或存储日期时间索引的方式发生了变化,但我懒得进一步探究。无论如何,既然您的日期时间变量只有小时数不同,您可以使用dt访问器提取小时数:

pd.ols(x=pd.to_datetime(z["index"]).dt.hour, y=z[0])

然而,由于模型中包含截距(并且y是x的线性函数),这给出了r-squared为1,因此模型被过度规定。您可以将range更改为np.random.randn,然后您会得到类似于正常回归结果的东西。

In [6]: z = pd.Series(np.random.randn(4), index = rng).reset_index()                                                               
        pd.ols(x=pd.to_datetime(z["index"]).dt.hour, y=z[0])
Out[6]: 

-------------------------Summary of Regression Analysis-------------------------

Formula: Y ~ <x> + <intercept>

Number of Observations:         4
Number of Degrees of Freedom:   2

R-squared:         0.7743
Adj R-squared:     0.6615

Rmse:              0.5156

F-stat (1, 2):     6.8626, p-value:     0.1200

Degrees of Freedom: model 1, resid 2

-----------------------Summary of Estimated Coefficients------------------------
      Variable       Coef    Std Err     t-stat    p-value    CI 2.5%   CI 97.5%
--------------------------------------------------------------------------------
             x    -0.6040     0.2306      -2.62     0.1200    -1.0560    -0.1521
     intercept     0.2915     0.4314       0.68     0.5689    -0.5540     1.1370
---------------------------------End of Summary---------------------------------

或者,您可以将索引转换为整数,尽管我发现这种方法效果不佳(我假设是因为整数表示自纪元以来的纳秒数或类似的东西,因此非常大且会导致精度问题),但将其转换为整数并除以万亿级别的数确实有效,并且结果与使用dt.hour相同(即相同的r-squared):

pd.ols(x=pd.to_datetime(z["index"]).astype(int)/1e12, y=z[0])

错误信息来源

FWIW,看起来该错误信息是从类似以下内容的源代码中产生的:

pd.to_datetime(z["index"]).astype(float)

虽然有一个相当明显的解决方法:

pd.to_datetime(z["index"]).astype(int).astype(float)

两种解决方案都很有帮助,尤其是第二个。 - canyon289

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接