编者按:本文节选自方巍著《Python 数据挖掘与机器学习实战》一书中的部分章节。
3.5 基于线性回归的股票预测
线性回归预测算法一般用以解决“使用已知样本对未知公式参数的估计”类问题。线性回归在整个财务中广泛应用于众多应用程序中。本节将介绍如何使用线性回归进行股票特征的提取与预测。
3.5.1 数据获取
本节使用的股票数据从大型数据网站www.quandl.com获取,股票数据特征包括:开盘价(Open)、最高价(High)、最低价(Low)、收盘价(Close)、交易额(Volume)及调整后的开盘价(Adj.Open)、最高价(Adj.High)、最低价(Adj.Low)、收盘价(Adj.Close)和交易额(Adj.Volume)。获取到的原始数据如图 3-5 所示。
图 3-5 数据集中的部分数据示例 1
图 3-5 数据集中的部分数据示例 2
3.5.2 数据预处理
由于带 Adj 前缀的数据是除权后的数据,更能反映股票数据特征,所以主要使用的数据特征为调整后的开盘价、最高价、最低价、收盘价和交易额(即 Adj.Open、Adj.High、Adj.Low、Adj.Close 和 Adj.Volume)。
两个数据特征如下:
HLPCT(股票最高价与最低价变化百分比):
PCTchange(股票收盘价与开盘价的变化百分比):
于是,自变量为:Adj.Close、HLPCT、PCTchange和Adj.Volume。因变量为:Adj.Close。
最后,对自变量数据进行规范化处理,使之服从正态分布。只需要执行以下语句就可以达到预处理的目的,代码如下:
X = preprocessing.scale(X)
复制代码
使用 Sklearn 做线性回归,首先导入相关函数:
from sklearn.linear_model import LinearRegression
复制代码
建立线性回归模型:
clf = LinearRegression(n_jobs=-1)
复制代码
进行线性模拟:
clf.fit(X_train, y_train)
复制代码
使用 predict()函数对需要预测的数据进行预测:
forecast_set = clf.predict(X_lately)
复制代码
模型的评估主要使用精度(accuracy)参数。调用线型模型中的精度评估函数 score()。
accuracy = clf.score(X_test, y_test)
复制代码
3.5.3 编码实现
完整的 Python 实现代码如下:
import quandl
from sklearn import preprocessing
#df = quandl.get('WIKI/GOOGL'),先注释这一行,预测Google股票再用
df = quandl.get('WIKI/AAPL')
import math
import numpy as np
# 定义预测列变量,它存放研究对象的标签名
forecast_col = 'Adj. Close'
# 定义预测天数,这里设置为所有数据量长度的1%
forecast_out = int(math.ceil(0.01*len(df)))
# 只用到df中的下面几个字段
df = df[['Adj. Open', 'Adj. High', 'Adj. Low', 'Adj. Close', 'Adj. Volume']]
# 构造两个新的列
# HL_PCT为股票最高价与最低价的变化百分比
df['HL_PCT']=(df['Adj. High'] - df['Adj. Close'])/ df['Adj. Close'] * 100.0
# PCT_change为股票收盘价与开盘价的变化百分比
df['PCT_change']=(df['Adj.Close']- df['Adj.Open'])/df['Adj. Open'] * 100.0
# 下面为真正用到的特征字段
df = df[['Adj. Close', 'HL_PCT', 'PCT_change', 'Adj. Volume']]
#因为scikit-learn并不会处理空数据,需要把为空的数据都设置为一个比较难出现的值#这里
取-99999,
df.fillna(-99999, inplace=True)
# 用label代表该字段,是预测结果
# 通过让Adj. Close列的数据往前移动1%行来表示
df['label'] = df[forecast_col].shift(-forecast_out)
# 最后生成真正在模型中使用的数据X?y,以及预测时用到的数据数据X_lately
X = np.array(df.drop(['label'], 1))
X = preprocessing.scale(X)
# 上面生成label列时留下的最后1%行的数据,这些行并没有label数据,因此可以拿它们
作为预测时用到的输入数据
X_lately = X[-forecast_out:]
X = X[:-forecast_out]
# 抛弃label列中为空的那些行
df.dropna(inplace=True)
y = np.array(df['label'])
# scikit-learn从0.2版本开始废弃cross_validation,改用model_selection
from sklearn import model_selection, svm
from sklearn.linear_model import LinearRegression
# 开始前,先把X和y数据分成两部分,一部分用来训练,一部分用来测试
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y,
test_size=0.2)
# 生成scikit-learn的线性回归对象
clf = LinearRegression(n_jobs=-1)
# 开始训练
clf.fit(X_train, y_train)
# 用测试数据评估准确性
accuracy = clf.score(X_test, y_test)
# 进行预测
forecast_set = clf.predict(X_lately)
print(forecast_set, accuracy)
import matplotlib.pyplot as plt
from matplotlib import style
import datetime
# 修改matplotlib样式
style.use('ggplot')
one_day = 86400
# 在df中新建Forecast列,用于存放预测结果的数据
df['Forecast'] = np.nan
# 取df最后一行的时间索引
last_date = df.iloc[-1].name
last_unix = last_date.timestamp()
next_unix = last_unix + one_day
# 遍历预测结果,用它向df中追加行
# 这些行除了Forecast字段,其他都设为np.nan
for i in forecast_set:
next_date = datetime.datetime.fromtimestamp(next_unix)
next_unix += one_day
# [np.nan for_in range(len(df.columns)-1)]生成不包含Forecast字段的列表
# 而[i]是只包含Forecast值的列表
# 上述两个列表拼接在一起就组成了新行,按日期追加到df的下面
df.loc[next_date] = [np.nan for _ in range(len(df.columns)- 1)] + [i]
# 开始绘图
df['Adj. Close'].plot()
df['Forecast'].plot()
plt.legend(loc=4)
plt.xlabel('Date')
plt.ylabel('Price')
plt.show()
复制代码
3.5.4 结果分析
以股票代号为 GOOGL 和 AAPL 的股票为例,线性模拟的结果如图 3-6 和图 3-7 所示。
上面对两个股票进行了线性模拟,并对一部分数据进行了预测。实验结果显示,对 GOOGL 股票的预测精度达到了 0.976871737402434;对 AAPL 股票的预测精度达到了 0.9719097855057968,表明该程序能对股票数据进行较好的预测。
图 3-6 GOOGL 股票数据预测结果
说明:图中的曲线部分为历史数据,最上部的竖直线部分为预测数据。
图 3-7 AAPL 股票数据预测结果
说明:除图中最上部的竖直线部分为预测数据,其余曲线均为历史数据。
图书简介:https://item.jd.com/12623592.html?dist=jd
相关阅读
Python数据挖掘与机器学习实战(一):Python语言优势及开发工具
Python数据挖掘与机器学习实战(二):Python语言简介
Python数据挖掘与机器学习实战(三):网络爬虫原理与设计实现
Python数据挖掘与机器学习实战(四):用 Python 实现多元线性回归
Python数据挖掘与机器学习实战(五):基于线性回归的股票预测
评论 1 条评论