当前位置: 首页 > article >正文

数据挖掘实训:基于CEEMDAN与多种机器学习模型股票预测与时间序列建模

股票市场的预测是金融领域中的一个重要研究方向,尤其是如何通过历史数据预测未来股价。这篇博客将带你走进如何通过多种方法,如CEEMDAN(Complete Ensemble Empirical Mode Decomposition with Adaptive Noise)分解技术与机器学习模型(如SVM、XGBoost、LSTM等)结合,来实现股票价格预测。我们将使用苹果公司(AAPL)股票的历史数据进行详细分析,并逐步展示如何通过不同的技术和模型对股票市场进行预测。

1. 数据预处理与模态分解

股票市场数据通常呈现出非常复杂的非线性和非平稳性特征。为了更好地进行预测,我们首先需要对数据进行适当的处理,去除噪声并提取更有用的信息。

部分数据如下所示:

1.1 数据读取与清洗

我们从苹果公司(AAPL)股票的历史数据入手,加载CSV文件,并去除缺失值。然后,我们将数据中的“Date”列删除,保留价格信息。

df_apple = pd.read_csv("AAPL.csv")
df_apple = df_apple.dropna()
del df_apple["Date"]
df_apple.head()

1.2 数据统计分析

对数据进行初步的统计分析,计算最大值、最小值、平均值、标准差等基本统计量,并进行偏度、峰度、JB检验等高级统计检验,以了解数据的分布特征。

def num_jy(df111):
    print("最大值", max(df111))
    print("最小值", min(df111))
    print("平均值", np.mean(df111))
    print("标准差:", np.std(df111))
    print("偏度:", pd.Series(df111).skew())
    print("峰度:", pd.Series(df111).kurt())
    # 计算JB检验量
    skew = pd.Series(df111).skew()
    krut = stats.kurtosis(df111) + 3
    JB = len(df111) * (skew ** 2 / 6 + (krut - 3) ** 2 / 24)
    print("JB检验:", JB)
    p_value = 1 - stats.chi2.cdf(JB, df=2)
    print('p_value:', p_value)
num_jy(df_apple["Close"])

1.3 CEEMDAN分解

为了从原始股价数据中提取潜在的模式,我们使用CEEMDAN(Complete Ensemble Empirical Mode Decomposition with Adaptive Noise)技术对数据进行模态分解。这一技术可以将复杂的时间序列分解为多个本征模态函数(IMFs),有助于去除数据中的噪声并提取出有效的信号。

ceemdan = CEEMDAN()
ceemdan.ceemdan(df_apple["Close"].to_numpy())
imfs, res = ceemdan.get_imfs_and_residue()

1.4 分解结果可视化

通过可视化分解后的IMFs(本征模态函数)和残差,可以直观地了解股价的不同时间尺度上的变化趋势。

plt.figure(figsize=(10,8))
plt.subplot(imfs.shape[0] + 2, 1, 1)
plt.plot(df_apple["Close"], 'r')
plt.ylabel("Original", rotation=60, fontsize=10)
for i in range(imfs.shape[0]):
    plt.subplot(imfs.shape[0] + 2, 1, i + 2)
    plt.plot(imfs[i], 'g')
    plt.ylabel(f"imf{i+1}", rotation=60, fontsize=10)
plt.subplot(imfs.shape[0] + 2, 1, imfs.shape[0] + 2)
plt.plot(res, 'g')
plt.ylabel("res", rotation=60, fontsize=10)
plt.show()

2. 特征选择与数据集划分

在对数据进行模态分解后,我们选择有意义的特征(如IMFs和残差),并将其作为输入特征来训练我们的模型。同时,划分数据集为训练集和测试集,通常选择80%的数据用于训练,剩余20%的数据用于测试。

def data_make(df):
    arr1 = ['imf'+str(i+1) for i in range(imfs.shape[0])] + ['res']
    arr2 = 'target'
    data_set_train1 = df[:int(df.shape[0] * 0.8)]
    data_set_test1 = df[int(df.shape[0] * 0.8):]
    train_X = data_set_train1[arr1]
    train_y = data_set_train1[arr2].to_numpy()
    test_X = data_set_test1[arr1]
    test_y = data_set_test1[arr2].to_numpy()
    return train_X, train_y, test_X, test_y

3. 模型构建与训练

3.1 支持向量机(SVM)

支持向量机(SVM)是一种常用的回归与分类算法,适用于非线性问题。我们首先使用标准的SVM模型进行训练,并用交叉验证评估其性能。

model = svm.LinearSVR()
model.fit(train1_X_apple, train1_y_apple)
y_pred_apple_ceemdan_svm = model.predict(test1_X_apple)

3.2 贝叶斯优化(Bayesian Optimization)

为了进一步提高模型的性能,我们使用贝叶斯优化技术来调整SVM的超参数。贝叶斯优化是一种全局优化算法,特别适合于调参问题。

def SVM_mse_cv(params):
    random_state = 10
    cv = 5
    params = {
        'epsilon': params['epsilon'],
        'C': int(params['C']),
        'intercept_scaling': params['intercept_scaling']
    }
    
    model = svm.LinearSVR(random_state=random_state, **params)
    
    score = -cross_val_score(model, train1_X_apple, train1_y_apple, 
                             cv=cv, scoring='neg_mean_squared_error',
                             n_jobs=1).mean()
    return {'loss': score, 'status': 'ok'}

def BO_SVM_pri(train_X, train_y, test_X):
    random_state = 10
    
    space = {
        'epsilon': hp.loguniform('epsilon', -2, 1),
        'C': hp.quniform('C', 1, 300, 1),
        'intercept_scaling': hp.loguniform('intercept_scaling', -2, 0)
    }
    trials = Trials()
    print("==========================贝叶斯参数优化==============================")
    
    best = fmin(fn=SVM_mse_cv,
                space=space,
                algo=tpe.suggest,
                max_evals=200,
                trials=trials)
    
    if best is None:
        raise ValueError("贝叶斯优化未能找到有效解")
    
    model = svm.LinearSVR(random_state=random_state, 
                          epsilon=best['epsilon'], 
                          C=int(best['C']), 
                          intercept_scaling=best['intercept_scaling'])
    
    model.fit(train_X, train_y)
    y_pred = model.predict(test_X)
    
    return y_pred

3.3 XGBoost与LightGBM

XGBoost和LightGBM是目前应用广泛的树模型,常用于回归与分类任务。它们通过提升树的性能,在许多竞赛中表现出色。我们使用Optuna进行超参数优化,并使用训练好的模型进行预测。

def objective(trial):
    params = {
        'objective': 'reg:squarederror',
        'learning_rate': trial.suggest_loguniform('learning_rate', 1e-3, 1),
        'max_depth': trial.suggest_int('max_depth', 3, 15),
        'n_estimators': trial.suggest_int('n_estimators', 50, 300),
        'subsample': trial.suggest_float('subsample', 0.5, 1.0),
        'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0),
        'reg_alpha': trial.suggest_float('reg_alpha', 0, 10),
        'reg_lambda': trial.suggest_float('reg_lambda', 0, 10),
    }
    model = XGBRegressor(**params)
    model.fit(train2_X_apple, train2_y_apple)
    y_pred = model.predict(test2_X_apple)
    mse = mean_squared_error(test2_y_apple, y_pred)
    return mse

3.4 LSTM与GRU

长短时记忆(LSTM)和门控循环单元(GRU)是两种常用的循环神经网络(RNN)结构,适用于时间序列数据。通过这些网络结构,可以捕捉股价的长期依赖关系,提高预测准确性。

def LSTM_model(x_train, y_train, x_test, epochs, batch_size):
    model = Sequential()
    model.add(LSTM(units=32, return_sequences=True, input_shape=(x_train.shape[1], 1)))
    model.add(Dropout(0.2))
    model.add(LSTM(units=16))
    model.add(Dropout(0.2))
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error', optimizer='adam')
    model.fit(np.array(x_train), np.array(y_train), epochs=epochs, batch_size=batch_size)
    prediction = model.predict(x_test)
    return prediction

4. 模型评估与性能比较

通过计算RMSE(均方根误差)、MAE(平均绝对误差)、MAPE(平均绝对百分比误差)等指标,我们可以评

估每个模型的表现并比较其优劣。下面是一个基于RMSE和MAPE评估模型的代码示例:

def evaluate_predictions(y_true, y_pred):
    rmse = np.sqrt(mean_squared_error(y_true, y_pred))
    mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
    print(f"RMSE: {rmse:.4f}, MAPE: {mape:.4f}%")

5. 结果可视化与总结

最后,我们通过可视化预测结果与实际值的对比,直观地展示每个模型的效果。通过图形,可以清楚地看到哪些模型在股票价格预测中表现得更好。

plt.plot(test_y_apple, color='blue', label='Real AAPL Price')
plt.plot(y_pred_apple_svm, color='red', label='Predicted AAPL Price')
plt.title('AAPL Price Prediction using SVM')
plt.xlabel('Time')
plt.ylabel('Price')
plt.legend()
plt.show()

总结

通过结合CEEMDAN和多种机器学习模型(如SVM、XGBoost、LSTM等),我们能够更准确地预测股票价格。每种模型在不同数据集上的表现有所不同,通过评估指标的比较,我们可以选择最佳的模型进行未来的预测。通过这种方法,不仅能提升股票预测的准确性,还能为金融分析师和投资者提供更有力的数据支持。

由于篇幅有限,需要完整代码请私信我!


http://www.kler.cn/a/502494.html

相关文章:

  • 【React】新建React项目
  • ElasticSearch在Windows环境搭建测试
  • ctypes对接C/C++函数中char*输出型参数
  • springboot vue uniapp 仿小红书 1:1 还原 (含源码演示)
  • Bash语言的多线程编程
  • Wireshark使用
  • PHP数据过滤函数详解:filter_var、filter_input、filter_has_var等函数的数据过滤技巧
  • python-PC应用自动化操作
  • 【LeetCode: 179. 最大数 + 贪心】
  • 福建双色荷花提取颜色
  • C# GDI+的DrawString无法绘制Tab键的现象
  • 腾讯云AI代码助手编程挑战赛-智能聊天助手
  • 大语言模型预训练、微调、RLHF
  • YangQG 面试题汇总
  • Java安全—SPEL表达式XXESSTI模板注入JDBCMyBatis注入
  • 玩转大语言模型——langchain调用ollama视觉多模态语言模型
  • Ubuntu Server挂载AWS S3成一个本地文件夹
  • Nginx简述
  • MySQL表的增删改查(进阶)-上篇
  • Vue.js组件开发-图片剪裁性能优化最佳方案实例
  • 【JVM-2.3】深入解析JVisualVM:Java性能监控与调优利器
  • 【解决问题】WSL报错 Netlink send error : Invalid argument
  • 认识机器学习中的经验风险最小化准则
  • torch.einsum计算张量的外积
  • 每天五分钟深度学习框架pytorch:快速搭建VGG网络的基础模块VGG块
  • docker 日常使用(进入容器、查看日志)