大家好~
今儿继续给大家讲解关于XGBoost结合时间序列的一个案例:使用 XGBoost 进行股票价格时间序列预测。
XGBoost (eXtreme Gradient Boosting) 是一种基于梯度提升(Gradient Boosting)算法的高效、灵活且可扩展的机器学习库,最初由Tianqi Chen开发,现已成为数据科学家和机器学习工程师的常用工具。XGBoost 是一种集合模型,意味着它通过将多个弱学习器(通常是决策树)集成在一起,以提高预测的准确性。
相较于其他传统的梯度提升算法,XGBoost 在以下几个方面表现出色:
速度:通过并行计算与树的增量构建,提高了运行效率。 正则化:加入了L1和L2正则化,防止模型过拟合。 缺失值处理:自动处理缺失值,填补过程高效且不损失精度。 剪枝机制:可以提前剪枝,避免树结构过于复杂。
XGBoost 目前广泛应用于分类、回归、排序等问题中。本文将通过使用 XGBoost 进行股票价格时间序列预测的实战案例,展示如何利用它处理时间序列回归问题,并对预测结果进行分析。
完整案例
使用 XGBoost 进行股票价格时间序列预测
使用股票价格数据来进行预测。这是一个典型的回归问题,因为我们的目标是预测未来的股价。
主要步骤:
数据收集:使用Yahoo Finance获取股票的历史数据。 特征工程:包括日期处理、价格变化率等。 数据可视化与分析:通过图表分析历史股价趋势。 模型训练与预测:使用XGBoost模型进行训练并预测未来股价。 结果评估:使用常见的回归评估指标(如RMSE)和可视化预测结果。
数据集获取,点击名片,回复「数据集」即可~
data = pd.read_csv('./dataset/aapl_us_d.csv')
print(data.columns)
data.reset_index(inplace=True)
data['Date'] = pd.to_datetime(data['Date'])
data.set_index('Date', inplace=True)
# 打印前5行数据
print(data.head())
数据预处理
对于时间序列数据,最重要的是如何处理日期列。我们可以从日期中提取出多个特征,如年份、月份、周、星期几等,这些都可能是预测未来价格的重要因素。此外,还可以计算前一天的价格变化率等。
# 添加日期特征
data['Year'] = data.index.year
data['Month'] = data.index.month
data['Day'] = data.index.day
data['Dayofweek'] = data.index.dayofweek
data['Dayofyear'] = data.index.dayofyear
data['Week'] = data.index.isocalendar().week
# 计算价格变化率
data['Pct_change'] = data['Close'].pct_change()
# 向前移动一天,作为未来预测目标
data['Target'] = data['Close'].shift(-1)
# 丢掉缺失值
data.dropna(inplace=True)
# 查看处理后的数据
print(data.head())
数据可视化
在训练模型之前,先对股票的历史价格进行分析和可视化。我们会画出四个不同的图表,来帮助理解数据的趋势和模式:
股票收盘价格的时间序列图:展示历史股票价格的变化。 收盘价变化率的时间序列图:展示每日股票价格变化的百分比。 股票价格的季节性变化(月份、星期几):帮助我们了解股票价格是否随时间有明显的季节性趋势。 目标变量与特征变量的相关性热图:查看特征与目标变量的相关性,帮助选择有用的特征。
# 图1:股票收盘价格的时间序列图
plt.figure(figsize=(10,6))
plt.plot(data.index, data['Close'], color='blue', label='Close Price')
plt.title('Stock Closing Price Over Time')
plt.xlabel('Date')
plt.ylabel('Closing Price (USD)')
plt.legend()
plt.grid(True)
plt.show()
# 图2:收盘价变化率的时间序列图
plt.figure(figsize=(10,6))
plt.plot(data.index, data['Pct_change'], color='red', label='Pct Change')
plt.title('Stock Daily Percentage Change Over Time')
plt.xlabel('Date')
plt.ylabel('Percentage Change')
plt.legend()
plt.grid(True)
plt.show()
# 图3:股票价格的月季节性变化
plt.figure(figsize=(10,6))
data.groupby('Month')['Close'].mean().plot(kind='bar', color='green', alpha=0.7)
plt.title('Average Stock Closing Price by Month')
plt.xlabel('Month')
plt.ylabel('Average Closing Price (USD)')
plt.grid(True)
plt.show()
# 图4:目标变量与特征的相关性热图
import seaborn as sns
plt.figure(figsize=(10,6))
correlation_matrix = data.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
plt.show()
通过这些图表,我们可以看到股票价格在过去几年中的变化趋势,日变化率的波动,股票价格在不同月份的平均水平,以及特征之间的相关性。
模型训练
在这里,我们将使用XGBoost来训练回归模型。为了让XGBoost模型能够处理时间序列问题,我们将使用窗口技术,将过去几天的价格作为特征,用于预测未来一天的价格。
# 定义用于预测的特征和目标
features = ['Year', 'Month', 'Day', 'Dayofweek', 'Dayofyear', 'Week', 'Pct_change']
target = 'Target'
# 分割数据集为训练集和测试集
X = data[features]
y = data[target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
# 创建XGBoost回归模型
model = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=1000, learning_rate=0.01)
model.fit(X_train, y_train)
# 进行预测
y_pred = model.predict(X_test)
# 打印测试集上的均方误差
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
结果评估与可视化
为了更好地理解模型的预测能力,我们可以将预测结果与真实的股票价格进行对比,绘制出它们的图形。此外,还可以绘制模型预测的残差图,查看预测值与真实值之间的误差。
# 图5:预测值与真实值的对比图
plt.figure(figsize=(10,6))
plt.plot(data.index[-len(y_test):], y_test, label='Real Price', color='green')
plt.plot(data.index[-len(y_test):], y_pred, label='Predicted Price', color='orange')
plt.title('Real vs Predicted Stock Prices')
plt.xlabel('Date')
plt.ylabel('Price (USD)')
plt.legend()
plt.grid(True)
plt.show()
# 图6:残差图
residuals = y_test - y_pred
plt.figure(figsize=(10,6))
plt.scatter(data.index[-len(y_test):], residuals, color='purple')
plt.title('Residuals (Errors) Between Real and Predicted Prices')
plt.xlabel('Date')
plt.ylabel('Residuals (USD)')
plt.grid(True)
plt.show()
整个代码,通过特征工程、数据分析、模型训练和评估,我们能够预测未来的股票价格。虽然XGBoost本身并非专为时间序列问题设计,但通过适当的特征选择和数据处理,它仍然能够很好地适应该类任务。
通过不同的图表分析,我们观察到了股票价格的时间趋势、价格波动及其与日期特征的关系。此外,XGBoost模型也表现出了较好的预测能力,尽管仍有一定误差,但总体效果还是较为理想。