技术│股票数据选择和特征提取技巧

今天我们以 “股票选择”为例子来给大家枚举下自己觉得好用的数据库资源,和用于数据选择及预处理的方法及相应代码。

人工智能、深度学习等先进计算机技术用来预测股市走向、选择好的股票资产最大的难点并不在于模型的选择、建立和应用,核心是在所获取的数据中选择高质量的数据,和要抓取的特征对数据进行预处理。 股票数据选择和特征提取是开端,若第一步未进行好,则后续全盘皆乱。然而更困难的是,网上有多到不可穷举的教如何建模及执行模型的库、APIs及指南等,对于最关键的如何选择数据和数据预处理的信息则少之又少。现有的数据集都是几年下来积累的成果,金融财务数据集则都经历了几十年的收集和不断完善。

在平常工作中, 我们无法和谷歌、微软等巨头相抗衡,没有足够的资金和资源去维护和获得一个相对全面和高质量的数据库。

那么我们如何利用市面上现有的资源和行之有效的方法论去获得自己想要的高质量数据呢?今天我们以“股票选择”为例子来给大家枚举下自己觉得好用的数据库资源,和用于数据选择及预处理的方法及相应代码。用人工智能和机器学习等进行股票选择的一般工作流程是:

我们只讨论工作流程中的第一步到第三步,数据选择和数据预处理的重要性及方法。输入的数据数量及质量强烈影响模型的性能好坏,为了最大限度地选择相关数据,首先要定义清楚解决的问题范围,才能决定哪些是要采集的相关数据,哪些是需要过滤的无关信息;定义清楚问题范围后,我们便进行数据的采集和选择,这里的数据是未经过任何处理的初始数据,因此数量的多少和质量的好坏都是针对初始数据而言的;接下来便是将初始数据进行预处理,对数据进行清洗,从中最大限度的仅获取有用数据,并将它们转换为计算机可读取编译,及机器学习模型可使用的数据。

01 分析问题

我们讨论的内容定义在“股票选择”这个框架下,基于对市场环境信息的搜集,选取及开发合适的模型,分析当前市场形势,预测未来市场走向,从而选取有获利潜力的股票。可以看出,足够数量和高质量的市场信息数据作为输入的第一步,具有非常重要的影响。 理论上如果我们使用基于“深度学习”的模型,只要输入的数据量足够多,利用“深度学习”自我学习和不断迭代优化的本质,相关性低和质量差的数据逐渐被过滤,初始数据的质量好坏就不那么重要,因此“数据选择”这个步骤就不再无足轻重。然而在实际生活中,获得足够多的数据这件事情非常困难,几乎不可能,因此就算使用了“深度学习”技术,我们还是要进行数据选择和数据预处理,保证数据的质量,避免引起偏差。

02 寻找并搜集数据

这一步是问题理清之后实施的开端,非常关键。各大巨头公司利用自身的规模、资源、人力、设施、财富等优势可以轻而易举地从各大顶尖优质数据库(有些数据库收费昂贵,用于负担前期数据库建立、后期数据库维护、运营及更新的成本)获取量级难以评估的大量数据。作为普通人,在没有那么多资金、资源和时间成本的情况下,如何获得建模所需的足够数据?用点功夫,仔细研究下,可以找到不少从学术界提供的免费数据源,APIs,或者开源库供我们获取数据。我们整理了一些有用的数据资源链接,供大家参考,希望能帮到各位:

啥也不说了,这个数据资源链接堪称完美!它汇集了全世界各地的经济/金融数据库,规模庞大。你可以选择任何所需的数据集,添加到购物车内,然后轻而易举地进行下载。

每次我想搜集点股票价格,资产负债表,市场分析预测报告等股票相关信息时,第一时间想到的就是这个网址。

用于搜集审核数据。

这个网址提供一系列用于预测市场信息和股票的数据,十分实用。

该网站专门提供各类指标型数据。

这个网址提供劳动力/人力资源相关的数据。

研究美股的朋友们,当然不能遗漏美国财政部的官方网站!

在有了这些数据资源做支撑的前提下,用Python语言进行建模编译的小伙伴们,即可从相关网址上的CSV文件夹内读取所需的数据。在进行自己的一些探索性分析前,注意先将不同的数据源和数据格式统一在一个数据框架下。

03 数据预处理

该部分包含三个步骤:1)数据清洗;2)特征工程,即特征构造、特征选择、特征生成,是“机器学习”重要的一步,目的是最大限度地从原始数据中提取特征,类似于人类的指纹,以供算法和模型使用;3)数据标准化。

下面我们将分别对以上三个步骤的数据预处理进行讨论。

1)数据清洗

数据清洗这一步对于获取高质量的数据是非常必要的。我们拿到的初始数据有的有洞,有的就是垃圾数据,有的数据跟要解答的问题毫不相关,有的则通过标准化或规则化可以变得更加实用。为了丰富训练模型所需的数据集,我们可以添加点人造的数据。一些大的图像处理公司,如Nvidia在利用仿真周遭环境来帮助训练CNN模型时,就添加了大量的人造数据来补充数据集。

这里推荐Pandas,只需简单调用内建的相关函数就能实现数据清洗的目的:

  • dropna () 会从数据框架中剔除所有NaN无效输入项,可用来处理数据准备过程中有遗漏数据或无效数据的情况,代码如下:

https://gist.githubusercontent.com/Poseyy/7628da7ab93382bfbb9e47fb4bc12565/raw/bc9a1773c48aa26b9f7134d0f4bd553df9aaa107/dropna.py

ticker = 'AMD'

timeframe = '1y'

df = p.chartDF(ticker, timeframe)

df = df[['close']]

df.reset_index(level=0, inplace=True)

df.columns=['ds','y']

df.dropna(inplace=True)

  • fillna () 会将我们自定义的数据集取代发现的NaN无效数据,一种方式是采用最临近NaN无效数据的两个输入数据进行替换,另一种方式是用无效数据所在的数据列均值来替换,我们给出数据列均值替换的函数示例,代码如下:

https://gist.githubusercontent.com/Poseyy/833b2bccbd306c26c91080d0ee081983/raw/7feec12a6f855766aca0b8f67b88b50b116fa078/fillna.py

ticker = 'AMD'

timeframe = '1y'

df = p.chartDF(ticker, timeframe)

df = df[['close']]

df.reset_index(level=0, inplace=True)

df.columns=['ds','y']

df.fillna(df.mean(), inplace=True)

2)特征工程

数据是信息的载体,但是原始数据中包含了大量的噪声,信息的表达也不够简练。因此,特征工程的目的是通过一系列工程活动,决定数据的哪些特征组合对于训练模型是有用的,将这些特征提取出来,即将信息以更高效的编码方式(特征)表示。 使用特征表示的信息,最大限度地减少了原始数据中的不确定影响(如白噪声、异常数据、数据缺失等),在信息损失量较少的情况下保留了原始数据中包含的规律。特征越好,灵活性越强,构建的模型越简单,模型的性能越出色。

有多种可高度区分的特征,然而最有效的方式可能还是“可视化”的视觉方法。Seaborn库是个很好用的工具,可根据我们的特征自动建立可视化模型并给出输出结果。 我们给出一个示例:

sns.pairplot (data=df,

hue=“asset_price”)

图片左边上下两幅图是基于第一个特征得出的蓝色和橙色两个分布图,右边上下两幅图是基于第二个特征得出的蓝色和橙色两个分布图。相比之下基于第一个特征得出的蓝色和橙色两个分布图相对好区分一些,因此对于模型训练而言第一个特征更为实用。

除了用大量的数据进行实验验证得出哪个特征对于训练模型更为有效外,我们还可以用一种更为量化的方法对特征进行打分。Scikit-Learn的SelectBest不失为一个好用的算法工具,可以调用其中的“Chi-Square”测试方差函数:

下面给出一个用SelectBest算法和Chi-Square测试方差函数进行量化评估特征的代码示例:

https://gist.githubusercontent.com/Poseyy/03215f78987de3737dc8f8a902af761b/raw/9da708f35218ad24fe44fff5d33ad0212a38d0a7/chi-sq.py

bestfeatures=SelectKBest(score_func=chi2,k='all)

fit = bestfeatures.fit(X1,Y1)

dfscores = pd.DataFrame(fit.scores_)

dfcolumns = pd.DataFrame(df.columns)

featureScores=pd.concat([dfcolumns,dfscores],axis=1)

featureScores.columns=['Specs','Score'] #naming the dataframe columns

print(featureScores.nlargest(5,'Score')) #print 5 best features

特征评估所得的分数越高,表明该特征对于模型训练的影响因子越大,应当纳入特征选择范围。下图为一个给各特征打分的结果示意:

3)数据标准化

标准化数据是为了将所有的数据统一成一种更易读取/消化的形式。个人强烈推荐Scikit-Learn的scale()函数,极其好用。下面我们给一个调用scale()函数将输出变量一维化的代码示例:

https://gist.githubusercontent.com/Poseyy/d57ac309f4d163b592d9260b074a0851/raw/5213027c9b32487162656d41361b1a0e04f9a6af/scaling.py

sel_feature=['P/E','Debt','Revenue']#Select features

X1 = df1[sel_feature].values

Y1 = df1['math score'].values

Y1 = Y1.flatten()

X_scale1 = scale(X1)

04 写在最后

看完这篇技术干货,各位小伙伴们有什么想法?希望本篇介绍的工作流程、方法论、函数及代码实例能够对各位有所启发和帮助。如果各位在运用机器学习进行选股时,一直花费大量时间和精力在模型选取和优化上,试图修正模型来拟合数据以期提高选股结果,要当心出现过拟合的现象。我建议小伙伴们这时不妨换个思路,从解决方案的开端 – “数据”来进行优化。你所忽略的“数据”才是问题和解决方案的核心!