I、项目任务要求
- 任务描述:由于直接的经济利益,股票价格预测一直吸引着有兴趣投资股票市场和股票交易所的人。它也是金融界的一个重要研究课题。然而股票市场收益预测是一个非常复杂的问题,取决于公司财务状况和国家政策等诸多因素。
- 主要任务要求如下:
可选用爬虫工具或其它方法制作数据集使用Quandl模块,引用其平台数据- 建立股票价格趋势预测模型(线性回归、支持向量机回归、决策树)
- 以预测精度来评估预测模型的拟合能力
- 结果分析
- 参考资料网站:基于线性回归的股票预测(scikit-learn)
II、数据集描述(10)
数据集包含两支股票(GOOGL、AAPL)的历史股价数据,其中特征属性包括:
- ‘Adj. Open’: 股票的开盘价格,经过调整后的价格。
- ‘Adj. High’: 股票的最高价格,经过调整后的价格。
- ‘Adj. Low’: 股票的最低价格,经过调整后的价格。
- ‘Adj. Close’: 股票的收盘价格,经过调整后的价格。
- ‘Adj. Volume’: 股票的交易量,经过调整后的交易量。
- ‘Ex-Dividend’: 不带股息(忽略)
- 补充数据(构造新数列):
- ‘HL_PCT’: 最高价和收盘价之间的百分比变化
- ‘PCT_change’: 开盘价和收盘价之间的百分比变化
- ‘label’: 待预测的股票价格,是 ‘Adj. Close’ 列向前移动了一定百分比行数的结果。
数据集中的记录数取决于获取的历史数据的时间段,每一行代表一天的数据。
III、主要算法原理及模型评价方法陈述(15分)
项目中涉及的主要算法是线性回归(Linear Regression)和支持向量机回归(Support Vector Machine Regression,SVM Regression)。
以下是算法原理的简要描述:
线性回归:
- 线性回归是一种监督学习算法,用于建立输入特征和输出目标之间的线性关系模型。在这个项目中,线性回归用于训练模型来预测股票的价格('label’列),使用历史股价和交易量等特征作为输入。
- 线性回归模型寻找一条最佳拟合直线,使得预测值与实际值之间的平方误差最小化。
支持向量机回归:
- 支持向量机回归是一种监督学习算法,用于建立输入特征和输出目标之间的非线性关系模型。
- 本项目中,SVM回归也可以用于预测股票价格。它通过将输入数据映射到高维空间,找到一个最佳的超平面,以最小化预测误差。
决策树
决策树模型是一种用于分类和回归任务的机器学习模型,它模仿了人类在面对决策问题时的思维方式,通过一系列的决策规则来进行预测和分类。决策树模型是一种可解释性强的模型,通常用于以下两种情况:
- 分类问题:决策树可以用于将数据样本划分到不同的类别中。在分类问题中,每个叶子节点代表一个类别,而每个非叶子节点代表一个特征或属性上的决策规则。数据样本从根节点开始,依次按照规则向下移动,最终到达一个叶子节点,从而确定其所属的类别。
- 回归问题:除了用于分类,决策树也可以用于回归任务,即预测连续数值的输出。在这种情况下,每个叶子节点仍然代表一个数值,但是非叶子节点的决策规则会将数据样本分配到不同的子节点,最终产生一个回归值。
决策树的构建过程通常分为以下几个步骤:
- 特征选择:选择最佳的特征来作为每个非叶子节点的决策规则。通常使用不同的评估指标(如信息增益、基尼不纯度等)来确定哪个特征最适合用于分割数据。
- 数据分割:根据选定的特征,将数据集划分为不同的子集。每个子集对应于不同的特征取值或范围。
- 递归构建:对每个子集递归地应用上述步骤,构建子树,直到达到停止条件。停止条件可以是达到最大深度、样本数不足或其他预定义条件。
- 叶子节点标记:为每个叶子节点分配一个类别(分类问题)或一个数值(回归问题)。
- 剪枝(可选):决策树可能会过度拟合训练数据,为了提高泛化能力,可以对树进行剪枝,即删除一些分支。
决策树模型的优点包括易于理解和解释、对缺失值不敏感、能够处理数值和分类特征、适用于大规模数据等。然而,它也容易过拟合训练数据,因此通常需要采用剪枝等技术来改进模型的泛化性能。决策树模型的一种常见变体是随机森林,它通过组合多个决策树来提高性能和稳定性。
模型评价方法:
在项目中,使用了以下模型评价方法来评估模型性能:
- 训练集和测试集拆分:数据集被分成训练集和测试集,以便评估模型的泛化性能。
- R-squared(R²):用于衡量模型对实际数据的拟合程度,值范围在0到1之间,越接近1表示拟合越好。
- 可视化分析:通过绘制股票价格和预测结果的图表来可视化分析模型的表现。
IV、代码实现(45分)
import quandl
from sklearn import preprocessing
import math
import numpy as np
from sklearn import model_selection, svm
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
from matplotlib import style
import datetime
from sklearn.tree import DecisionTreeRegressor
# Todo: 获取股票数据GOOGL、AAPL
# df = quandl.get('WIKI/GOOGL')
df = quandl.get('WIKI/AAPL')
# print(df)
# Todo: 定义预测列变量
# todo: 定义预测天数、特征、处理异常值、生成X,y
# 定义预测列变量,存放研究对象的标签名
forecast_col = 'Adj. Close'
# 定义预测天数,这里设置为所有数据量长度的1%
forecast_out = int(math.ceil(0.01 * len(df)))
print("----------定义の预测天数----------")
print(forecast_out)
# 只用到df中的下面几个字段
df = df[['Adj. Open', 'Adj. High', 'Adj. Low', 'Adj. Close', 'Adj. Volume']]
# 构造两个新列
df['HL_PCT'] = (df['Adj. High'] - df['Adj. Close']) / df['Adj. Close'] * 100.0
df['PCT_change'] = (df['Adj. Close'] - df['Adj. Open']) / df['Adj. Open'] * 100.0
# 真正用到的特征
df = df[['Adj. Close', 'HL_PCT', 'PCT_change', 'Adj. Volume']]
# 处理空值,这里设置为-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'], axis=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'])
print("----------预测股票价格的特征变量X----------")
print(X)
print("----------预测的目标变量y----------")
print(y)
print("----------用于预测的输入数据X_lately----------")
print(X_lately)
# Todo: 线性回归分析
# 先把X,y数据分成两部份,训练和测试
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.2)
# 生成线性回归对象
clf = LinearRegression(n_jobs=-1)
# 开始训练
clf.fit(X_train, y_train)
# 进行预测
foreca_set = clf.predict(X_lately)
# 用测试数据评估准确性
accuracy = clf.score(X_test, y_test)
print("----------线性回归-预测---------")
print(foreca_set)
print("---------线性回归-准确性---------")
print(accuracy)
# Todo: 支持向量机回归分析
# 支持向量机回归分析
clf_svm = svm.SVR(kernel='linear')
# 开始训练支持向量机回归模型
clf_svm.fit(X_train, y_train)
# 用测试数据评估支持向量机回归模型准确性
accuracy_svm = clf_svm.score(X_test, y_test)
# 进行支持向量机回归模型的预测
forecast_set_svm = clf_svm.predict(X_lately)
print("----------支持向量机-预测---------")
print(forecast_set_svm)
print("---------支持向量机-准确性---------")
print(accuracy_svm)
# 决策树回归模型
clf_tree = DecisionTreeRegressor()
clf_tree.fit(X_train, y_train)
accuracy_tree = clf_tree.score(X_test, y_test)
forecast_set_tree = clf_tree.predict(X_lately)
print("----------决策树-预测---------")
print(forecast_set_tree)
print("---------决策树-准确性---------")
print(accuracy_tree)
# Todo: 可视化展示
# 修改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中追加行
for i in foreca_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()
x_train:代表训练数据集的输入特征,即训练图像数据。
x_test:代表测试数据集的输入特征,即测试图像数据。
y_train:代表训练数据集的目标标签,即训练图像对应的类别。
y_test:代表测试数据集的目标标签,即测试图像对应的类别。
V、运行结果截图(15分)
- 可视化展示(线性回归-苹果)
VI、结果分析(15分)
项目的主要目标是预测股票价格,并通过模型评价方法来评估预测的准确性。
最终的结果分析包括以下几个方面:
模型准确性:
- 通过使用模型评价方法(例如R-squared)来评估模型在测试集上的准确性。较高的R-squared值表示模型对实际数据的拟合较好。
可视化分析:
- 通过绘制股票价格和预测结果的图表,可以直观地观察模型的预测效果。如果预测曲线与实际股价曲线趋势相符,说明模型在一定程度上成功预测了股票价格。
时间序列分析:
- 通过时间序列分析,可以观察模型是否能够捕捉到股票价格的趋势和波动。这有助于确定模型在不同市场情况下的表现如何。
综合这些分析结果,可以评估模型的预测能力和泛化性能,以确定模型是否适合用于股票价格预测以及在实际交易中的应用潜力。