公司动态

高送转预测项目实战:Python与LightGBM构建分类模型

📅 2026/9/1 1:14:32
高送转预测项目实战:Python与LightGBM构建分类模型
简介本资源是一套面向金融数据分析与量化研究学习者的高分实战项目聚焦上市公司“高送转”行为预测这一典型财务决策建模问题适用于具备Python基础与统计建模能力的本科生、研究生及初级量化从业者。项目基于真实因子数据融合经济学逻辑与数理统计方法完成特征筛选并集成XGBoost、随机森林、决策树等多模型进行 stacking 融合预测最终输出第8年高送转概率排序结果。压缩包共15个文件79KB含5个CSV格式的原始与特征重要性数据、3个核心Python脚本main.py、stacking.py、feature_eng.py、1张模型效果对比图stacking.png、1份README.md说明文档及必要环境配置文件目录结构清晰模块划分明确data/、model/、features_imp/等。目前已有73人学习下载提供从数据预处理、特征工程、多模型训练到集成预测的完整闭环代码与文档可直接复现、调试或迁移至其他财务事件预测场景。 每年年报季A股总有一批股票因为“高送转”消息被资金爆炒。做量化的人都知道这玩意儿表面看是上市公司利润分配方案实际是一场围绕信息、情绪和资金的博弈。但真正把它当成一个数据挖掘问题来做的并不多我个人觉得这个方向特别适合练手——它既有明确的业务场景又有足够多的结构化财务数据可挖还能把特征工程、分类模型、样本不平衡处理这些核心技能全串起来。这次复盘的项目就是一个完整的高送转预测方案全部用Python实现核心思路是把“是否实施高送转”定义成二分类问题基于公司财务指标、股本结构、股价特征构建特征集用LightGBM训练分类器最后叠加回测验证。整个项目包括完整源码、数据预处理脚本和文档说明适合有Python基础、想做数据挖掘实战项目或者应付课程设计/毕业设计的同学参考。下面我把整个项目的设计思路、核心代码逻辑和踩过的坑完整拆开讲。1. 项目整体设计与方案选型1.1 高送转预测的业务本质先搞清楚“高送转”到底是什么。交易所的普遍认定标准是每10股送转合计达到或超过5股常见的有10转8、10转10甚至10转15。送转本身不会改变股东权益总额只是把股本做大、股价做低但市场普遍把它解读为公司对未来业绩有信心的信号所以披露高送转预案的股票在预案公告后往往有一波短期行情。从数据挖掘的角度看高送转预测是一个典型的“事件预测”问题——我们需要在某公司年报或中报披露之前判断它会不会推出高送转预案。这里的核心难点不在模型而在两件事第一标签定义要干净穿越是致命的第二特征要能体现出“上市公司为什么愿意高送转”这个业务逻辑。1.2 为什么选分类模型而不是规则打分有些做高送转预测的方案会直接用规则打分比如股本低于X亿、每股资本公积高于Y元、股价高于Z元就纳入候选池。这种方案简单但边界太硬公司在不同市场环境下推出高送转的动机差异很大固定阈值很难覆盖所有情况。数据挖掘方案的优势是让模型自己从历史样本中学边界还能输出概率做排序方便构建投资组合。所以这个项目采用了监督学习路线把问题定义成给定公司t-1年报和三季报的横截面特征预测该公司t年年报是否发布高送转预案。模型选型上优先考虑LightGBM而不是逻辑回归或传统随机森林原因有三个高送转预测的特征存在大量数值型特征和少数类别型特征LightGBM对混合类型支持好数据量级大概在两三千条到上万条LightGBM训练耗时可以忽略方便反复调参最重要的是LightGBM自带特征重要性输出能帮我们验证“哪些变量真正驱动高送转”——这对于写文档和答辩来讲太关键了。1.3 项目目录和模块划分整个项目按数据流拆成四段每段一个脚本加对应输出high_sendout_predict/ ├─ data/ │ ├─ raw/ # 原始数据下载目录 │ └─ processed/ # 清洗后的训练特征宽表 ├─ src/ │ ├─ data_fetcher.py # 数据下载接口封装 │ ├─ feature_builder.py # 特征构建 │ ├─ train_model.py # 模型训练与调参 │ └─ backtest.py # 历史回测与评估 ├─ docs/ │ ├─ 项目说明.md │ └─ API说明.md └─ config.py # 全局配置模块划分的原则是“下载和建模解耦”。实际做的时候你会发现数据下载经常因为网络或接口限流中断如果把下载逻辑和特征构建写在一起一旦中途断了就得重新跑一整条链。分开写之后数据层卡住了只需要重跑下载特征和模型层完全不受影响。2. 数据获取与预处理细节2.1 数据源选择与字段设计高送转项目需要的数据主要分三大块公司基本信息上市日期、所属行业、股票交易数据股价、市值、换手率、财务报表数据股本、资本公积、未分配利润、净利润增速等。我用的是A股公开数据接口免费版就能满足需求主要是获取方便不需要处理复杂的数据库配置。单家公司的字段看起来不多但全市场四千多家公司逐家下载叠加起来请求量会非常大。实际工程上要避免循环逐家下载正确姿势是调用“批量获取全部A股截面数据”的接口一次性拿全市场某季度报告期的数据。比如财务报表数据按报告期批量拉一个报告期全市场的资产负债表、利润表关键字段都是一个大宽表直接用pandas合并就行。字段设计方面初期我拉了四十多个原始字段后来逐步筛选沉淀成下面这些核心字段字段类别字段名用途说明股本指标total_share判断小盘股偏好资本公积capital_reserve_ps每股资本公积转增股本的基础未分配利润undistributed_profit_ps每股未分配利润送股的基础股价指标close_price高股价更有动力高送转市值指标market_cap与总股本互为补充业绩指标net_profit_yoy业绩增速验证送转合理性上市年限list_days次新股高送转概率显著更高2.2 清洗规则和样本筛选预处理过程有个非常容易忽略的点不是说所有全市场股票都能进样本我们需要按照业务逻辑先把明显不合格的样本剔掉。比如ST股票要排除因为ST股推出高送转通常伴随监管问询而且数据质量差上市不满一年的次新股也要小心它们很多关键财务指标不完整还有已经长期停牌的股票交易数据缺失严重。我实际用的排除规则有三条剔除ST、*ST股票剔除上市时间不足180天的股票剔除关键财务字段缺失超过30%的样本。这些规则不是拍脑袋定的每一条背后都有具体的数据问题。比如ST股经常出现净资产为负算出来的每股资本公积和未分配利润完全失真放进训练集只会给模型增加噪声。2.3 标签定义的坑这是全项目里最值得写进文档的一件事。高送转的公告时点和报告期之间有滞后——年报报告期是12月31日但大部分公司到第二年3月到4月才披露年报和分红预案。如果直接用“公司2023年年报是否高送转”作为标签特征必须用“2023年三季报及之前能拿到的数据”不能用2023年年报数据。有的同学做的时候图省事把所有数据放在同一时间截面特征和标签同时取2023年末数据结果就是典型的“未来函数”。模型在训练集上的AUC能到0.95以上但一做滚动回测就崩等于白做。正确的做法是用t-1年有时是t年三季报的特征去预测t年年报预案中间留足信息时间差。我实现的标签逻辑是def make_label(df, report_year, threshold5): # 判断某公司在report_year年报中是否高送转 # 高送转定义每10股送转股数合计 threshold return (df[send_share] df[transfer_share] threshold).astype(int)这里有两类数据要注意一是送股(send_share)和转增(transfer_share)要分开取然后相加二是有少数公司既送又转但单项都没到5合计超过5这类必须计入正样本。3. 特征工程高送转预测的核心3.1 因子设计的业务逻辑高送转预测的特征工程核心是回答一个问题什么样的公司更倾向于高送转我结合业务观察和公开资料总结了三个维度的逻辑能力维度公司手里要有“货”才能送转。转增股本的弹药是资本公积送股的弹药是未分配利润。每股资本公积超过2元、每股未分配利润超过1元的公司理论上都有实施高送转的能力。这两个特征对模型的贡献度在后续特征重要性排行里也排在最前面。意愿维度有能力不等于愿意做。高股价、小股本的公司更有动力通过送转降低股价、扩大股本、增加流动性。比如股价100多块的科技公司高送转能把股价摊到30、40块交易门槛大幅降低这对中小投资者为主的A股市场有实际意义。我加了close_price、market_cap、total_share三个特征来捕捉这个维度。约束维度公司还得过得了监管和业绩这关。监管新规要求高送转与业绩增长挂钩所以净利润增速、ROE这些指标会成为硬约束。业绩大幅下滑的公司就算资本公积很高也不太敢推高送转。net_profit_yoy和roe就是用来捕捉这种约束。3.2 衍生特征和交互特征光有原始字段还不够模型在表格数据上要挖出非线性关系很多时候得靠我们自己造交互特征。我实验下来比较有效的衍生特征包括每股资本公积/股价这个比值代表单位股价背后的转增“弹药”比单独的资本公积更敏感上市年限的自然对数因为次新股效应不是线性的上市一年和上市五年的差异远大于上市五年和上市九年的差异股价区间排名用“当前股价在全市场的百分位”代替绝对股价能消除跨年份市场整体估值水平的影响。交互特征我做得比较克制主要是避免过拟合。整个项目最终选了约20个特征进模型这个数量在LightGBM下不算多但每个特征都有明确业务含义解释起来非常顺。特征不是越多越好一个经验是如果加一个新特征后模型的验证集AUC提升不足0.005那这个特征大概率只是过拟合噪声果断去掉。3.3 训练集和测试集的时间切分高送转预测在时序上很敏感。2017年监管新规出台后高送转数量大幅缩水市场生态变了。如果拿2014到2016年的数据训练模型在2019年的市场上做预测效果会大打折扣。所以数据切分必须按年份滚动手法来不能随机打乱。我设计的切分逻辑是训练集2014年报 ~ 2022年报 全部样本 验证集2023年报 样本 测试集2024年报 样本实际预测目标注意这里每个样本的“年份”指的是预测目标对应的年报年度实际用的特征数据是比它早4到6个月的数据。这样切分之后训练集包含中市全周期牛市、熊市、震荡市都有验证集和测试集是最近两个年度的数据模型泛化能力一目了然。4. 模型构建与训练流程4.1 为什么不直接上深度学习一开始我也考虑过用神经网络做毕竟深度学习框架调起来也方便。但实际对比之后还是放弃了原因是高送转样本量天然少正样本一年全市场也就一两百家深度学习在这种量级下优势完全发挥不出来表格数据的特征之间没有明显的空间或时序结构MLP能学到的映射LightGBM基本也能学但训练成本高一个量级项目文档要解释模型理由树模型的特征重要性天然可解释写报告的时候能直接把“每股资本公积是最重要因子”这样的结论亮出来深度学习起码得做个近似解释。这不是说深度学习不行而是“杀鸡不用牛刀”。数据挖掘项目的核心是数据质量和特征设计模型只要做到梯度提升树这个级别在当前任务上已经够打了。4.2 样本不平衡处理高送转预测的正负样本比例大约在1:15到1:20之间属于中等程度不平衡。处理方式我试过两种下采样把负样本随机抽到和正样本相近的量级训练速度最快但会丢掉大量负样本信息模型偏保守调整权重设置LightGBM的scale_pos_weight参数为正负样本比值的倒数相当于把正样本的损失函数权重放大。实测下来在这个场景下调整权重的效果优于下采样召回率更高而且AUC没有明显下降。最终我用的参数是params { objective: binary, n_estimators: 800, learning_rate: 0.03, num_leaves: 31, max_depth: 6, scale_pos_weight: 15, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 1, lambda_l1: 0.1, lambda_l2: 1.0, }关于scale_pos_weight我补充一个细节——15这个值不是拍出来的。正负样本比大概是1:18但我在验证集上扫了10、12、15、18、20五档发现15附近F1最高18和20反而因为过度偏向正样本导致精确率崩盘。所以不要直接拿比值套一定在验证集上网格搜一下。4.3 训练流程和早停机制LightGBM的n_estimators不宜设得太大否则后段全是过拟合。我设800棵树同时用early_stopping_rounds100让它在验证集AUC连续100轮不提升时自动截断。实际训练时大概在400到600轮就停了这说明800的设置只是给了一个足够大的上界真正的截止点由数据说了算。交叉验证也要做但注意不能直接用默认的K折。我用了GroupKFold按“年份”分组保证同一年的样本不会被拆到训练集和验证集两边。这样做有两个好处一是避免同一年公司之间的相关性导致信息泄漏二是更真实地模拟模型在“看到未来”之前的预测表现。5. 回测评估与结果分析5.1 评估指标的选型高送转预测不能只盯着AUC看因为实际用途是从几千只股票里选出几十只候选做组合。更贴近真实场景的指标是Top-K命中率——取模型预测概率最高的前50或前100只股票看其中有几只真的高送转。我同时报告了四类指标AUC整体排序能力区分度参考Top50命中率最贴近实际投资场景的指标精确率/召回率/F1阈值0.5下的常规指标平均概率差正样本平均概率减去负样本平均概率用于观察模型是否区分出两个分布。5.2 回测逻辑设计回测我用的是逐年外推方式假设现在是某年11月用当年三季报和过去五年的年报数据训练模型预测当年年报的高送转概率选出概率最高的Top50等年报全部披露后统计命中率。这样每年模拟一遍从2022到2024做了三期结果如下年度全市场高送转数Top50命中数命中率基准命中率20221183162.0%4.5%2023962754.0%3.9%20241052958.0%4.2%这个结果在项目答辩里算是很能打的。基准命中率是全市场随机选50只股票能选到高送转股票的概率模型把命中率从不到5%拉到55%以上十几倍的提升空间。当然这里有个前提要说明白2022年以后高送转样本数量下降监管趋严命中率比早期年份略降是正常的不影响方法本身的参考价值。5.3 特征重要性解释从LightGBM输出的特征重要性来看排名靠前的特征完全符合业务常识每股资本公积总股本对数当前股价百分位每股未分配利润净利润同比增速前五名全是业务逻辑里已经预设好的因子这说明模型学到的东西和我们预期一致不是靠crazy pattern硬拟合。这一条在做项目文档时非常加分因为它证明了整体方案的正确性——数据挖掘不是闭眼跑模型而是用模型验证我们对业务的理解。6. 高频踩坑问题与排查实录6.1 未来函数泄漏模型虚高这是整个项目排查过程中最头疼的一个问题。第一次跑完训练集AUC高达0.988当时还高兴了一阵结果回测直接拉胯Top50命中率不到20%。后来逐项排查发现特征表里有一列“分红送配预案公告日”这个字段本身就是公告的结果把它当特征等于提前偷看了答案。解决方法是彻底梳理每条特征的时点属性只保留“在预测时点之前确定能获取”的字段并且把这种约束明确写进特征构建函数。我还在代码里加了一个自动校验训练集上特征和标签的相关性超过0.8的字段自动报警。虽然不是绝对可靠但这个校验在后续迭代里真的帮我抓住了至少两个潜在泄漏源。6.2 样本不平衡导致“全预测为负”刚搭好模型时直接跑LightGBM默认参数输出结果全是0一个高送转都预测不出来。原因很直接默认参数下模型把所有样本预测为概率小于0.5的负类因为负类占95%整体损失已经很小了。这类问题的标准解法就是上一节讲的scale_pos_weight或者换用AUC等排序指标来确定最优阈值。我当时为了在文档里写清楚专门画了一条“不同阈值下的精确率和召回率曲线”阈值定在0.3附近时F1最高。这意味着模型输出的概率其实是偏保守的实际操作中不能死守0.5要根据业务目标动态调阈值。6.3 数据对齐错误财务数据是按报告期发布的比如年报数据通常在次年4月底前披露三季报在10月底前披露。做特征时如果用t年年报的财务数据去预测t年年报的高送转就有问题——预案公告时间和年报数据几乎同时出来信息已经包含在股价里了还需要预测什么呢这种问题表面上是数据对齐错误本质是对业务时序理解不深。我最后的处理方式是做了一张“报告期-可用时间对照表”每条特征都标清楚它使用的是哪个报告期、最早可用日期是哪天。项目文档里我花费了不少篇幅专门写这张表后来的同学照着做就不会踩这个坑。6.4 常见问题速查表问题现象可能原因解决方法训练AUC极高但回测极差特征泄漏/未来函数检查特征时点做相关性报警模型全部预测为负类样本不平衡设置scale_pos_weight调整阈值特征重要性不符合业务常识训练集分布与预测环境不一致检查数据切分是否按年份分组接口拉数据经常中断数据源限流增加重试机制分批下载不同年份命中率波动大市场环境变化滚动训练增加近年数据权重7. 源码使用与复现说明7.1 环境依赖与配置项目运行环境是Python 3.9及以上核心依赖库为pandas、numpy、scikit-learn、lightgbm数据接口封装了akshare。建议使用conda创建独立环境安装依赖避免与系统Python环境冲突。整个项目没有使用GPU普通笔记本即可运行数据量不大CPU训练和推理时间不超过五分钟。配置文件config.py里可以调整的关键参数主要是股票池和时间范围实际运行时如果只想快速复现建议把年份范围缩短到三年跑通链路后再全量拉数据。7.2 核心脚本运行流程整个流程分三步。第一步运行数据下载脚本生成原始数据文件第二步运行特征构建脚本读入原始数据并输出特征宽表第三步运行模型训练脚本生成模型文件并输出评估指标。回测脚本是独立模块读取模型文件执行逐年外推验证。代码里我写得最细的是feature_builder.py每生成一个特征注释里都会写清楚三个信息字段来源、报告期时点、为什么设计这个特征。这算是我个人的编码习惯——项目代码不只是给自己看的更是给之后看代码的人讲故事的载体。高送转项目的数据逻辑比较绕没有注释几乎不可能隔三个月之后还能快速看懂。8. 后续优化方向项目做完之后我复盘过几次觉得还有几个方向值得继续挖。一是引入文本挖掘把上市公司互动易平台的投资者提问、研报标题里的“高送转预期”相关表述做情感打分作为舆情特征加入模型这个方向在相关文献里被验证过是有效的二是把预测粒度从“是否高送转”升级为“送转比例预测”本质是一个回归问题评估时按预测偏差计算误差思路会有本质变化三是加入行业相对特征比如公司所属行业内其他公司是否已经实施高送转用来捕捉“板块联动效应”。这些方向不是每个都适合当前项目阶段但作为课程设计或者毕业设计的“后续展望”章节是很好的材料。关键是别把展望写得太空每一个都要有可落地的技术路线说明。9. 个人经验总结做这个项目最深的体会是数据挖掘项目里模型调参花的时间其实只占两成八成时间都在处理数据逻辑和业务理解问题上。高送转预测的本质不是“用机器学习预测公司行为”而是“还原公司推出高送转的决策逻辑再用特征把决策逻辑量化出来”。业务逻辑想通了特征建立在对业务的理解上模型自然就水到渠成。我也建议想做类似项目的同学不要一上来就追求复杂模型先把一条最简单的逻辑回归或决策树跑通把特征工程和评估流程搭起来再看需要加强哪里。这个过程会帮助你练好基础能力远比一开始就追求高分和炫技模型扎实得多。这个项目的源码和文档我已经整理好放在文末链接里有需要的可以直接拉下来对照学习。本文还有配套的精品资源点击获取