写在前面
下面的这篇文章首先将介绍极限学习机(Extreme Learning Machine,ELM)的基本原理,然后通过python实现ELM,并将其用于股票价格预测当中。原代码在文末进行获取。
1
极限学习机的基本原理
极限学习机(Extreme Learning Machine,ELM)是由黄广斌提出来的求解单隐层神经网络的算法。ELM是一种应用于训练单隐层前馈神经网络的算法,传统的单隐层前馈神经网络由于其结构简单、训练速度快且具有较高的泛化能力等特点,已经在模式识别、信号处理、短期预测等领域有了很多应用成果。相比于传统的基于梯度下降的BP算法来训练SLFN,ELM具有更好的泛化能力和更快的训练速度。
对于一个如下图所示的单隐层神经网络,假设有 个样本 ,其中 ,则对于一个具有 个隐层节点的单隐藏层神经网络,前向传播的过程表示为:
其中, 表示激活函数, 是隐藏层的第 个权重矩阵, 是隐藏层的第 个偏置项, 是输出层的权重。
单隐藏层神经网络的目标是使得是输出的误差最小,表示为:
则若存在 使得:
用矩阵的形式表示:
其中, 是隐层节点的输出, 为输出层权重, 为期望输出。
为了训练单隐层神经网络得到 来最小化损失函数:
在ELM算法中,隐层权重 和偏置项 被随机确定,从而隐层的输出矩阵就被确定了,之后将这个训练过程转换为求解一个线性系统 ,并且输出层权重 可以被确定:
其中, 是矩阵 的Moore-Penrose广义逆。 且可证明求得的解的范数是最小的并且唯一。
因为ELM是一种 batch-based 的算法,所以这就意味着在训练阶段,它需要获得所有的训练数据,然后 train then test,而不是随着新数据的到来在线更新。所以黄广斌教授的团队又提出了在线顺序超限学习机算法,用于在线学习并更新网络参数,OS-ELM具备了ELM的速度和泛化能力上的优点,并且可以随着新数据的到来不断更新模型,而不是重新训练模型。OS-ELM分为两个部分,第一部分为通过少量的训练样本,利用ELM算法计算并初始化输出权重;第二部分开始在线学习,每次当一个新的数据样本到来时,通过一个递推公式得到新的输出权重,从而实现在线且快速的训练,具体的关于OS-ELM的递推公式推导可以参考相关论文和网上的资料。下面是OS-ELM的算法流程图:
2
环境准备
本地环境:
Python 3.7
IDE:Pycharm
库版本:
numpy 1.18.1
pandas 1.0.3
sklearn 0.22.2
matplotlib 3.2.1
然后,导入需要用到的所有库:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
3
代码实现
首先,需要先定义一个ELM的类,并初始化权重参数。
class ELM():
def __init__(self, input_nums, hidden_nums, output_nums):
self.input_nums = input_nums
self.hidden_nums = hidden_nums
self.output_nums = output_nums
self.is_inited = False
# 隐层权重矩阵
self.W = np.array([[np.random.uniform(-1, 1) for _ in range(self.hidden_nums)] for i in range(self.input_nums)])
# 隐层偏置项
self.bias = np.array([np.random.uniform(-1, 1) for _ in range(self.hidden_nums)])
# 输出层权重
self.beta = np.zeros(shape=[self.hidden_nums, self.output_nums])
# (H^{T}H)^{-1}
self.P = np.zeros(shape=[self.hidden_nums, self.hidden_nums])
之后定义初始化方法和激活函数,其中激活函数用到了sigmoid。初始化阶段首先计算隐层的输出矩阵,再计算输出层的权重 ,最后将is_inited参数设置为True表示已经完成初始化。
def init_train(self, x, target):
# output matrix
H = self.activation(np.dot(x, self.W) + self.bias)
HT = np.transpose(H)
HTH = np.dot(HT, H)
self.P = np.linalg.inv(HTH)
pHT = np.dot(self.P, HT)
self.beta = np.dot(pHT, target)
self.is_inited = True
def activation(self, x):
return 1 / (1 + np.exp(-x))
当完成模型的初始化之后,每当有新数据到来时可以用来进一步在线更新,更新的方式可以参考前面的OS-ELM的算法流程图。代码实现如下,其中x和target可以是单独的样本也可以是批次的样本。
def seq_train(self, x, target):
batch_size = x.shape[0]
H = self.activation(np.dot(x, self.W) + self.bias)
HT = np.transpose(H)
I = np.eye(batch_size)
Hp = np.dot(H, self.P)
HpHT = np.dot(Hp, HT)
temp = np.linalg.inv(I + HpHT)
pHT = np.dot(self.P, HT)
self.P -= np.dot(np.dot(pHT, temp), Hp)
pHT = np.dot(self.P, HT)
Hbeta = np.dot(H, self.beta)
self.beta += np.dot(pHT, target - Hbeta)
最后,是预测方法的实现,即进行一次前向计算:
def predict(self, x):
return np.dot(self.activation(np.dot(x, self.W) + self.bias), self.beta)
为了评估模型的效果,我们用到了上证指数14到17年四年的收盘价数据来进行了简单的实验验证。其中需要先对数据进行归一化,然后按照滑动窗口划分数据,然后划分训练和测试集。在进行实验时,我们先测试了不进行在线更新的ELM的效果,然后测试了进行在线更新的ELM的效果。两者的RMSE和拟合效果分别如下所示:
RMSE of ELM 34.04633755067868
RMSE of OS-ELM 29.139883515427595
从实验结果中可以看出ELM可以实现不错的数据拟合效果,并且经过在线更新的ELM可以实现更好的效果。虽然ELM与LSTM,TCN等深度学习相比,精度不是特别高,但是其简单的结构和更快的训练速度可以使其同样具有很强的实际应用价值。
4
总结
在这篇文章中,我们介绍了ELM的基本原理,并通过上证指数对模型进行了实验,可以看出ELM对股价预测具有一定的效果。另外,我们仅仅只是通过价格数据作为了数据输入,为了更好地结合市场特征,我们也可以将一些技术指标作为输入来使得模型学习更多的市场信息。
参考文献:
Huang, G. B. , Zhu, Q. Y. , & Siew, C. K. . (2006). Extreme learning machine: theory and applications. Neurocomputing, 70(1/3), 489-501.
简单易学的机器学习算法——极限学习机(ELM)
简单易学的机器学习算法——在线顺序极限学习机OS-ELM
完整代码和数据请在《人工智能量化实验室》公众号后台回复“090”关键字。本文内容仅仅是技术探讨和学习,并不构成任何投资建议。
了解更多人工智能与
量化金融知识
<-请扫码关注
让我知道你在看