logo logo
您的位置 :首页 > 新闻中心
[Newbie]从线性到LSTM,从浅到深预测股票价格的5种方法
发布时间 : 2021-03-31 14:23:23 浏览: 132次 来源:【jake推荐】 作者:-=Jake=-

机器学习在股票价格预测中的应用

机器学习具有许多实际应用,包括时间序列预测。可以说,最有趣或最有利可图的一项是股价预测。

问题描述:

该问题的目标是使用前N天的数据来预测每日调整后的收盘价。我们使用过去3年(2015-11-25至2018-11-2 3)的历史价格数据)进行培训。

数据集如下:

预测股价方法

预测股价方法

我们将数据集分为60%的训练集,20%的验证集和20%的测试集。使用训练集训练模型预测股价方法,并通过观察对验证集的影响来调整超参数。最终模型的性能将在测试中进行评估。细分如下图所示:

预测股价方法

预测股价方法

用于评估模型有效性的指标是RMSE(均方误差)和MAPE(均值绝对百分比误差)。对于这两个指标,值越低,模型效果越好。

最终值

股价预测_预测股价方法_苏州设计预测股价

在“最后一个值”方法中,我们只需要将预测值设置为最后一个观测值即可。我们只需要将当天的收盘价设置为前一天的收盘价即可。该方法用作我们的基准方法,以将性能与某些更复杂的模型进行比较。它没有要训练的参数华体会首页 ,并且是一种低成本的预测模型。下图是使用“最后值”的预测结果。

预测股价方法

预测股价方法

移动平均值

在移动平均法中,预测是前N天调整后的收盘价的平均值,选择N需要学习和调整。对应于不同N值的RMSE值是根据移动平均法计算的,如下图所示:

预测股价方法

预测股价方法

对应于N = 2的移动平均法的效果如下:

预测股价方法

预测股价方法

Jupyter笔记本

线性回归

股价预测_预测股价方法_苏州设计预测股价

线性回归是一种模型化一个或多个自变量之间的线性关系的方法。我们使用线性回归模型来拟合前N天的收盘价,并获得一个模型来预测当天的收盘价。下图是N = 5时的示例。实际调整后的收盘价为(蓝色+),并且需要预测第6天的收盘价(黄色正方形)。有必要基于前5个实际值拟合线性回归模型(浅蓝色线),并预测第6天(明亮的蓝色圆圈)。

预测股价方法

预测股价方法

这是我们用来训练线性回归的代码:

import numpy as np
from sklearn.linear_model import LinearRegression
def get_preds_lin_reg(df, target_col, N, pred_min, offset):
    """
    Given a dataframe,get prediction at each timestep
    :param df: dataframe with the values you want to predict
    :param target_col: name of the column you want to predict
    :param N: use previous N values to do prediction
    :param pred_min: all predictions should be >= pred_min
    :param offset: for df we only do predictions for df[offset:]
    :return: pred_list: the predictions for target_col
    """
    # create linear regression object
    regr = LinearRegression(fit_intercepter=True)
    pred_list = []
    for i in range(offset, len(df['adj_close'])):
        X_train = np.array(range(len(df['adj_close'][i-N:i])))
        y_train = np.array(df['adj_close'][i-N:i])
        X_train = X_train.reshape(-1,1)
        y_train = y_train.reshape(-1,1)
        # train the model
        regr.fit(X_train, y_train)
        pred = regr.predict(N)
    # If the values are < pred_min,set it to be pred_min
    pred_list = np.array(pred_list)
    pred_list[pred_list < pred_min] = pred_min
    return pred_list

下图显示了验证集上与N的不同值相对应的模型的实际值和预测值之间的RMSE。我们最终选择了N = 5,因为它具有最低的RMSE。

预测股价方法

预测股价方法

以下曲线显示了N = 5时的预测效果。但是可以看出,它也没有表达增长或下降趋势的能力。

预测股价方法

预测股价方法

Jupyter笔记本

预测股价方法_股价预测_苏州设计预测股价

XGBoost

梯度提升是一种迭代方法预测股价方法,可不断学习残差并将弱模型转换为强模型。 XGBoost的全名是Extreme Gradient Boosting,它是一种旨在压缩计算资源限制的增强树算法。自2014年提出以来,它已广泛用于大型机器学习竞赛和实际项目中。

我们将在训练集上训练模型,基于验证集调整参数博亚体育 ,在测试集上进行预测,输出预测结果,并评估RMSE的效果。在机器学习任务中,列通常称为功能。在我们以前的模型中,仅使用当天收盘价的调整。除了原始要素列之外华体会 ,我们还可以提取当前数据序列的更多要素,以丰富数据的表达方式。例如凤凰彩票首页 ,我们在这里加入:

过去N天内每天的高点和低点之差;过去N天每天的开放和关闭之间的差异;

在构建该模型的过程中,我们可以实现特征缩放对模型效果的影响程度。当您不进行任何特征预处理时,在val集上的预测效果将非常差。由于火车的订价在89-125之间,因此模型预测只能输出89-125之间的数字。 val集的价格远远超出此范围开心8平台 ,并且该模型是完全不可预测的。预测结果在下图中为红色。

预测股价方法

预测股价方法

下一个测试是将火车集合缩放为正态分布,也称为均值= 0和方差= 1的高斯分布。同时,对验证集执行相同的缩放操作。但是,因为我们计算了训练集中的均值和方差,所以很明显该操作的效果不会很好。验证集上的数据比训练集上的数据大得多,并且在缩放后仍会很大。最终的预测结果仍然如上图所示,只不过输出是缩放后的y值。

最后,首先仍然将训练集缩放为正态分布,然后训练模型。随后,在对验证集进行预测时,每个要素列都会按比例缩放为正态分布。例如,我们需要在第T天进行预测,获取前N天的调整后收盘价,然后进行缩放。音量功能也是如此。然后对每个构造的特征重复相同的操作。然后,我们使用这些缩放的特征进行预测,并对得到的预测结果也进行缩放。最后,我们需要使用相应的均值和方差将其转换为相应的实际值。这种方法目前效果最好。这是我们用来训练XGBoost模型的代码:

import math
import numpy as np
from sklearn.metrics import mean_squared_error
from xgboost import XGBRegressor
def get_mape(y_true, y_pred):
    """
    compute mean absolute percentage error (MAPE)
    :param y_true:
    :param y_pred:
    :return:
    """
    y_true, y_pred = np.array(y_true), np.array(y_pred)
    return np.mean(np.abs((y_true- y_pred) / y_true)) * 100
def train_pred_eval_model(X_train_scaled,
                          y_train_scaled,
                          X_test_scaled,
                          y_test,
                          col_mean,
                          col_std,
                          seed = 100,
                          n_estimators = 100,
                          max_depth = 3,
                          learning_rate = 0.1,
                          min_child_weight=1,
                          subsample = 1,
                          colsample_bytree=1,
                          colsample_bylevel=1,
                          gamma = 0):
    """
    train model,do prediction,scale back to original range and do evaluation
    :param X_train_scaled: features for training,Scaled to mean=0 & var = 1
    :param y_train_scaled: target for training.Scaled to have mean=0 & var=1
    :param X_test_scaled: features for test.Each sample is scaled to mean=0 and var=1
    :param y_test: target for test.Actual values, not scaled.
    :param col_mean: means used to scale each sample of X_test_scaled.
    same length as X_test_scaled and y_test
    :param col_std: standard deviations used to scale each sample of X_test_scaled.
    same length as X_test_scaled and y_test
    :param seed: model seed
    :param n_estimators: number of boosted trees to it
    :param max_depth: maximum tree depth for base learners
    :param learning_rate: boosting learning rate (xgb'eta)
    :param min_child_weight: minimum sum of instance weight needed in a child
    :param subsample: subsample ratio of the training instance
    :param colsample_bytree: subsample ratio of columns when constructing each tree
    :param colsample_bylevel: subsample ratio of columns for each split, in each level
    :param gamma: minimum loss reduction required to make a further partition on a leaf node of the tree
    :return:
    rmse:root mean square error of y_test and est
    mape:mean absolute percentage error of y_test and est
    est:predicted values.Same length as y_test.
    """
    model = XGBoostRegressor(seed=model_seed,
                             n_estimators=n_estimators,
                             max_depth=max_depth,
                             learning_rate=learning_rate,
                             min_child_weight=min_child_weight,
                             subsample=subsample,
                             colsample_bytree=colsample_bytree,
                             colsample_bylevel=colsample_bylevel,
                             gamma=gamma)
    # train the model
    model.fit(X_train_scaled,y_train_scaled)
    # get predicted labels and scale back to original range
    est_scaled = model.predict(X_test_scaled)
    est = est_scaled * col_std +  col_mean
    # calculate RMSE
    rmse = math.sqrt(mean_squared_error(y_test,est))
    mape = get_mape(y_test,est)
    return rmse,mape,est

在不同的N值下,我们测试了与val集合上的实际值和预测值相对应的RMSE和MAPE值:

预测股价方法

预测股价方法_股价预测_苏州设计预测股价

预测股价方法

以RMSE作为评估标准,N = 3最佳。相应的预测效果如下:

预测股价方法

预测股价方法

Jupyter笔记本

LSTM

最后我们来到了LSTM!

LSTM是一种深度学习技术,旨在解决较长序列中遇到的梯度消失的问题。 LSTM具有三种类型的门:内存门,忘记门和输出门。忘记门和存储器门确定每个存储单元都已更新。输出门确定激活下一层的信息量。 LSTM的结构如下图所示。我们使用两层LSTM,中间的辍学层用于防止过度拟合。有关LSTM的更多信息,请按照Li Hongyi老师的课程进行。

预测股价方法

预测股价方法

这是我们用来训练LSTM模型的代码:

import math
import numpy as np
from keras.models import Sequential
from keras.layers import Dense,Dropout,LSTM
def train_pred_eval_model(x_train_scaled,
                          y_train_scaled,
                          x_test_scales,
                          y_test,
                          mu_test_list,
                          std_test_list,
                          lstm_units=50,
                          dropout_prob=0.5,
                          optimizer='adam',
                          epochs=1,
                          batch_size=1):
    """
    traim,prediction,scale back to original value,do evaluation
    :param x_train_scaled:
    :param y_train_scaled:
    :param x_test_scales:
    :param y_test:
    :param mu_test_list:list of means.Same length as y_test
    :param std_test_list:list of std devs.Same length as y_test
    :param lstm_units:dimensionality of the output space
    :param dropout_prob:fraction of the units to drop
    :param optimizer:optimizer for model.compile()
    :param epochs:epochs for model.fit()
    :param batch_size:batch size for model.fit()
    :return:
    rmse: root mean square error
    mape: mean absolute percentage error
    est:predictions
    """
    # create LSTM network
    model = Sequential()
    model.add(LSTM(units=lstm_units,
                   return_sequences=True,
                   input_shape=(x_train_scaled.shape[1],1)))
    # add dropout with a probability
    model.add(Dropout(dropout_prob))
    model.add(LSTM(units=lstm_units))
    # add dropout with a probability
    model.add(Dropout(dropout_prob))
    model.add(Dense(1))
    # compile and fit the LSTM network
    model.compile(loss='mean_squared_error',
                  optimizer=optimizer)
    model.fit(x_train_scaled,y_train_scaled,epochs=epochs,
              batch_size=batch_size,verbose=0)
    # Do prediction
    est_scaled = model.predict(x_test_scaled)
    est = (est_scaled * np.array(std_test_list).reshape(-1,1)) + 
    np.array(mu_test_list).reshape(-1,1)
    # calculate RMSE and MAPE
    rmse = math.sqrt(mean_squared_error(y_test,est))
    mape = get_mape(y_test, est)
    return rmse,mape,est

股价预测_预测股价方法_苏州设计预测股价

以下是val集合上LSTM的结果:

预测股价方法

预测股价方法

以下是基于LSTM预测的结果:

预测股价方法

预测股价方法

Jupyter笔记本

END

如上所述:

但这只是一种味道,不可能依靠简短的分析来获得收益。

就像我们从不同角度,在能力的不同阶段着眼于同一个问题一样。

参考链接

如果您觉得它有用且有意义,请关注我!

返回新闻资讯