SVR 对所有特征给出相同的预测

数据挖掘 Python 回归 熊猫 麻木的 支持
2022-01-20 21:49:22

我正在创建一个基本应用程序来预测第 n+1 天股票的“收盘价”,给定股票 n 的特征,使用 Python 和 Scikit-learn

我的数据框中的示例行如下所示(2000 行)

       Open     Close    High     Low      Volume     
0      537.40   537.10   541.55   530.47   52877.98  

此视频类似,他使用“日期”和“开盘价”。在此示例中,日期是特征,开盘价是目标。

现在在我的示例中,我的数据集中没有“日期”值,而是希望使用 Open、High、Low、Volume 数据作为特征,因为我认为这会使其更准确

我是这样定义我的功能和目标的

features = df.loc[:,df.columns != 'Closing']
targets = df.loc[:,df.columns  == 'Closing']

这将返回一个看起来像这样的功能:

       Open      High      Low      Vol from  
29     670.02    685.11    661.09   92227.36

目标:

       Close
29     674.57

但是我意识到数据需要在一个 numpy 数组中,所以我现在得到了我的特性和目标

features = df.loc[:,df.columns != 'Closing'].values
targets = df.loc[:,df.columns  == 'Closing'].values

所以现在我的功能看起来像这样

[6.70020000e+02 6.85110000e+02 6.61090000e+02 9.22273600e+04
  6.23944806e+07]
 [7.78102000e+03 8.10087000e+03 7.67541000e+03 6.86188500e+04
  5.41391322e+08]

我的目标看起来像这样

[  674.57]
[ 8042.64]

然后我使用拆分我的数据

X_training, X_testing, y_training, y_testing = train_test_split(features, targets, test_size=0.8)

我尝试遵循 Scikit-Learn 文档,结果如下

svr_rbf = svm.SVR(kernel='rbf', C=100.0, gamma=0.0004, epsilon= 0.01 )
svr_rbf.fit(X_training, y_training)
predictions = svr_rbf.predict(X_testing)
print(predictions)

我假设这将预测给定测试特征的 Y 值,然后我可以根据实际 y_testing 值绘制它以查看它们的相似程度。但是,预测会为每个 X_testing 特征打印出相同的值。

[3763.84681818 3763.84681818 3763.84681818 3763.84681818 3763.84681818

我试过改变 epsilon、c 和 gamma 的值,但这似乎并没有改变预测总是给出相同值的事实

我知道预测股票价格可能不准确,但是在将模型应用于各种不同的测试数据时,我一定做错了才能得到相同的值

1个回答

有几个部分我认为改变会有所帮助。

首先,所有模型构建的通用模型:我建议您在将数据放入模型之前对其进行缩放。

它可能无法直接解决在每个步骤中接收相同预测值的问题,但您可能会注意到您的预测位于输入值范围内的某个位置 - 因为您使用的是未缩放的体积,这使得模型变得困难。它本质上必须同时在两个不同的规模上工作,这是不能做得很好的。

查看sklean中的 StandardScaler 以了解如何做到这一点。


接下来是一些改变的建议,特别是因为你正在处理股票价格:

我通常会预测明天股市的价值,而不是相同数据的收盘价,您使用的是open/high/low/volume对我来说,只有拥有高频(日内)数据才有意义。鉴于此,您需要将您的y价值转移一步。Pandas DataFrames 上有一种方法可以帮助您解决这个问题,但是由于您没有date列,并且您只需要移动一个时间步长,您就可以这样做:

features = df.loc[:-1, df.columns != 'Closing'].values    # leave out last step
targets = df.loc[1:, df.columns  == 'Closing'].values     # start one step later

然后,您甚至可以预测第二天的开盘价,或将closing数据保留在features数据中,因为这不会引入时间偏差。


需要更多设置的东西是看洗牌你的数据。同样,因为您想使用历史值来预测未来的值,所以您需要将相关的历史放在一起。看看我对这个问题的其他答案和图表,它解释了更多关于这个想法的信息。

编辑

您还应该缩放y_trainy_test,以便模型知道在该范围内进行预测。使用相同的StandardScaler实例执行此操作,以免引入偏见。看看这个简短的教程然后,您的预测将在同一范围内(例如[-1, +1])。您也可以计算该范围内的错误。如果你真的想要,你可以将你的预测缩放回原始范围,这样它们看起来更真实,但这并不是验证模型所必需的。您可以简单地在缩放空间中针对基本事实绘制预测。

查看这个线程StandardScaler,它解释了为什么应该在测试数据上使用相同实例的几个原因