
简介高送转是A股市场中一种特殊的股利政策本质是所有者权益的内部调整并不直接改变公司价值却常引发股价异动。这种可观测的市场现象为数据挖掘提供了天然的研究场景。通过公开的财务指标、股本结构与行情数据结合机器学习分类模型可以构建一套高送转概率预测系统。其核心价值在于利用特征工程刻画公司的送转能力与意愿并通过时间序列划分、类别不平衡处理等手段避免未来函数与准确率陷阱。该方案在量化选股、财务因子研究及金融科技课程设计中具有广泛应用前景尤其适合作为毕业设计或入门金融数据挖掘的完整项目。本文围绕该主题详细拆解了从数据获取、清洗对齐、特征构造到LightGBM建模评估的完整链路帮助读者掌握金融数据挖掘项目的工程化落地方法。 做这类项目有一个特别反直觉的现象高送转本质上是把股本拆细、把资本公积转成股本股东权益总额一分钱没变但市场就是愿意为它买单。公告一出股价常有明显反应。这种“明知道不改变价值、却总有人抢跑”的题材恰恰是数据挖掘最好的练兵场。这篇文章要拆解的就是一套完整的“基于数据挖掘的上市公司高送转预测”Python项目包括源码设计思路、数据链路、特征工程、模型实验和文档整理方案。它特别适合正在做课程设计、毕业设计或者想入门金融数据挖掘的人参考我自己当时跑通这个项目后最大的感受是这个选题的完成度上限很高但坑也比想象中多。1. 高送转预测这个选题凭什么值得做成数据挖掘项目1.1 高送转的基本逻辑与市场关注度高送转的全称是“高比例送转股”指的是上市公司在分红方案里同时采用“送红股”和“资本公积转增股本”两种方式而且送转比例比较高。比如“10送5转5”就是每持有10股额外获得5股红股和5股转增股合计变成20股。从会计角度看送红股用的是未分配利润转增股本用的是资本公积都是所有者权益内部科目的腾挪企业实际资产和经营能力没有任何变化。但A股市场的交易者长期以来把它解读成“公司对未来业绩有信心”的信号加上除权后股价变低、散户参与门槛降低很容易形成抢权行情。这种非理性的市场行为越是持久就越值得用数据去建模和分析。对数据挖掘项目来说这个方向有一个其他选题很难替代的优点每一年都有清晰的结果标签。哪家公司公告高送转、哪家没有公告日期和送转比例全部公开可查建模之后可以直接验证预测准不准。这种“结果可验证”的属性在数据分析类课题里特别珍贵。1.2 为什么这个方向天然适合数据挖掘一个选题适不适合做数据挖掘要看三个条件有没有明确标签、有没有可获取的特征、有没有业务逻辑可讲。高送转预测三条全占。标签方面只要拿到上市公司分红送转预案就能算出每只股票对应报告期的送转比例然后按阈值切分成“高送转”和“非高送转”二分类标签。特征方面公司的财务数据、股本结构、股价水平、上市年限、历史送转习惯全是公开数据接口直接能拉。业务逻辑方面高送转背后有明确的“能力意愿”驱动有能力是指账上有足够的资本公积和未分配利润有意愿是指公司股本偏小、股价偏高、有扩张动机。这套逻辑不依赖内幕信息纯粹从公开数据出发既符合学术规范也便于答辩时讲清楚。1.3 项目适用范围与前置基础这个项目方案适合三类人。第一类是数据挖掘或金融科技方向的本科生需要做一个完整度较高的课程设计或毕业设计第二类是准备保研、考研复试的学生想通过一个能落地的金融数据项目展示编程和建模能力第三类是刚开始接触量化选股的人想理解财务因子如何与机器学习模型结合。前置基础不高会Python基础语法、了解pandas和sklearn的基本用法、能看懂分类模型评价指标就够了。金融知识反而不用太深高送转的会计逻辑半小时能搞明白真正花时间的是数据清洗和特征设计。顺便说一句项目内所有分析和代码仅用于学习研究不构成任何投资建议。做这类课题最重要的是理解数据链路和建模方法而不是用它指导实盘操作。2. 数据获取与清洗把财报和行情数据改造成训练样本2.1 数据源选型Tushare、AkShare还是Wind训练数据从哪里来是这个项目第一个需要决策的点。我实际对比过三条路各有取舍。Tushare Pro是学生项目里用得最多的。注册后申请token积分达到一定门槛就能调用财务指标、每日行情、股本变动等接口。优点是数据结构规范、字段说明完善社区里对应的教程也多缺点是部分接口有积分限制新注册账号积分不够时需要先完成一些积分任务或者等几天才能调全量历史数据。AkShare是完全免费的开源库接口数量非常多数据来自公开网页爬取。优点是零门槛、不需要token缺点是个别接口会随网页结构变动而失效今天能跑通的代码过两周可能要改。如果项目周期短、只需要一次性跑通AkShare完全可以作为备选。Wind / Choice这类商业终端数据质量最好但学生很难拿到license接口调用也需要在特定环境里操作不适合作为课程设计的主数据源。我的建议是优先用Tushare Pro如果积分不够就用AkShare兜底。关键是把数据拉取这一层封装成独立模块后续换数据源时不用改特征工程代码。2.2 标签定义什么才算“高送转”高送转不是一个严格的会计术语每个研究机构口径略有不同。我采用的方案是以“每10股送转股数合计”作为核心指标送转股数 送红股数 转增股数合计大于等于5的标记为高送转否则为非高送转。为什么定5而不是10因为近年的市场环境下能达到“10送转10”的公司数量已经很少把阈值定太高会导致正样本极其稀疏模型基本学不到有效模式。定5能在“样本数量”和“业务含义”之间取得相对平衡。标签生成时要注意两个细节。第一送转数据只能看“分红送转预案公告”不能用最终实施方案因为中间可能调整第二同一家公司一年可能公告两次年报和中报每条样本要用“报告期”区分开避免把两期数据混成一条。import pandas as pd def make_label(div_df: pd.DataFrame, threshold: float 5.0) - pd.DataFrame: # div_df 至少包含: ts_code, end_date, ann_date, send_share, transfer_share df div_df.copy() df[send_transfer_total] df[send_share].fillna(0) df[transfer_share].fillna(0) df[label] (df[send_transfer_total] threshold).astype(int) return df[[ts_code, end_date, ann_date, send_transfer_total, label]]2.3 清洗与对齐最容易被忽视的未来函数问题数据清洗这个环节表面上是处理缺失值和异常值实际上这个项目的关键难点在于“时间对齐”。说白了就是建模时必须确保用到的每一个特征在预测时间点上是“已经可知的”。最典型的坑是财务数据和公告日期的错位。年报数据虽然标注的是“报告期2023-12-31”但实际的年报公告日期往往是次年的三四月份。如果你用“报告期”直接和股价数据拼接就会把未来才披露的数据用到过去的样本上造成严重的“未来函数”偏差。这种数据泄露不会报错但会让训练阶段指标非常好看真实场景一验证就原形毕露。我在项目里用了一个笨但有效的对齐策略每条样本使用上一报告期的财务数据而不是当前报告期。比如预测某公司2024年中报是否会高送转训练特征只能用2023年年报以及更早的数据绝对不碰2024年的任何财务字段。这样从数据结构上就杜绝了未来函数。清洗流程本身也建议按顺序来先剔除ST、*ST股票这类公司高送转概率极低且财务数据异常再剔除上市不满一年的次新股次新股没有完整的财务历史且送转规则和普通公司不同然后做缺失值处理字段缺失超过30%的直接删掉单条样本缺失则用行业均值填充最后用分位数截断消除极端值财务数据的量纲差异大必须缩尾后再进入模型。3. 特征工程的设计逻辑从财务动机反推预测因子3.1 高送转公司的四个共同画像特征工程不是把能拿到的字段一股脑塞进模型而是要站在“公司为什么愿意高送转”的角度反推。我做调研时梳理了一批历年高送转公司的特征发现它们有明显的共性可以归纳成四句话账上有钱、股本偏小、股价偏高、业绩兜底。账上有钱指的是资本公积和未分配利润充足这是送转的“弹药库”股本偏小意味着公司有做大体量的扩张需求大公司股本已经很大再送转的意义不大股价偏高会提高散户参与门槛公司有通过除权降低股价的动机业绩兜底说的是公司会评估自己的盈利能力和成长性太差的话送转容易引发监管问询和市场质疑。这四句话基本决定了特征体系的结构。3.2 四类特征体系能力、意愿、业绩与市场情绪围绕上述画像我把特征分成四组。第一组是“高送转能力”类包括每股资本公积、每股未分配利润、资本公积占净资产比例、未分配利润占净资产比例。第二组是“高送转意愿”类包括总股本、流通股本、最新股价、上市年限、上一报告期是否实施过高送转。第三组是“业绩与成长性”类包括每股收益、净资产收益率、营业收入同比增速、净利润同比增速、经营现金流。第四组是“市场因素”类包括总市值、近60日换手率、近60日涨跌幅。这里有个容易被忽略的细节送转能力类特征必须除以股本不能用资本公积总额。因为同样是5亿元资本公积对10亿股本和1亿股本的公司意义完全不同。用“每股资本公积”这类相对指标才能公平比较不同规模的公司。3.3 特征处理细节极值、标准化与相关性筛选原始财务特征基本都有两个毛病量纲差异大、极端值多。以每股资本公积为例多数公司集中在0到3之间但少数公司会因为历史股本操作冲到10以上。如果不做处理树模型可能被极端值带偏线性模型更是直接崩掉。我在项目里做了三步处理。第一步对每个连续型特征做分位数缩尾小于1%分位数的按1%分位数替换大于99%分位数的按99%分位数替换把极端值拉回来。第二步对偏态明显的特征做log1p变换比如总股本、总市值这类跨度几个数量级的字段取对数后分布更接近正态。第三步计算特征间的皮尔逊相关系数相关性超过0.85的保留其中一个比如“总股本”和“流通股本”高度相关保留一个就够。这些处理做完后特征数量大概在20个左右。我个人不推荐再加更多特征因为财务数据本身噪声大特征越多越容易过拟合而且答辩时解释起来也费劲。把20个特征背后的业务逻辑讲清楚比堆80个特征更有说服力。4. 模型训练与“未来函数”陷阱类别不平衡是最大的坑4.1 数据集划分为什么不能直接随机K折很多人在模型阶段犯的第一个错误就是用sklearn默认的train_test_split随机划分数据或者用KFold交叉验证。这在普通机器学习项目里没问题但在高送转预测里会直接导致数据泄露。原因很简单高送转预测本质是时间序列上的事件预测2018年的样本和2023年的样本不是独立的。如果随机划分训练集里会出现“用2022年信息学到的规律”去预测2019年样本的情况相当于测试集里混进了未来信息。正确的做法是按时点划分比如用2015到2021年的数据做训练集2021到2023年的数据做测试集模拟真实的“用历史预测未来”。我实际测试过随机划分的测试集AUC能到0.85以上但按时点切分的真实AUC通常在0.72到0.78之间。这个差距不是模型能力问题而是数据划分方式造成的虚假高估。答辩时把这一点讲出来是很大的加分项。4.2 类别不平衡准确率虚高的真相高送转样本的比例有多低全市场一年公告高送转的公司大约200到300家而A股上市公司超过5000家正样本比例大概5%左右。在这样的数据上训练模型即使模型什么都不学、一律预测“不高送转”准确率也有95%。所以准确率这个指标在这个项目里基本没有意义。很多初学者看到自己模型准确率95%就以为成功了实际上是被类别不平衡骗了。我在项目文档里专门加了一节“为什么不用准确率评价模型”把这个问题讲透要看AUC、F1值或者更贴近业务场景的TopN命中率。4.3 模型选型与评价指标本质是TopN召回问题高送转预测的实际应用场景不是把所有股票精确分成两类而是“从几千只股票里挑出最有可能的几十只”。所以我在项目里把它定义成一个排序问题对测试集每只股票输出预测概率按概率从高到低排序看排名前50名的命中率以及前100名的命中率。模型选择上我对比了逻辑回归、随机森林和LightGBM最终采用LightGBM作为主力模型。原因有三个训练速度快、自带类别不平衡处理参数、特征重要性可以反哺特征工程。逻辑回归保留作为baseline用来证明树模型的提升幅度。类别不平衡的解决方式我用了两种并对比效果。第一种是Tushare拉到的样本里直接设置样本权重让正样本权重等于负样本数除以正样本数第二种是用SMOTE做少数类过采样。实测下来LightGBM自带的is_unbalanceTrue参数在这个场景比SMOTE更稳因为SMOTE会在少数类之间插值生成新样本但财务特征的插值样本可能并不真实反而引入噪声。评价指标我固定为三个AUC、Top50命中率、Top100命中率。代码如下import lightgbm as lgb # 按时点切分训练集和测试集 train_df df[df[ann_date] 2022-01-01] test_df df[(df[ann_date] 2022-01-01) (df[ann_date] 2023-01-01)] lgb_params { objective: binary, learning_rate: 0.05, num_leaves: 31, max_depth: -1, is_unbalance: True, verbose: -1, seed: 42, } lgb_train lgb.Dataset(train_df[feature_cols], train_df[label]) model lgb.train(lgb_params, lgb_train, num_boost_round300) test_df[prob] model.predict(test_df[feature_cols]) # TopN命中率 top50 test_df.sort_values(prob, ascendingFalse).head(50) top100 test_df.sort_values(prob, ascendingFalse).head(100) print(fAUC: {roc_auc_score(test_df[label], test_df[prob]):.4f}) print(fTop50命中率: {top50[label].mean():.2%}) print(fTop100命中率: {top100[label].mean():.2%})4.4 特征重要性的反哺模型训练完之后不要急着写结论先看一眼LightGBM输出的feature importance。这一步经常能发现特征工程里的问题。我在跑第一版模型时重要性排名第一的是“上一报告期是否实施过高送转”其次是“每股资本公积”和“每股未分配利润”。这说明模型的判断逻辑和业务逻辑高度一致有历史送转习惯的公司、账上有充足公积金的公司确实更容易再次高送转。而“近60日涨跌幅”重要性排倒数说明市场情绪类特征对预测几乎没有贡献原因可能是市场已经在公告前price in了一部分信息。根据这个结果我把情绪类特征精简掉只保留市值和换手率特征数量从24个降到19个AUC反而小幅提升。这就是特征重要性反哺特征工程的价值用模型结果验证特征假设砍掉无效特征既提升泛化能力也简化答辩叙述。5. 源码结构、运行流程与核心代码解读5.1 项目目录结构拿到源码后第一件事不是急着运行而是先看懂目录结构。一套结构清晰的项目代码能不能一键跑通是次要的先让读者明白“每个文件是干什么的”更重要。我设计的目录如下gaosongzhuan/ ├── data/ │ ├── raw/ # 原始数据从接口拉下来后的落盘文件 │ └── processed/ # 清洗和特征构建后的中间数据 ├── src/ │ ├── data_fetcher.py # 数据拉取封装Tushare/AkShare接口 │ ├── build_features.py # 特征构建输入原始数据输出特征表 │ ├── train.py # 模型训练与评估 │ ├── predict.py # 加载模型预测新一期样本 │ └── utils.py # 通用工具函数 ├── docs/ │ ├── 项目说明.md # 完整文档说明 │ └── 答辩讲稿.md # 答辩思路与话术 ├── config.yaml # 配置文件token、路径、参数 ├── requirements.txt # 依赖包列表 └── README.md # 快速上手指南这个结构的好处是“数据、特征、模型、文档”完全隔离。改特征不用动模型代码换数据源不用动特征代码答辩时按模块逐个讲也特别顺。5.2 运行环境与完整流程运行环境建议Python 3.9以上核心依赖是pandas、numpy、scikit-learn、lightgbm、PyYAML。如果数据用Tushare再加一个tushare包如果用AkShare就把data_fetcher里的实现换掉。完整的运行流程分四步在config.yaml里填入数据接口的token配置好数据起止日期。运行data_fetcher.py拉取原始数据落盘到data/raw目录。运行build_features.py生成特征表落盘到data/processed目录。运行train.py完成训练和评估输出指标和预测结果表。每一步都建议加日志输出打印当前处理到哪一步、处理了多少条样本。这个习惯在调bug时能节省大量时间。5.3 关键代码片段解读整个项目里最核心的代码有三段标签生成、特征拼接和训练评估。标签生成的代码前面已经写过了这里重点说特征拼接和训练评估里容易出错的地方。特征拼接时最容易出的问题是索引错位。财务数据、行情数据、标签数据来自不同接口索引结构完全不同。我在代码里统一用ts_code end_date作为主键先把三张表各自处理好再按主键做merge。merge之后立刻检查行数有没有异常如果和预期差异超过5%说明主键有问题需要停下来排查。def build_feature_table(fin_df, market_df, label_df): # 统一主键: ts_code end_date df fin_df.merge(label_df, on[ts_code, end_date], howinner) df df.merge(market_df, on[ts_code], howleft) # 检查样本量是否符合预期 if len(df) len(label_df) * 0.95: raise ValueError(特征拼接后样本量异常请检查主键是否对齐) return df训练评估的代码前面给过LightGBM版本了有一个细节要补充特征列必须在训练和预测时保持一致。很多人在训练时用了20个特征预测时DataFrame里少了一列模型直接报错。更隐蔽的问题是特征顺序不一致树模型对顺序不敏感所以没事但如果换成线性模型就会出错。我在predict.py里用model.feature_name()强制对齐特征顺序从根本上避免这个问题。6. 文档说明与答辩材料怎么写才能撑起“高分项目”四字6.1 高分文档的七段式结构项目源码只是载体真正决定评分上限的往往是文档。我见过不少代码能力不错但文档一塌糊涂的项目最后评分反而不如代码一般但讲得清楚的项目。针对这个选题我建议文档按七段式结构写选题背景与研究意义——讲高送转的市场现象以及用数据挖掘预测它的价值。数据来源与预处理——把数据源、拉取范围、清洗规则、时间对齐方案写清楚。特征工程——每个特征为什么入选、背后对应什么业务逻辑。模型设计与实验——模型选型、参数设置、训练集/测试集划分方式。实验结果分析——AUC、TopN命中率、特征重要性排序。项目局限性——哪些因素可能导致预测偏差比如公司可能因为监管环境变化调整送转策略。改进方向——引入舆情数据、公告文本分析、更细粒度的财务预测等。每一段都要配上表和代码不能只有文字描述。6.2 答辩时最容易加分的三个细节做这个项目时有三个细节如果能在文档或答辩PPT里体现出来评委的观感会明显不一样。第一个是时间序列划分的说明。主动讲“我没有用随机划分因为高送转预测是按时间演进的随机划分会引入未来信息”一句话就能体现你理解数据泄露的问题。第二个是类别不平衡处理的对比。把“不做处理”和“设置样本权重”后的AUC差异列成一张表展示动手实验的过程比直接说“我用了is_unbalance参数”更有说服力。第三个是TopN命中率的业务解释。说明“实际应用中就是挑出概率最高的50只股票看里面有多少只真的高送转”这能让评委理解你不是在刷指标而是真的思考过业务落地场景。6.3 数据与模型的局限性怎么写才不翻车写局限性这一节很多人容易犯两个错误要么避而不谈要么过度谦虚把所有问题都归为“能力不足”。正确的写法是“客观陈述限制条件并提出可行的改进路径”。我在文档里写了三点局限性。第一高送转比例本身受市场环境影响监管口径变化会直接影响高送转公司数量模型在新环境下的稳定性需要进一步验证。第二部分潜在高送转公司在预案公告前会释放业绩预告等信息这些事件型特征没有被纳入。第三正样本数量有限尤其是送转比例特别高的“极端高送转”样本更少模型对尾部样本的区分能力仍然不足。这三点写得越具体越证明你认真思考过项目边界而不是只把代码跑通就结束了。个人经验是做这类金融数据挖掘项目真正拉开差距的不是模型精度而是数据链路的严谨程度。未来函数检查、按时间切分、类别不平衡处理这三件事做到位项目就已经超过大多数同类作业了。最后再分享一个小技巧——把预测结果做成Excel表格按概率从高到低排序标出公司代码、名称、预测概率、是否实际公告高送转导师或评委一看就懂比自己对着屏幕念指标有用得多。本文还有配套的精品资源点击获取