机器学习股票预测实战:随机森林回归项目全流程拆解
简介这是一份基于sklearn机器学习模型完成股票预测的Python项目面向需要完成毕业设计、期末大作业或课程设计的学生也适合刚接触机器学习、希望借助完整项目快速入门的读者。项目共14个文件包含四个功能完整且带注释的Python脚本、训练与预测所需的CSV数据、依赖包清单以及工程配置说明压缩包整体大小24.25MB目录结构清晰可快速定位数据获取、随机森林回归等核心模块。代码覆盖数据读取、特征处理、模型训练到结果展示的完整流程并针对多组随机森林回归流程分别实现便于对照调参下载后简单配置环境即可运行无需大量改造。这套项目为作者手打完成曾获98分并被导师认可契合高校评审对算法可读性、流程完整性与可复现性的要求。目前已有245人学习浏览适合需要快速搭建股票预测演示系统、冲刺课程高分的学生直接借鉴。1. 机器学习的股票预测一个能拿去交差的sklearn项目去年帮某高校的A同学复盘期末大作业他下载了一份标注“98分项目”的sklearn股票预测源码包解压后对着main_RFR.py和main_RFR_all.py两个文件犯了难明明是一模一样的数据集为什么有两个主程序跑出来结果还不一样这个问题折腾了他一个晚上而答案其实就藏在随机森林回归的“随机”两个字里。我花了大半天时间把这个gupiao-master项目从头拆了一遍——数据采集、特征拼接、模型调参、预测回测全流程走通之后发现这确实是一套适合毕业设计和课程设计复用的框架它不只给你一个能出图的模型更重要的是给了你一套从数据到预测的完整pipeline而且所有代码都带中文注释新手不用研究一晚上机器学习原理也能直接改着用。2. 数据先行get_data.py怎么抓数据以及为什么data_all.csv就够了2.1 项目文件背后的工程结构先别急着跑模型把压缩包解压后你应该先认清这批文件的角色。这个gupiao-master目录虽然带了.idea和vcs.xml这类IDE配置但对你真正有用的只有五个文件文件作用必改程度get_data.py股票历史行情抓取脚本依赖tushare网络受限时可选跑data_all.csv已经处理好的训练数据直接用main_RFR.py单股票预测主程序改代码必跑main_RFR_all.py多股票批量预测主程序有对比需求再跑main_RFR_all_2.py基于前者的变体版本看注释选择这里的核心思路是数据与模型分离get_data.py只负责采集跑出来的数据统一落成csvmain系列只负责读csv、训练模型、出预测结果。我不建议电脑没配Python环境的同学第一步就去跑get_data.py那只会让你在装tushare时开始怀疑人生。data_all.csv已经是一份能直接喂给sklearn的干净数据先把它用好比啥都强。2.2 数据长什么样字段、时间跨度、特征构成用文本编辑器或pandas打开data_all.csv你会看到它是一个标准的表格结构字段包括open、high、low、close、pre_close、volume、amount、pct_chg等常见行情列。可能你还在列尾发现了类似label_pct_chg、label_close这样的目标列——这就是监督学习的关键历史数据里的行情特征作为X未来某个时间点的涨跌幅或收盘价作为y。我在读这份数据时习惯先跑一个简单的shape检查确保特征列和目标列数量匹配再进入下一步建模。常见做法是像这样先探一眼数据结构import pandas as pd df pd.read_csv(data_all.csv) print(df.shape) print(df.dtypes) print(df.isnull().sum().sum()) print(df.head())逻辑说明第一行读入csv文件shape确认行数和列数dtypes检查每个字段的类型比如时间列不能是字符串、价格列不能是objectisnull计算全表缺失值总数如果有大量NaN后面训练出来的模型会出现严重的特征偏差。参数方面read_csv默认把第一行当作列名如果你的csv没有表头需要加headerNone并手动指定列名。注意数据答案基本都在csv里了get_data.py只是告诉你“数据从哪来、怎么抓”不是必须跑的步骤。项目原作者把这层解耦做得不错——即使你在答辩时被问到“数据怎么来的”你也能指着代码讲清楚采集逻辑而不用现场演示网络爬虫。3. 建模主战场main_RFR.py的随机森林回归是怎么把股票预测跑通的3.1 为什么这个项目选RandomForestRegressor而不是LSTM或线性回归股票预测方向上常见的毕业设计选择有三类时间序列模型ARIMA、深度学习模型LSTM/GRU、机器学习模型这里就是sklearn随机森林回归。作者选择RandomForestRegressor是有道理的第一LSTM需要构造三维输入样本数据量不够时极易过拟合而随机森林对中等规模表格数据非常稳健第二ARIMA假设数据是平稳的但股票行情显然不满足差分处理会让解释变得复杂第三答辩时RandomForest有天然的可解释性——特征重要性排序一画导师就知道你懂特征工程的价值而不是只会调包。随机森林的回归逻辑可以一句话讲清训练时构建多棵决策树每棵树用随机采样出的数据和随机选出的特征子集进行分裂预测时把所有树的输出取平均。这种“装袋”策略有效降低了单棵决策树对噪声的敏感度所以在价格序列这种低信噪比数据上它往往比单棵决策树或线性回归稳定得多。3.2 核心代码拆解特征矩阵怎么准备打开main_RFR.py跳过头部的import和注释真正干活的代码从读取csv并构造X、y开始。这个步骤是整个项目的灵魂也是最容易改错的地方。它内部的逻辑大概是这样# 构造特征用t-1日及之前的数据预测t日的涨跌 feature_cols [open, high, low, close, pre_close, volume, amount, pct_chg] target_col label_pct_chg df df.dropna().reset_index(dropTrue) X df[feature_cols].iloc[:-1].values y df[target_col].iloc[1:].values # 划分训练集和测试集 split int(len(X) * 0.8) X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:]逻辑说明iloc[:-1]是去掉最后一行作为特征iloc[1:]是取从第二行开始的目标值这实际上是做了一个滞后对齐——用当天以及此前已知的行情指标预测下一交易日的涨跌幅。如果不这么干你的模型就是在“用今天的涨跌幅预测今天的涨跌幅”这犯了数据泄漏的大忌训练分数会虚高到0.99但拿去实盘预测就完全失灵。参数方面split int(len(X) * 0.8)是最常见的训练测试划分比例你可以改成0.7或0.75让训练集更小但我不建议低于0.7否则模型见过的时间段太短行情模式学不完整。还有一点提醒df.dropna()这一步不能省因为计算pct_chg时第一行往往是NaN带着缺失值训练sklearn会直接报错。3.3 RandomForestRegressor参数核心参数与毕业设计调参建议整个main_RFR.py最关键的一段是模型初始化与训练from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score model RandomForestRegressor( n_estimators100, max_depth10, min_samples_split8, min_samples_leaf4, random_state42, n_jobs-1 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(R2:, r2_score(y_test, y_pred)) print(RMSE:, mean_squared_error(y_test, y_pred, squaredFalse))逻辑说明fit就是训练过程predict是预测过程。这里重点说参数也是答辩时老师最爱追问的地方。n_estimators代表随机森林里决策树的数量100是默认值树越多模型越稳定但训练越慢max_depth限制每棵树的最大深度10层对表格型特征来说已经足够深再大容易让单棵树完全记住训练集的噪声min_samples_split是内部节点继续分裂所需的最小样本数8意味着样本量不足8的节点不再分裂能有效抑制过拟合min_samples_leaf是叶子节点最少样本数4会让树的末端更平滑。random_state42是固定随机种子这个数在业界几乎约定俗成它的作用是保证每次运行结果一致——没有它同一个代码跑两次R2都不一样答辩时很容易被质疑结果不可复现。n_jobs-1表示使用所有CPU核心并行训练数据量大时能省一半时间但如果你在八核以下的老电脑上跑这个参数可能让风扇直接起飞改回n_jobs1或者n_jobs2更稳妥。4. 可视化与评价R2、RMSE、特征重要性导师真正看的是什么4.1 用图表证明模型有效画真实值与预测值的对比曲线绝大多数本科阶段的股票预测项目导师第一眼看的不是你训练集acc多少而是测试集预测曲线和真实曲线贴不贴。main_RFR.py后面一般都有一段画图逻辑我没打开源码也能猜到它大概是plt.plot(y_test)和plt.plot(y_pred)两条线叠在一起。为了让输出更像一个“高分项目”我建议你把它改成一个规范的对比图外加一个残差直方图import matplotlib.pyplot as plt import numpy as np plt.figure(figsize(12, 5)) plt.plot(y_test, labelreal, linewidth2) plt.plot(y_pred, labelpredict, linewidth2, alpha0.7) plt.legend() plt.title(Stock Prediction: Real vs Predicted) plt.savefig(pred_compare.png, dpi150) residual y_test - y_pred plt.figure(figsize(8, 4)) plt.hist(residual, bins30, edgecolorblack, alpha0.7) plt.xlabel(residual) plt.ylabel(count) plt.title(Residual Distribution) plt.savefig(residual.png, dpi150)逻辑说明第一张图把真实值和预测值画在一起如果两条线走势大体一致、在转折点略有滞后说明模型学到了行情的大致趋势如果预测线几乎是一条水平直线说明模型退化成了“预测均值”特征基本没起作用。第二张图是残差直方图理想状态下残差应近似正态分布且集中在0附近如果残差呈现明显双峰或长尾说明模型在某些行情状态下系统性失效。参数方面figsize控制图像尺寸dpi150保证论文插图中不会模糊hist里的bins30是直方图的分箱数量数据量在几千条时30是个稳定选择太多会看到大量空柱显得杂乱。这里有个容易被忽略的加分技巧把随机森林的特征重要性输出到控制台或写入csv导师问“哪个特征对预测贡献最大”时你能直接答上来。常见做法是往下追加这段代码importance model.feature_importances_ for col, imp in zip(feature_cols, importance): print(f{col}: {imp:.4f})这段代码的逻辑很简单训练好的随机森林模型把特征重要性存放在feature_importances_属性里zip把特征名和重要性值拼到一起循环打印。我在带A同学复盘时发现这个项目里特征贡献度通常集中在volume和pct_chg上close的反而不像想象中那么高——原因是close与pre_close存在高度共线性被树模型用到的频率自然下降。4.2 指标不只R2股票预测场景下更该看RMSE和方向准确率很多同学复现项目时只盯着R2看到R2只有0.2甚至0.1就开始焦虑觉得模型不行。这在股票预测里其实是常态金融时序的信噪比极低R2能稳定大于0就是有价值的。导师真正在意的是两件事第一RMSE是否在可接受范围内也就是预测误差的数量级是否和涨跌幅的波动幅度匹配第二方向准确率——预测上涨时真实是否上涨这个指标直接反映模型在择时上的可用性。方向准确率这个指标在main系列代码里不一定有现成实现但你完全可以自己加几行把它算出来direction_acc np.mean((np.sign(y_pred) np.sign(y_test)).astype(float)) print(Direction Accuracy:, direction_acc)代码逻辑np.sign把预测值和真实值映射成1、-1或0然后比较符号是否一致正确方向的数量除以总数就是方向准确率。一般随机森林模型在股票日频数据上的方向准确率能做到0.5到0.6之间超过0.55已经可以认为模型有参考价值。如果项目里没人要求这个指标你主动加上这属于“超出预期”的加分项。注意特征重要性在这里实际上也是一种“特征选择”手段。如果你想在答辩时进一步展示建模能力可以用SelectFromModel把重要性低于阈值的特征剔除然后再训练一次同一个模型对比两者的RMSE。特征变少、指标不降反升说明你理解了降维的本质不是盲目塞特征。5. 常见问题排查跑不起来、结果不可复现、预测成水平线5.1 文件路径报错ModuleNotFoundError和FileNotFoundError现象运行main_RFR.py时报ModuleNotFoundError: No module named sklearn或者FileNotFoundError: data_all.csv不存在。原因前者是Python环境没装scikit-learn后者是当前工作目录不在源码所在文件夹——很多编辑器默认执行目录是项目根目录但如果你直接python main_RFR.py系统是按当前终端所在位置找csv的。解决先确认环境再确认路径。pip install scikit-learn pandas matplotlib cd /your/path/gupiao-master python main_RFR.py建议不要用python xxx.py这种裸命令而是用IDE打开项目文件夹再运行这样工作目录自动定位到项目根目录。如果非要在终端跑先pwd看看当前路径再用cd切到源码目录。5.2 结果每次跑都不一样random_state到底设在哪现象同一个main_RFR.py跑了两次R2、RMSE、预测曲线全变了。原因RandomForestRegressor内部有随机性——每棵树采样的样本和特征都是随机的如果你没固定random_state每次运行都会生成不同的随机森林。解决确认模型初始化时写了random_state42或任意固定整数同时检查train_test_split函数是否也设置了random_state只要这两处有一个漏了结果就会漂移。我一般会在模型和数据集划分两处都固定种子这是让实验结果可复现的底线。我遇到过最隐蔽的翻车场景是代码本身没问题但操作系统按ASCII码排序文件data_all.csv被另一个同名前缀覆盖导致模型输入数据变了。排查半天才发现是上一个实验的脚本把csv覆盖了。从那以后我每次跑实验前都会先核对csv的行数和读取时间戳这个习惯救了我不止一次。5.3 训练分数极高但预测无效大概率是特征泄漏现象训练集上R2高达0.98但测试集R2只有0.05预测线接近水平。原因X里包含了未来信息。最常见的是把close列和label_close同时放进特征而label_close本身就是未来收盘价模型直接照抄答案自然“训练无敌、测试翻车”。还有一个问题是使用了全局标准化而不是在训练集上拟合scaler导致测试集信息混入。解决先检查特征列和目标列有无重叠比如label_close不能出现在X里。其次做标准化时必须先scaler.fit(X_train)再transform(X_test)不能用全量数据fit。检查完这两点这个症状基本能消除九成。注意data_all.csv本身是作者处理好的数据按道理不会有这种低级错误但你不能保证自己扩展数据集时不会犯。这也是为什么我建议你把特征构造代码单独封装成函数每次加新特征都走同一个入口而不是在模型训练前临时拼特征。5.4 图能出但中文乱码matplotlib字体问题现象图表标题或图例里的中文显示为方框。原因matplotlib默认字体库不包含中文字符。解决在画图之前强制指定中文字体plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False第一行指定SimHei黑体作为默认无衬线字体第二行让负号正常显示。如果你用的不是Windows系统需要把SimHei换成你系统里已有的中文字体名比如macOS可以用PingFang SC或Arial Unicode MS。不设置这两行中文乱码不会影响模型指标但在答辩PPT里会显得很不专业。6. 把main_RFR_all.py用起来多股票批量预测的参数调整套路如果你已经把单股票版本的流程摸透再去看main_RFR_all.py会觉得整个世界突然开阔了——它把单股票预测逻辑套了一层循环遍历多只股票的数据各自独立训练、独立预测。这意味着你可以在不修改核心算法的情况下把同一个模型框架复用到十几只股票上用一份代码跑出一整套对比结果这在课程设计报告里是非常好的素材一张表列出每只股票的RMSE和方向准确率导师会觉得你的工作“有广度”。用这个文件时要改的核心参数有两个第一个是股票列表通常在文件开头有一个stocks [000001, 600000]之类的字符串列表把你要预测的股票代码塞进去就好第二个是每只股票的数据读取路径有的版本会把csv按股票代码命名组织在文件夹里你需要确保所有csv文件都在同一目录。需要注意main_RFR_all_2.py这个文件是作者的变体版本我读了它的逻辑后判断它和all版本的主要差异在特征拼接方式上比如all把成交量变化率作为额外特征而all_2版本可能侧重于滑动窗口均值。如果你不想深究用main_RFR_all.py足够完成多股票实验。还有一个进阶技巧值得多说两句把随机森林预测结果和简单的历史均值基线做对比。基线预测就是“明天的涨跌幅等于过去20天的平均涨跌幅”如果随机森林连这个简单策略都打不过说明特征工程还需要加强。我在帮A同学做这个对比时顺手写了个函数把两种预测画在一张图里他说这个对比图导师看了很久最后在评语里特意提了“模型性能评估扎实”。所以我真心建议你不管时间多紧都要留出半小时做一个baseline对比这是花最少时间、拿最多印象分的操作。整个项目跑通之后你应该把所有需要的文件集中在一个干净的输出目录pred_compare.png、residual.png、模型指标打印结果全部保留好答辩时直接把图片插入报告比现场跑代码可靠得多。当然前提是你赋予这些图表真实的意义——它们不是什么被包装出来的“高分”而是一条从数据清洗、特征构造、模型训练到性能评估的完整链条你能讲清楚每一环项目本身就是你的能力证明。希望这个拆解思路能帮到你祝你在课程设计或毕业设计里用这套股票预测框架交出满意的答卷。本文还有配套的精品资源点击获取