Pandas/Statsmodel OLS 预测未来值

5 投票
1 回答
24702 浏览
提问于 2025-04-18 18:37

我一直在尝试为我创建的模型预测未来的数值。我用过pandas和statsmodels中的OLS方法。以下是我在statsmodels中的代码:

import statsmodels.api as sm
endog = pd.DataFrame(dframe['monthly_data_smoothed8'])
smresults = sm.OLS(dframe['monthly_data_smoothed8'], dframe['date_delta']).fit()
sm_pred = smresults.predict(endog)
sm_pred

返回的数组长度和我原始数据表中的记录数量是一样的,但数值却不相同。当我用pandas做同样的事情时,没有返回任何值。

from pandas.stats.api import ols
res1 = ols(y=dframe['monthly_data_smoothed8'], x=dframe['date_delta'])
res1.predict

(注意,pandas中的OLS没有.fit这个函数)有没有人能帮我解释一下,如何从我的OLS模型中获取未来的预测值,无论是在pandas还是statsmodels中?我意识到我可能没有正确使用.predict这个方法,我也看过很多其他人遇到的问题,但似乎都不适用于我的情况。

编辑 我觉得定义的'endog'可能不对——我应该传入我想要预测的值;所以我创建了一个从最后一个记录值开始的12个时间段的日期范围。但我还是觉得缺少什么,因为我收到了以下错误:

matrices are not aligned

编辑 这里有一段数据,最后一列(红色部分)的数字是日期差值,表示从第一个日期起的月份差:

month   monthly_data    monthly_data_smoothed5  monthly_data_smoothed8  monthly_data_smoothed12 monthly_data_smoothed3  date_delta
0   2011-01-31  3.711838e+11    3.711838e+11    3.711838e+11    3.711838e+11    3.711838e+11    0.000000
1   2011-02-28  3.776706e+11    3.750759e+11    3.748327e+11    3.746975e+11    3.755084e+11    0.919937
2   2011-03-31  4.547079e+11    4.127964e+11    4.083554e+11    4.059256e+11    4.207653e+11    1.938438
3   2011-04-30  4.688370e+11    4.360748e+11    4.295531e+11    4.257843e+11    4.464035e+11    2.924085

1 个回答

10

我觉得你遇到的问题是,statsmodels 默认情况下不添加截距,这样你的模型就无法很好地拟合数据。要解决这个问题,你可以在代码中这样做:

dframe = pd.read_clipboard() # your sample data
dframe['intercept'] = 1
X = dframe[['intercept', 'date_delta']]
y = dframe['monthly_data_smoothed8']

smresults = sm.OLS(y, X).fit()

dframe['pred'] = smresults.predict()

另外,值得一提的是,当处理数据框(DataFrames)时,statsmodel 的公式 API 使用起来要简单得多,而且默认会添加截距(如果想去掉,可以加个 - 1)。下面的例子应该会给出相同的结果。

import statsmodels.formula.api as smf

smresults = smf.ols('monthly_data_smoothed8 ~ date_delta', dframe).fit()

dframe['pred'] = smresults.predict()

编辑:

要预测未来的值,只需将新数据传递给 .predict()。例如,使用第一个模型:

In [165]: smresults.predict(pd.DataFrame({'intercept': 1, 
                                          'date_delta': [0.5, 0.75, 1.0]}))
Out[165]: array([  2.03927604e+11,   2.95182280e+11,   3.86436955e+11])

关于截距,数字 1 本身没有特别的含义,它只是基于最小二乘法(OLS)的数学原理(截距就像一个总是等于 1 的回归变量),所以你可以直接从总结中提取这个值。查看 statsmodels 的 文档,添加截距的另一种方法是:

X = sm.add_constant(X)

撰写回答