「数据游戏」:使用岭回归预测招商银行的股价

作者:Max,「数据游戏」优胜队伍成员

前阵子报名参加了「数据游戏」比赛,题目是预测5月15号(星期三)招商银行的股价,截止时间是在5月12号(星期天)。在本次预测中,我用到的是岭回归。

岭回归

岭回归是回归的一种,它解决回归中重大疑难问题:排除多重共线性,进行变量的选择,在存在共线性问题和病态数据偏多的研究中有较大的实用价值。按照度娘百科的解释:岭回归是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价获得回归系数更为符合实际、更可靠的回归方法,对病态数据的拟合要强于最小二乘法。

多重共线性指线性回归模型中的解释变量之间由于存在精确相关关系或高度相关关系而使模型估计失真或难以估计准确。

由于岭回归涉及的数学知识比较复杂,且文章篇幅有限,这里不过多展开。

数据获取

本次数据是通过 Tushare 的 get_hist_data() 获取的。Tushare 是一个免费、开源的 python 财经数据接口包。python 安装 tushare 直接通过 pip install tushare 即可安装。

import tushare as ts
data = ts.get_hist_data('600848')

运行之后可以查看它的前后几行数据。按照 tushare 官方的说明,get_hist_data() 只能获取近3年的日线数据,而他的返回值的说明是这样的:

  • date:日期;
  • open:开盘价;
  • high:最高价;
  • close:收盘价;
  • low:最低价;
  • volume:成交量;
  • price_change:价格变动;
  • p_change:涨跌幅;
  • ma5:5日均价;
  • ma10:10日均价;
  • ma20:20日均价;
  • v_ma5:5日均量;
  • v_ma10:10日均量;
  • v_ma20:20日均量

均价的意思大概就是股票 n 天的成交价格或指数的平均值。均量则跟成交量有关。至于其他的返回值,应该是一下子就能明白的吧。在获得数据之后,我们查看一下描述性统计,通过data.describe()查看是否存在什么异常值或者缺失值。

image

这样看来似乎除了由于周末以及节假日不开盘导致的当天的数据缺失以外,并没有其他的缺失和异常。但是这里我们不考虑节假日的缺失值。

数据预处理

由于获取的数据是按日期降序排序,但本次预测跟时间序列有关,因此我们需要把顺序转一下,让它按照日期升序排序。

data1 = data[::-1]

处理完顺序之后,我们要做一下特征值的选择。由于 volume 以及均量的值很大,如果不进行处理的话,很可能对整体的预测造成不良影响。由于时间有限,而且考虑到运算的复杂度,这里我没有对这些特征进行处理,而是直接将它们去掉了。至于均价,我是按照自己的理解,和10日均价、20日均价相比,5日均价的范围没那么大,对近期的预测会比另外两个要好,因此保留5日均价。接着,我用 sklearn.model_selection 的 cross_val_score,分别查看除 'open', 'close', 'high', 'low', 'ma5' 以外的其他剩余属性对预测值的影响。发现 、 'p_change'、'price_change'这两个属性对预测结果的影响不大,为了节省内存,增加运算速度,提高预测的准确性,也直接把它们去掉了。完了之后,查看前后三行数据。

data1 = data1[['open','high','low','ma5','close']]
data1.head(3), data1.tail(3)
image

建模预测

由于提交截止日期是周日,预测的是周三,因此需要先对周一周二的信息进行预测。在这里我突然想到一个问题,是用前一天的所有数据来训练模型以预测当天的 close 比较准确,还是用当天除了 close 以外的其他数据来训练模型以训练当天的 close 比较准呢?为了验证这个问题,我分别对这两种方法做了实验。

为了减少代码量,定义了一个函数用以评估模型的错误率。

def get_score(X_train, y_train):
    ridge_score = np.sqrt(-cross_val_score(ridge, X_train, y_train, cv=10, scoring='neg_mean_squared_error'))
    return np.mean(ridge_score)

用前一天的所有数据来当训练集

y_train = data1['close'].values[1:]
X_train = data1.values[:-1]
score = get_score(X_train, y_train)

输出结果大约为0.469,这个错误率就比较大了,不太合理,更何况还要预测其他特征值作为测试数据。

用当天除了 close 以外的其他数据来当训练集

data2 = data1[:]
y_train = data2.pop('close').values
X_train = data2.values
score = get_score(X_train, y_train)

输出结果大约为0.183,跟第一个相比简直好多了。所以,就决定是你了!

接下来建模并把模型保存下来:

y_train = data1['close']
X_train = data1[['open', 'high', 'low', 'ma5']]
close_model = ridge.fit(X_train, y_train)
joblib.dump(ridge, 'close_model.m')

在预测之前呢,我们先拿训练集的后8组数据做一下测试,做个图看看:

scores = []
for x in X_train[-8:]:
    score = close_model.predict(np.array(x).reshape(1, -1))
    scores.append(score)
x = np.arange(8)
fig, axes = plt.subplots(1, 1, figsize=(13, 6))
axes.plot(scores)
axes.plot(y_train[-8:])
plt.xticks(x, data1.index[-8:].values, size=13, rotation=0)
image

看到这样子我还是相对比较放心的,不过,这个模型的训练值除了 close 以外的属性都是已知的,要预测三天后的还得预测前两天的测试值。

def get_model(s):
    y_train = data1[s].values[1:]
    X_train = data1.values[:-1]
    model = ridge.fit(X_train, y_train)
    return model
def get_results(X_test):
    attrs = ['open', 'high', 'low', 'ma5']
    results = []
    for attr in attrs:
        result = get_model(attr).predict(X_test)
        results.append(result)
    return results

接下来预测三天的股价:

X_test = data1[-1:].values
for i in range(3):
    results = get_results(X_test)
    close = close_model.predict(np.array(results).reshape(1, -1))
    print(close)
    results.append(close)
    X_test = np.array(results).reshape(1, -1)
print("5月15日招商银行关盘时的股价为:" + str(round(close[0], 2)))

输出结果为:

[33.46370029]
[33.4532047]
[33.43836721]

5月15日招商银行关盘时的股价为:33.44

总结

虽然预测结果是这样子,但感觉这样预测似乎很菜啊。毕竟预测的每个值都会有偏差,多个偏差累加起来就很多了,这让我有点害怕。不知道存不存在不预测其他值直接预测close的方法,或者说直接预测5月15号的而不用先预测13、14号的方法。虽然我知道有种算法是时间序列算法,但不是很懂。希望哪位大神看了能给我一些建议,指点迷津。

对于一个自学数据分析的在校学生,苦于没有项目经验,正好赶上这次的「数据游戏」,能利用此次机会操作一波真的很不错。既能学到东西,获胜的话还能得到奖品。

image

Ad Time

学习更多数据科学知识请关注微信公众号:read_csv

参与数据科学活动请加 QQ 群:759677734

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容