资讯动态

机器学习股票预测课设全流程:数据、特征、LSTM与回测实战

发布时间:2026/10/14 16:24:33 来源:尧图企业网站定制
简介机器学习股票预测算法源码项目资料包面向高校人工智能、计算机、金融工程等相关专业学生适用于课程设计、毕业设计及量化交易入门实践。项目覆盖了完整的股票数据获取、特征工程、模型训练与回测流程包括K线数据入库、小市值结合盈利指标过滤策略、FFT滤波、单层LSTM预测以及基于sklearn的单票回测等典型量化场景。资料包共26个文件以Jupyter Notebook、Python脚本、CSV数据文件为主辅以Markdown说明与Word报告文档压缩包仅2.57MB整体结构清晰适合按模块渐进学习。目前已有53人学习下载。代码经测试可正常运行附带说明文档能帮助初学者梳理数据预处理、模型构建与评估思路对于基础较好的读者也可直接在此框架上扩展多因子选股或参数调优实验并在课设答辩时结合报告完整呈现研究过程。1. 机器学习股票预测这份课设源码包里到底有什么做股票预测课程设计最怕的是什么不是模型不收敛而是资料凑不齐——数据要自己爬、特征要自己造、报告要自己编最后做出来一个自己都不敢信的“黑匣子”。这份《机器学习股票预测算法源码项目说明报告2024课设》把整条链路都打包好了数据获取脚本、特征工程、K线数据入库、LSTM单票预测、sklearn多模型回测、实时预测脚本外加一份可以直接参考的课程设计报告。我拆完这个包之后最直接的感受是它不是那种只有一个孤零零notebook的“demo”而是一套有数据、有过程、有对比、有交付物的完整课设工程。适合三类人做机器学习相关课设/毕设的学生、想快速跑通“数据→特征→模型→回测”全流程的初学者、以及想拿现成框架改成自己课题的从业者。接下来我按实际拆包顺序把每个模块怎么用、参数怎么调、坑在哪里都过一遍。2. 数据获取与特征工程先解决“喂什么”再谈“怎么预测”2.1 get_data.py与getstockcsv.py两类取数脚本的差异与选型数据是预测的地基。包里有两个取数脚本用途完全不同。# get_data.py —— 单票日K拉取适合研究单只股票时用 import akshare as ak import pandas as pd import time def fetch_daily(symbol: str, start_date: str, end_date: str, save_path: str): # symbol 形如 600256akshare 需要补全交易所后缀 if symbol.startswith((6, 9)): code fsh{symbol} else: code fsz{symbol} df ak.stock_zh_a_hist( symbolcode, perioddaily, start_datestart_date, end_dateend_date, adjustqfq # 前复权避免除权跳空干扰 ) # 重命名列统一成后续模型能直接用的字段 df.rename(columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume }, inplaceTrue) df.to_csv(save_path, indexFalse) time.sleep(1.2) # 限速避免触发接口频控 print(f{symbol} saved to {save_path}, rows{len(df)}) if __name__ __main__: # 执行python get_data.py fetch_daily(600256, 20180101, 20241231, data/600256.csv)这个脚本的逻辑很直白先用股票代码前缀判断交易所然后通过akshare拉取前复权日K统一字段命名后落盘CSV。这里有两个容易被新手忽略的点一是adjustqfq如果不做复权处理遇到除权除息日股价会跳空模型学到的“涨跌规律”里混入了非交易因素二是time.sleep(1.2)akshare免费接口有频控拉多只股票时不加休眠大概率中途断掉。getstockcsv.py则是另一套逻辑我打开看了下它适合批量场景从一个股票池列表循环取数每只股票存一个独立CSV。选型建议很简单只做单票预测比如你只研究一只股票用get_data.py就够了如果你想在后期做多票筛选比如“小市值盈利过滤”那个notebook那就用getstockcsv.py先把候选池的数据批量拉下来。注意akshare接口字段偶尔会变动如果你的pandas版本或akshare版本和作者不一致取回来的列名可能对不上后续脚本会直接KeyError。2.2 newfeature.py特征怎么构造才不只是“收盘价成交量”# newfeature.py —— 传统技术指标 衍生特征 import pandas as pd import numpy as np def add_features(df: pd.DataFrame) - pd.DataFrame: df df.copy() # 动量特征5日 / 10日 / 20日收益率 df[ret_5] df[close].pct_change(5) df[ret_10] df[close].pct_change(10) df[ret_20] df[close].pct_change(20) # 均线结构特征收盘价相对MA5 / MA10 / MA20的位置 df[ma5] df[close].rolling(5).mean() df[ma10] df[close].rolling(10).mean() df[ma20] df[close].rolling(20).mean() df[close_ma5_ratio] df[close] / df[ma5] - 1 df[close_ma10_ratio] df[close] / df[ma10] - 1 df[close_ma20_ratio] df[close] / df[ma20] - 1 # 量能特征成交量相对5日均量的放大倍数 df[vol_ma5] df[volume].rolling(5).mean() df[vol_ratio] df[volume] / df[vol_ma5] # 波动率特征20日收益率标准差年化近似 df[volatility] df[close].pct_change().rolling(20).std() * np.sqrt(252) # 清洗删除前20行均线和波动率需要滚动窗口产生NaN df df.iloc[20:].reset_index(dropTrue) return df特征工程这段值得多说两句。包里的newfeature.py走的是“技术指标衍生”路线构造了四个维度的特征动量多周期收益率、均线结构价格相对均线的偏离度、量能量比、波动率。这四个维度覆盖了趋势、位置、资金参与度和风险状态是机器学习预测股票时比较标准的特征底子。为什么要做close_ma5_ratio而不是直接喂ma5这里有个经验点模型对绝对数值不敏感但对“相对关系”敏感。close / ma5 - 1表示价格偏离5日均线的百分比这个值是尺度无关的——不管股价是5块还是500块偏离5%在特征空间里是同一个量级模型不需要额外学习价格尺度。同理vol_ratio代表当天量能是5日均量的几倍比绝对手数更稳定。理论上特征越多越好不是的特征越多越容易过拟合尤其样本量只有几百根日K时。我一般控制特征数量在10个以内而且优先选“有经济含义”的特征。技术指标类特征的问题在于它们本质上是价格的函数变换信息有重叠树模型还能扛得住线性模型和神经网络容易学到冗余映射。2.3 保存K线数据到数据库.ipynb为什么要入库而不是直接用CSV包里有个保存K线数据到数据库.ipynb这个文件很容易被忽略但它实际上解决了一个很现实的问题——数据管理。拉下来的K线数据如果只存在CSV里时间一长你会面临几个问题文件散落在不同目录、增量更新要靠脚本手动跑、多个notebook读同一份数据时格式不统一。入库之后这些问题就干净了。# 保存K线数据到数据库.ipynb 核心逻辑 import sqlite3 import pandas as pd # 连接SQLite文件型数据库零配置适合课设 conn sqlite3.connect(stock_data.db) # 建表每只股票一张表按日期主键去重 create_sql CREATE TABLE IF NOT EXISTS kline_daily ( code TEXT, date TEXT, open REAL, high REAL, low REAL, close REAL, volume INTEGER, PRIMARY KEY (code, date) ); conn.execute(create_sql) # 读CSV → 按唯一约束去重 → 写入 df pd.read_csv(data/600256.csv) df[code] 600256 df.to_sql(kline_daily, conn, if_existsappend, indexFalse) # 用SQL去重保留每只股票每个交易日最新一条 dedup_sql DELETE FROM kline_daily WHERE (code, date, rowid) NOT IN ( SELECT code, date, MAX(rowid) FROM kline_daily GROUP BY code, date ); conn.execute(dedup_sql) conn.commit() conn.close()入库的好处体现在后面所有环节做多票策略回测时一条SQL就能把多只股票按日期对齐做特征工程时不需要反复读CSV增量更新只需把新数据append进去再跑一次去重。SQLite是文件型数据库不需要装服务课设机器上直接能用不会因为数据库起不来而翻车。如果你用的是MySQL连接串、建表语句基本同理只是需要先启动服务并配置账号权限。我觉得这个notebook放在这里还有一个隐含意图课设答辩时老师问“数据怎么管理的”你答“用SQLite统一存储按codedate做唯一约束去重增量追加”——这比“我用CSV存的那老师自己翻代码去吧”要加分得多。3. LSTM单票预测从数据清洗到模型训练的全流程拆解3.1 singlelstm.ipynb与singlelstm2.ipynb两个版本的区别在哪包里有两个LSTM版本的notebooksinglelstm.ipynb和singlelstm2.ipynb一开始我以为只是作者写了两个草稿仔细对比之后发现它们的建模思路有明显差异对比项singlelstm.ipynbsinglelstm2.ipynb输入特征只用收盘价序列收盘价 成交量 技术指标归一化方式MinMax整体归一化滑动窗口内归一化预测目标下一日收盘价下一日收益率序列长度30 天60 天适用场景快速验证LSTM能否学到趋势更接近可用的预测方案第一个版本是“最小可用”的基线单变量序列、30天窗口、预测次日价格跑通流程给模型打个底。第二个版本做了三处关键升级特征从单变量变成多变量接了前面newfeature.py的输出、预测目标从价格变为收益率、序列长度从30变成60。这里有个值得展开的点为什么第二个版本要把预测目标从“收盘价”改成“收益率”直接预测价格模型学到的其实是“昨天的价格加上一个微小增量”——因为价格序列高度自相关今天的收盘价和昨天几乎一样模型很快就会找到一个“最优解”直接把上一日价格作为预测输出损失函数已经很小了但它并没有学到任何有意义的东西。而收益率序列是近似平稳的模型必须真正学习特征与涨跌之间的关系而不是抄近路。3.2 LSTM模型结构与训练参数Keras代码逐行解读# singlelstm2.ipynb 的核心模型构建与训练 import numpy as np import pandas as pd from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split # 数据准备特征列与标签列 df pd.read_csv(data/600256.csv) df add_features(df) # 接 newfeature.py 的特征工程 feature_cols [close, volume, ret_5, ret_10, close_ma5_ratio, close_ma10_ratio, vol_ratio, volatility] # 标准化注意fit在训练集上避免数据泄露 scaler StandardScaler() scaled scaler.fit_transform(df[feature_cols].values) # 标签下一日收益率t1相对t的收益 df[label] df[close].shift(-1) / df[close] - 1 label_col df[label].values # 构造序列样本lookback60天预测下一天 def make_sequences(data, labels, lookback60): X, y [], [] for i in range(lookback, len(data) - 1): X.append(data[i - lookback:i]) y.append(labels[i]) return np.array(X), np.array(y) lookback 60 X, y make_sequences(scaled, label_col, lookback) # 按时间顺序切分不能用随机切分时间序列不能打乱顺序 split_idx int(len(X) * 0.8) X_train, X_test X[:split_idx], X[split_idx:] y_train, y_test y[:split_idx], y[split_idx:] # 模型两层LSTM Dropout 全连接 model Sequential([ LSTM(64, return_sequencesTrue, input_shape(lookback, X.shape[2])), Dropout(0.2), LSTM(32, return_sequencesFalse), Dropout(0.2), Dense(16, activationrelu), Dense(1) ]) model.compile(optimizeradam, lossmse, metrics[mae]) # EarlyStopping验证集loss连续10轮不降就停防止过拟合 early_stop EarlyStopping(monitorval_loss, patience10, restore_best_weightsTrue) history model.fit( X_train, y_train, validation_split0.1, epochs100, batch_size32, callbacks[early_stop], verbose0 )这段代码里有几个训练参数值得单独说明。lookback60的意思是模型每次看过去60个交易日的特征窗口来预测下一天60天大约是3个月——对日线数据来说这个窗口长度能覆盖一段相对完整的趋势又不至于太长导致样本数量骤减。如果你手里的股票数据只有200个交易日建议把lookback降到30否则样本量太少。batch_size32是训练速度和稳定性的折中小批量提供梯度噪声有助于跳出局部最优。patience10表示验证集loss连续10轮不降就停。我见过很多人训练LSTM不看loss曲线硬跑100轮结果过拟合得一塌糊涂。EarlyStopping加restore_best_weightsTrue是最稳妥的组合——停了之后自动回滚到验证集最优的权重不需要手动保存。validation_split0.1是在训练集里再切10%做验证注意这是“训练集内部的验证”和前面按时间切出的X_test是两回事。X_test用来评估模型的真实泛化能力val只用来监控训练过程。这两个角色不能混。3.3 fft-filter.ipynb用FFT对价格序列滤波再训练是玄学还是真有效这个文件是我拆包时的意外收获。fft-filter.ipynb做的事情是先对收盘价序列做快速傅里叶变换FFT把高频噪声过滤掉再用逆变换重构一个平滑的价格序列然后在这个“去噪”序列上做后续分析和建模。# fft-filter.ipynb 核心逻辑 import numpy as np import pandas as pd def fft_filter(series: pd.Series, keep_ratio: float 0.1) - np.ndarray: 对价格序列做FFT仅保留幅度最大的前 keep_ratio 比例的频率分量 # 原始序列长度 n len(series) # 快速傅里叶变换复数结果 fft_vals np.fft.fft(series.values - np.mean(series.values)) # 取频域幅值 amplitude np.abs(fft_vals) # 保留能量最大的频率索引低频为主 keep_count max(1, int(n * keep_ratio)) threshold np.sort(amplitude)[::-1][keep_count - 1] fft_vals[amplitude threshold] 0 # 其余置零等效于滤掉高频噪声 # 逆变换回时域再补回均值 filtered np.fft.ifft(fft_vals).real np.mean(series.values) return filteredFFT滤波的原理一句话讲清楚价格序列可以看作很多不同频率的正弦波叠加低频对应长期趋势高频对应短期噪声。保留前10%的幅度分量相当于只留下趋势和主要波段滤掉随机波动。这样做的好处是模型不用在噪声中挣扎着找规律训练会更平稳代价是滤掉的部分可能包含真实信息——短线反转信号往往是高频的滤掉了就学不到。实操建议如果你做的是趋势跟踪类策略这个滤波思路值得试参数keep_ratio从0.05到0.2之间网格搜索一下找到对验证集最合适的值但如果你做的是高频短线预测别轻易滤高频。至少它是一个能写进报告里的“对比实验”同一套LSTM结构滤波前vs滤波后验证集MAE差多少——这比只贴一个模型的loss曲线有说服力得多。4. sklearn机器学习单票回测用传统模型验证预测思路4.1 模型对比线性回归、随机森林、SVR谁更适合股票预测sklearn机器学习单票回测.ipynb是包里实现传统机器学习模型的notebook它解决的问题是LSTM到底比传统模型强在哪以及如果不用深度学习传统模型能不能得到一个“还能用”的预测器先看一下常见做法——把特征工程产出的特征矩阵直接喂给不同回归模型统一用滚动时间窗口评估。这里的关键是“滚动”而非随机切分。时间序列的样本之间有先后依赖如果随机打乱再切分相当于让模型“偷看未来”训练出来的指标全是虚的。# sklearn机器学习单票回测.ipynb 核心逻辑 import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.svm import SVR from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, mean_squared_error from sklearn.preprocessing import StandardScaler df pd.read_csv(data/600256.csv) df add_features(df) # 标签次日收益率 df[label] df[close].shift(-1) / df[close] - 1 df df.dropna() feature_cols [ret_5, ret_10, ret_20, close_ma5_ratio, close_ma10_ratio, close_ma20_ratio, vol_ratio, volatility] X df[feature_cols].values y df[label].values # 滚动切分前70%训练后30%测试严格按时间顺序 split int(len(X) * 0.7) X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:] # 特征需要标准化SVR对尺度敏感 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 三个模型统一评测MAE与方向准确率 models { LinearRegression: LinearRegression(), RandomForest: RandomForestRegressor(n_estimators200, max_depth8, random_state42), SVR: SVR(kernelrbf, C1.0, epsilon0.02) } results {} for name, model in models.items(): model.fit(X_train_scaled, y_train) pred model.predict(X_test_scaled) mae mean_absolute_error(y_test, pred) # 方向准确率预测涨跌方向与真实涨跌方向一致的比例 direction_acc np.mean((np.sign(pred) np.sign(y_test))) results[name] {MAE: mae, DirectionAcc: direction_acc} print(f{name}: MAE{mae:.4f}, DirectionAcc{direction_acc:.2f})为什么SVR要做标准化而随机森林不需要三两句说清楚。SVR用的是高斯核rbf核函数计算的是样本在高维空间的距离如果特征尺度差100倍距离会被大尺度特征主导小尺度特征的信息直接被淹没随机森林是做特征分裂的每次只在一个特征上找切分点尺度大小对分裂结果没有影响所以可以不标准化。线性回归的系数本来就自带尺度归一化能力但标准化后可以加速求解做了也不亏。三个模型的定位差异也很明显。线性回归是“基线”——先看线性关系能做到什么水平如果MAE和方向准确率已经不错说明特征和标签的关系接近线性没必要上复杂模型随机森林是“非线性基线”它只用了8层深度因为股票特征的交互效应其实有限太深的树纯属过拟合SVR的epsilon0.02表示预测值和真实值在±0.02的误差范围内不计算损失这给了模型一个“容差带”对噪声较多的金融数据有一定的防止过拟合作用。4.2 单票回测怎么评估MAE、MSE、方向准确率之外还要看什么回测最忌讳只盯着MAE这一个指标。比如模型预测的收益误差是0.01看起来很漂亮但如果方向准确率只有48%说明模型的预测和抛硬币没区别——它在数值上“接近”但方向上完全没判断力。一个预测次日收益率的模型方向准确率是首要指标超过52%才有继续调参的意义低于50%基本说明特征和标签之间没有稳定的映射关系。除了方向准确率我还会再看两个指标一个是盈亏不对称性——把预测正确的样本和预测错误的样本分开看如果模型在暴涨日表现出色、在暴跌日完全失效说明它学到的是趋势延续而不是转折识别另一个是预测值分布与真实值分布的差异——如果模型预测的收益率集中在±0.01区间而真实收益率的分布明显更宽说明模型学到的只是“平均回归”预测结果基本没有区分度。这个对比可以用一行代码看# 观察预测值分布 vs 真实值分布判断模型是否退化为均值回归 percentiles_pred np.percentile(pred, [10, 50, 90]) percentiles_true np.percentile(y_test, [10, 50, 90]) print(预测分布 (P10/P50/P90):, percentiles_pred) print(真实分布 (P10/P50/P90):, percentiles_true)如果P90_P10的跨度只有真实分布的一半这模型预测的方向可能还对但幅度全部被“压扁”了。这时候如果你直接按预测收益率排序选股会发现选出的是“全市场都一样涨”的股票——毫无区分度。这个scikit-learn模型对比的价值在于它可以作为LSTM的一个参照系。LSTM的MAE如果还没线性回归低那说明你的特征或者数据预处理出了问题而不是LSTM不行——深度学习不是免死金牌它只是更昂贵的模型在信号强度不足的数据上传统模型反而更稳健。5. 踩坑记录这些坑我替你踩过了别再往里跳5.1 特征归一化时用了全量数据的mean和std预测结果虚高现象训练集MAE很低但测试集一跑预测曲线几乎是“上一日价格的平移”方向准确率在50%附近晃。原因是scaler.fit()用了包含测试集的全部数据计算mean和std相当于让模型“偷看”了测试集的分布——这叫数据泄露data leakage是时间序列建模最常见的问题。解决也很简单先切分数据、再归一化而且fit只在训练集上调用测试集只用transform。这里有一个容易被忽略的细节如果你用了FFT滤波滤波过程本身也牵涉到全序列信息也要先滤波再切分或者按时间分段滤波否则同样的泄露问题会换个马甲回来。从那以后我每次做时间序列实验都强制先切分、再归一化一步都不改顺序。5.2 akshare取数接口报错“请求太频繁”现象拉第7、8只股票时报HTTP 429或者请求频繁脚本中断。原因akshare免费接口没有官方QPS承诺短时间连续请求会被服务端限流。解决每只股票之间time.sleep(1.2)是最基础的方案更稳的做法是在getstockcsv.py里加失败重试和随机退避——失败后随机等2到5秒再试一次连续失败3次就跳过并记录。另外建议把“失败重试”和“全部成功”两个状态的分支都加上打印日志前后端信息一目了然for symbol in stock_list: for attempt in range(3): try: fetch_daily(symbol, start, end, save_path) break except Exception as e: wait 2 np.random.rand() * 3 print(f{symbol} 第{attempt 1}次失败: {e}{wait:.1f}s后重试) time.sleep(wait)5.3 用“次日开盘买入”做回测时预测日和交易日的对齐错了现象回测收益曲线看起来非常漂亮年化收益率50%以上但实盘完全对不上。原因大概率是模型预测的是t1的收益率代码里却用t1的收盘价作为买入价格——相当于你在今天收盘时已经知道了明天的收盘价然后按明天收盘价买入这不叫预测叫作弊属于典型的未来函数。正确做法是用t日收盘后能拿到的全部信息做预测在t1日开盘价买入t2日开盘价卖出或t1收盘价卖出买入价和卖出价必须是真实可成交的价格。未来函数是回测里最坑的一类问题表现就是回测好看到像梦实盘打脸到清醒。5.4 LSTM每次训练的结果都不一样不知道以哪个为准现象同一个notebook连续跑三次三次的验证集MAE都不一样有时差5%有时差20%。原因神经网络权重随机初始化 Adam的随机梯度下降 Dropout的随机失活这些随机性叠加起来结果当然不一样。解决第一步在模型构建后设置全局随机种子np.random.seed(42)加上tf.random.set_seed(42)第二步多跑几次取中位数当作模型真实水平的估计。课设报告里只写一次结果是不严谨的写“同参数下5次运行的平均MAE±标准差”会更有说服力。更稳的做法是最终提交前固定种子再跑一次保证答辩现场复现的结果和你报告里写的一致。5.5 报告里的参考图和实际跑出来的数据对不上现象包里的报告仅供参考学习.docx中有训练曲线、收益曲线等图表你照着代码重跑一遍发现数值和图上不一样。原因报告对应的可能是作者当时某次运行的结果特定随机种子、特定时间段的数据而文件里的数据脚本重跑后数据时间范围可能有出入。这个不是代码坏了是“实验可复现性”问题。解决以自己跑出来的结果为准报告只作为行文结构和分析框架参考如果需要引用报告里的数字必须在答辩时说明“该结果在当时的数据和随机种子下取得重跑会略有波动”。6. real_time.py把训练好的模型接到实时行情上real_time.py是包里最有“工程感”的一个文件——它把静态的训练流程推向了动态的预测流程。先看核心代码结构# real_time.py —— 简化版实时预测流程 import pandas as pd import numpy as np import akshare as ak from tensorflow.keras.models import load_model # 加载训练阶段保存的模型和标准化器 model load_model(lstm_stock_model.h5) def fetch_realtime_latest(symbol: str) - pd.DataFrame: # 拉最近80个交易日日Klookback需要60多取20天用于特征计算 if symbol.startswith((6, 9)): code fsh{symbol} else: code fsz{symbol} df ak.stock_zh_a_hist(symbolcode, perioddaily, start_date20241001, end_date20241231, adjustqfq) return df def predict_next(symbol: str) - float: df fetch_realtime_latest(symbol) df add_features(df) # 复用特征工程 latest_window df[feature_cols].values[-60:] # 最近60行 scaled scaler.transform(latest_window) # 注意只用transform X_input scaled.reshape(1, 60, len(feature_cols)) pred_return model.predict(X_input)[0][0] return pred_return这个脚本的设计逻辑值得注意。它没有直接调行情接口去预测“下一秒”而是拉最近80个交易日日K算出特征后取最近60个交易日窗口喂给模型。为什么多拉20天因为特征工程里的ret_20和volatility需要20天的历史来滚算如果只拿60天特征的前20行全是没有意义的NaN。real_time.py的局限也要说清楚它的“实时”其实是日线级别——每天收盘后跑一次预测明天的收益率并不是分钟级的盘中预测。做课设写报告时这个定位要写准确日线级预测的目标是辅助判断中线趋势不是T0交易信号。脚本的价值在于把训练和预测两段流程解耦了训练阶段产出的lstm_stock_model.h5和scaler经过joblib或pickle持久化实时阶段不用重新跑特征工程和训练直接加载即可。我在实际用的过程中会再给它加两件事。第一是加一个“预测置信区间”的提示——用模型在测试集上预测误差的标准差来估计波动范围预测值±1.96倍标准差做个区间比只给一个点值更诚实。第二是加一个阈值判断——当预测收益率绝对值小于某个阈值比如0.005时标记为“观望”这种信号在策略层面直接过滤掉减少无效操作的次数。别小看这一步它能把回测里的交易次数降下来、手续费损耗跟着降“少动”对日线级别的模型是一种保护。最后加一个实操层面的习惯每次改造这个项目里的数据源或模型参数我都会用同一个验证集跑一次对比记录MAE和方向准确率的变化更新到自己的笔记里。课设代码本身可以改但改动的每一步都要有记录——答辩时老师问“你做了什么改进”的时候你能拿出前后对比的数据而不是一句“我调了参数”。这份资源包的代码完整度在课设级别里算高的好好拆一遍LSTM和sklearn两条线的对比你就知道深度学习在时间序列预测上的边界在哪了希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑