1
机器学习的基本概念
如今人工智能成为一大热门话题,一些专业术语如机器学习、深度学习等逐渐被大家所熟悉,那么它们到底是什么?它们之间究竟有怎样的关系呢?
我们通过一张图直观感受一下。
人工智能范围很广,泛指通过计算机实现人的头脑思维,使得机器像人一样去决策。
机器学习是人工智能的重要分支,是实现人工智能的一种技术。其涉及概率论、统计学、逼近论、凸分析、计算复杂度等多门学科。
深度学习是机器学习的一个分支,它也是传统神经网络的延伸,通过神经网络模型来模拟人脑进行学习,使其具有更强大的表达能力。卷积神经网络(Convolutional Neural Networks)、递归神经网络(Recurrent Neural Networks)都属于深度学习的范畴。你肯定听说过谷歌旗下DeepMind公司开发的AlphaGo战胜人类顶尖围棋选手。这里AlphaGo主要的工作原理就是深度学习。
自然语言处理则是深度学习发展的产物。
总而言之,深度学习是机器学习的一个子集,机器学习是人工智能的一个子集。
2
机器学习的分类
机器学习最常见的表现形式是通过某种特定的算法,用大量的数据进行训练、建模,并利用训练好的模型和新的输入进行预测或分类。
根据机器学习算法的学习方式,可以将其分为监督学习(Supervised Learning)、非监督学习(Unsupervised Learning)、半监督学习(Semi-Supervised Learning)和强化学习(Reinforcement Learning)。
监督学习是使用已知正确答案的示例来训练网络的,也就是需要明确的标签。监督学习主要解决回归问题和分类问题。回归问题针对连续型变量。对训练数据拟合适当的模型 y=f(x),这里 y 是数据的标签,而对于一个新的自变量 x,通过 y=f(x) 得到标签 y。分类问题与回归最大的区别在于,分类是针对离散型变量,输出的结果是有限的。分类需要将数据分为不同的类别,通过训练的模型对数据进行分类。
非监督学习不需要明确的标签,适用于无标签数据集。它通过学习数据中的内在特征(特殊结构),将其组织成群(聚类)。
半监督学习结合了监督学习和非监督学习的特点,训练时结合了大量无标签数据和少量标签数据,在数据服从同一分布的情况下,对无标签数据进行非监督学习获得标签,并与标签数据共同用于解决问题。与前两者相比,半监督学习在训练时可以更为准确,而且训练成本更低。
强化学习与前面的定义都不相同,它也使用无标签数据,通过定义一个智能体,并让智能体与环境进行交互,通过一些方法(奖罚函数)得到环境的反馈,从而对学习策略进行训练和调整,以实现最大的环境奖励。
我们通过思维导图将机器学习的方法进行归纳。
3
机器学习常见算法
BP神经网络
BP神经网络是一种多层的前馈神经网络,通常由输入层、隐含层和输出层组成,主要特点是信号的正向传播和误差的反向传播。基本思想是梯度下降法,利用梯度搜索技术,使得网络的实际输出值和期望输出值的误差均方差为最小。BP神经网络基本结构见图。
决策树
决策树是一种基本的分类和回归方法。
决策树由结点和有向边组成。一般的,一颗决策树包含一个根结点、若干个内部结点和若干个叶结点。其中内部节点表示一个特征或属性,叶结点表示一个类。叶结点对应于决策结果,其他每个结点对应于一个属性测试。
根结点包含样本全集,从根结点到每一个叶结点的路径对应了一个判定测试序列,路径中每个结点包含的样本集合根据属性测试的结果被划分到子节点中。
在上图中,圆盒方框分别代表内部结点和叶结点。
决策树的学习目的是为了产生一棵泛化能力强的树,即处理未见示例的能力强。
随机森林
在机器学习中,存在的一个重大的问题是过拟合问题,但在大多数情况下对于随机森林模型而言不会那么容易出现,因为随机森林可以将多棵树组合成一个集合模型,这能降低决策树模型的高方差。随着随机森林规模的扩大,过拟合问题会逐渐削弱。
随机森林模型在bagging集合策略的基础上进行了修改,在原样本集中通过多次随机可重复的抽样得到多个数据集,对每个数据集构造一棵决策树,随机森林由很多无关联的决策树组成,构造过程是通过将数据集中的样本点分到左右两个子集中实现的,此迭代过程执行到最大树深度或不能通过继续分割获得最大信息增益为止,随机森林回归模型通过取平均值的方法得到预测结果,算法流程如下图所示。
支持向量机
支持向量机(SVM)是监督学习算法,直观思想是:寻找一个能够最大程度分隔两类样本的超平面。在二维中,你可以将超平面视为一条线。
从直观来看,最佳超平面可以让两类样本中的点到这条直线的最短距离最大,由于在实际中决定超平面的往往是靠近这个边界的几个点,我们称之为支持向量。SVM学习算法找到导致超平面最好地分离类的系数。
下图中介绍的是一种最简单的线性svm,它将一个线性函数作为决策边界,即可实现将两种类别的数据进行分类。
当两种数据的分布如下图所示时,通过简单的线性边界就无法实现划分,我们称之为线性不可分。
面对线性不可分数据,通过需要借助一种工具——核函数,通过它将原空间的数据映射到新的空间(通常是更高维度的空间),在新的特征空间里寻找一个能够最大程度分隔两类样本的超平面。
4
基于Sklearn库实现SVM模型
经过前面的相关知识梳理,相信大家对机器学习有了一些了解,下面将介绍如何通过Sklearn库来实现支持向量机模型。
我们需要利用Tushare库获取数据集。Tushare是免费、开源的python量化库,能够为金融分析人员提供多样的便于分析的数据。
这里我们以神州高铁从2019年1月1日至2020年12月1日作为原始数据集,首先我们对数据集进行处理。
import tushare as ts
ts.set_token('token')
pro = ts.pro_api()
data = pro.daily(ts_code='000008.SZ',start_date='20190101',end_date='20201201',
fields='ts\_code,trade\_date,open,close')
data = data.reindex(index=data.index[::-1])
data = data.reset_index(drop=True)
我们的目标是通过过去10天的收盘价信息预测判断第二天的涨跌。假设收盘价 > 开盘价,第二天涨,标记为1,否则标记为0.
data['rof']=data['close']-data['open']
narray=data[['rof', 'close']].values
x=[]
y=[]
day=10
for i in range(len(narray) - day - 1):
x.append(narray[i:i+day, 1])
if narray[i+day, 0] > 0:
y.append(1)
else:
y.append(0)
利用Sklearn库的train_test_split函数按照7:3的比例划分训练集和测试集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)
在获得训练数据和测试数据后,可以利用Sklearn库中的SVM模块建立模型了。
from sklearn.svm import SVC
svm_model=SVC(kernel='linear')
svm_model.fit(x_train,y_train)
predict=svm_model.predict(x_train)
利用metric模块计算预测结果的准确性
from sklearn.metrics import accuracy_score
print(accuracy_score(y_train,predict))
predict1=svm_model.predict(x_test)
print(accuracy_score(y_test,predict1))
输出结果:
0.5772870662460567
0.6131386861313869
可以看到训练集数据预测的准确率约为58%,测试集的预测结果准确率约为61%.
完整代码为:
import tushare as ts
def cleandata(ts_code,start_date,end_date,day=10):
ts.set_token('token')
pro = ts.pro_api()
data = pro.daily(ts_code=ts_code,start_date=start_date,end_date=end_date,
fields='ts\_code,trade\_date,open,close')
data = data.reindex(index=data.index[::-1])
data = data.reset_index(drop=True)
data['rof'] = data['close']-data['open']
narray=data[['rof', 'close']].values
x=[]
y=[]
day=10
for i in range(len(narray) - day - 1):
x.append(narray[i:i+day, 1])
if narray[i+day, 0] > 0:
y.append(1)
else:
y.append(0)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)
return x_train, y_train, x_test, y_test
if __name__=='\_\_main\_\_':
x_train, y_train, x_test, y_test=cleandata('000008.SZ','20190101','20201201')
from sklearn.svm import SVC
svm_model=SVC(kernel='linear')
svm_model.fit(x_train,y_train)
predict=svm.predict(x_train)
from sklearn.metrics import accuracy_score
print(accuracy_score(y_train,predict))
predict1=svm_model.predict(x_test)
print(accuracy_score(y_test,predict1))
上面我们利用10日收盘价预测次日的涨跌情况,下面我们将输入序列改为CCI等技术指标,利用前一日的技术指标及收盘价预测次日的涨跌情况。完整代码如下:
import tushare as ts
import talib
def cleandata(ts_code,start_date,end_date,period=21):
ts.set_token('token')
pro = ts.pro_api()
data = pro.daily(ts_code=ts_code,start_date=start_date,end_date=end_date,
fields='ts\_code,trade\_date,open,close,high,low')
data = data.reindex(index=data.index[::-1])
data = data.reset_index(drop=True)
data['rof']=data['close']-data['open']
data['CCI']=talib.CCI(data['high'],data['low'],data['close'],timeperiod=period)
data['RSI']=talib.RSI(data['close'],timeperiod=period)
data['ATR']=talib.ATR(data['high'],data['low'],data['close'],timeperiod=period)
narray=data[['close',CCI','RSI','ATR','rof']].values
print(narray)
x=[]
y=[]
for i in range(len(narray)-1):
x.append(narray[i,0:4])
if narray[i+1,4]>0:
y.append(1)
else:
y.append(0)
from sklearn.model\_selection import train\_test\_split
x\_train, x\_test, y\_train, y\_test = train\_test\_split(x, y, test\_size=0.3)
return x\_train, y\_train, x\_test, y\_test
from sklearn.svm import SVC
from sklearn.metrics import accuracy\_score
x\_train, y\_train, x\_test, y\_test = cleandata('000008.SZ', '20190101', '20201201')
svm\_model=SVC(kernel='linear')
svm\_model.fit(x\_train,y\_train)
predict1=svm\_model.predict(x\_test)
print(accuracy\_score(y\_test,predict1))
得到的准确率如下:
0.631578947368421
可以看到,利用技术指标的预测结果的准确率略高于利用收盘价序列的预测结果。虽然股票价格是难以预测的,但是增加输入特征有助于提高准确度。
END
添 加 助 手 微 信 回 复 研 究 方 向 或 专 业 即 可 加 入 我 们 的 微 信 交 流 群 或 Q Q 交 流 群
扫 码 关 注 我 们
携 手 2 0 2 1 年 , 为 梦 想 启 程 !