6.1 数据清理
数据分析界有一句很有名的谚语“Garbage in,garbage out”,意思是如果输入的数据质量很糟糕,那么即使算法再精妙也得不到有价值的结果。更有甚者,还可能会将人引向相反的结果,造成重大决策失误。这一说法在量化投资领域当然也成立—如果输入的数据存在各种错误和问题,那将会很难做出有效的投资模型。
所以第一步,也是非常关键的一步,就是数据的清理。为了清理数据,我们必须要知道可能存在的问题,才能针对相应的问题设计相应的方法。
6.1.1 可能的问题
原始数据可能存在如下三种问题。
·数据缺失:数据缺失的问题在高频数据里面特别常见。而且由于很多投资者是自己实时下载的数据,因此即使之后发现也很难弥补。
·噪声或者离群点:由于系统或者人为的失误,导致数据出现明显的错误,比如某支股票的价格本应在12元左右,结果突然出现了100元的价格数据。
·数据不一致:很多投资者,为了确保数据正确性,会使用多个数据源进行交叉验证,这时往往会出现数据不一致的问题。即使是同一个数据源,有时候也会出现数据不一致的问题。比如期货行情数据,Wind、文华、MC的数据都有可能出现不一致的问题,数据频率越高,不一致的可能性就越大。
6.1.2 缺失值
针对缺失值,实际操作中,需要两套程序:一套程序是检查缺失值,一套程序是填补缺失值。一般流程是,先检查缺失值,研究缺失值,选择填补方法,进行填补,然后再次检查。这样迭代循环,直到将数据缺失控制在可接受范围内。
缺失值,也有多种类型,一种是“正常缺失”,比如股票在某一天停牌,那么这一天的交易数据就是没有的。一种是“非正常缺失”,比如明明有交易,但就是没有交易数据。
举个例子,在下载5分钟数据的时候,发现20160104的数据都有缺失,但Wind上的数据又显示当天的交易情况为“交易”。实际情况是当天发生了“熔断”,因为是新的机制,所以Wind还没来得及准备一个字段用于表示当天的交易状态。这种情况就属于数据的“正常缺失”,只是交易状态与数据不一致而已。
图 6-1
Wind的交易状态字段如图6-1所示。
在检查缺失值时,这两种缺失需要分辨清楚,因为不同的缺失值,处理方法也不一样。
检查好缺失值之后,就需要进行处理了。先处理“非正常缺失”,一般流程具体如下。
1)检查提取数据是否出错。有时候,数据源本身是完整的,然而自己在提取数据的时候出现了问题。比如,笔者在使用市场上某家的金融高频数据的时候,下载5分钟数据计算高频波动率,发现存在很多缺失的数据。经该公司后台查询后发现,他们的数据库其实是有这个数据的,这说明是在下载数据的过程中出现了问题。
2)从其他数据源提取。有的数据源本身就缺失了数据,对于这种情况可以再寻找另外一个数据源进行补充。
·算法填充。有的时候,我们没有办法使用多数据源进行补充,而且有的数据本身就有空缺,无法补充。这个时候,可以退而求其次,使用算法填充。
常用算法有向前填充和向后填充两种。所谓向前填充是指使用之前最近的一个数据对空值进行填充。向后填充是指使用之后最近的一个数据对空值进行填充。
Pandas提供了一个函数用于数据填充。示例代码如下:
df = pd.DataFrame([[np.nan, 2, np.nan, 0], ... [3, 4, np.nan, 1], ... [np.nan, np.nan, np.nan, 5], ... [np.nan, 3, np.nan, 4]], ... columns=list('ABCD')) df A B C D 0 NaN 2.0 NaN 0 1 3.0 4.0 NaN 1 2 NaN NaN NaN 5 3 NaN 3.0 NaN 4
向前填充的示例代码如下:
df.fillna(method='ffill') A B C D 0 NaN 2.0 NaN 0 1 3.0 4.0 NaN 1 2 3.0 4.0 NaN 5 3 3.0 3.0 NaN 4
除了向前填充,该函数也支持向后填充,不过,要使用特定的值进行填充。
有的数据发生了缺失,无法使用简单的向前填充或向后填充来处理。比如,使用Wind下载a股复权数据,会发现交易状态trade_status在1999年之前都是空值,虽然实际上是有交易的,但如果直接按照trade_status=‘交易’这个条件来筛选,将会把1999年之前的所有数据都去掉。这个时候就需要根据逻辑设计一个算法来进行填充,比如将成交量volume>0的都填充为“交易”。
6.1.3 噪声或者离群点
噪声或离群点的问题一般有两种情况,一种是数据错误导致的,比如本来应该是10.0的数据,错误显示为10000;另一种则是其本身是真实数据,但就是离群点,比如金融危机中的收益率或者波动率,可能就非常极端,成为离群点。
一般的处理步骤具体如下。
1)通过一定的算法识别出离群点。一般是使用该数据标准差的多少倍来判断。比如正太分布中,正负标准差3倍以上的概率是99.7%,可以将其认定为可疑离群点。
2)人工判断离群点是属于错误数据导致的,还是正常的离群点。
3)对离群点进行处理。一般来说,错误的离群点需要更正或者删除。正常的离群点则需要另外建模进行分析。
6.1.4 数据不一致
为了确保数据的准确性,有时候需要使用多种数据源进行交叉验证。比如,在研究港股的时候,对比了Wind和Bloomberg的后复权数据之后,发现两者存在很大的差别,这就是数据不一致的问题,但我们并不能确定哪一个才是正确的,于是又加入了同花顺和CSMAR的数据进行对比,发现后者与Wind的数据是一致的。所以可以确认是Bloomberg的问题,因而采用Wind的数据。
当然,在实际工作中,数据清理的问题要远远多于这里介绍的几种,需要系统性地、仔细地去处理。