吃过晚饭回到房间,电脑屏幕因为长时间无操作已经进入了休眠。

    江临晃了一下鼠标,屏幕亮起,下载管理器里的进度条已经拉满。

    那个标着nute_rket_data_v3.zip ,大小足有3.4Gb的数据集,安静地躺在他的本地硬盘里。

    江临趁着解压的间隙看了看规则。

    平台那个UI极其简陋的任务说明页面上,规则写得很长,密密麻麻的一大篇免责条款和计分细则。

    数据禁止外传,允许使用公开算法,允许提交清洗后的异常标记文件、方法说明报告和辅助脚本等等。

    江临把几段规则复制下来,粘贴到本地新建的记事本里,然后用鼠标给其中三个词加了粗。

    隐藏标签,可复现性,泛化能力。

    这三个词,比那八千块钱奖金重要得多。

    它透露了主办方真正的痛点。

    他们不要那种在特定数据集上跑分很高,换个市场环境就彻底拉胯的比赛特供模型。

    他们要的是一条真正能落地的工业级清洗流水线。

    江临却看得眉头微皱。

    因为他熟悉的是坏数据,不是金融市场。

    温度传感器零点漂移、相机暗场噪声、光学支架热胀冷缩、辐射计被宇宙线打出异常尖峰,这些东西他处理过太多次。

    可是分钟级行情不是温度曲线,成交量不是传感器采样,停牌标记也不是设备掉线。

    如果连系统的基本工作方式都没弄清楚,就急着下手清洗数据,那不叫审计。

    那叫把自己的无知写进脚本里。

    江临把下载页面暂时放到一边,新建了一个文档。

    标题只有四个字:量化补课。

    目标:学习这些数据在什么制度和流程下产生。

    他先从最基础的字段开始查。

    开盘价,成交量,复权,涨跌停……

    每一个词他都只看最基础的定义,不往投资策略上发散。

    遇到讲十倍收益,稳定套利,资金曲线完美的帖子,直接关掉。

    遇到有人认真讨论未来函数,幸存者偏差,样本外失效,滑点和冲击成本的长帖,才停下来读。

    两个小时后,他列出了六个必须先确认的制度性问题,从集合竞价边界到测试集隔离方式,并在纸上画出一条很粗糙的数据链路。

    最后评价为:量化数据不是市场本身,是市场经过多层设备,制度,软件和商业口径之后留下的影子。

    这句话写完,他又下载了数据字典和平台提供的baseline(基准参考代码)。

    数据字典是一个二十多页的pdF文件。

    不得不说,提供方在脱敏上做得很绝。

    那个所谓的标的代码,根本不是什么诸如这种能在软件里搜出来的股票代码,而是被全部转成了一长串毫无规律的5哈希值。

    时间戳里的交易日(date_id)也做了整体偏移。你没法知道这是2015年股灾时的数据,还是2020年抱团行情时的数据。

    所有的价格和成交量也全都在后台做过了等比例缩放,绝对值已经失去现实含义,只保留了零值、缺失、相邻变化率以及同一口径下的相对关系。

    这意味着,你不可能靠现实世界的金融常识或者去查雅虎财经的历史记录,去反推哪一只股票在某年某月某日发生了什么异常。

    这很对江临的胃口。

    因为外部查资料的捷径被切断后,剩下的胜负就会回到数据内部的逻辑、制度边界和审计能力上。

    江临打开windows命令行窗口,在工程目录下建好了五个分类文件夹。

    解压数据集的压缩包。

    进度条走完后,data_raw 文件夹里出现了四个庞然大物。

    train_features.parquet,train_labels.csv,test_features.parquet,sale_subssion.csv

    他现在用的这台二手电脑,内存只有可怜的8G。

    如果直接用pandas把这三点几个G的parquet格式数据全量读进内存,这台二手机器大概率会直接卡死。

    于是,他打开编辑器,写了一个几十行的python短脚本。

    只读表头元数据和前面的前一百万行样本切片,用来探路。

    十分钟后,按下运行键。

    终端里瞬间刷出一长串刺眼的红字报错信息。

    江临盯着那串红字,愣了两秒,然后哑然失笑。

    现实世界就是这样充满黑色幽默。

    你踌躇满志,以为自己马上就要面对深不可测的资本市场,要去手撕复杂的金融微观结构了,结果第一刀,却结结实实地砍在了一个缺失的底层依赖库上。

    “行吧,先搞后勤。“

    江临摇了摇头,在命令行里敲下了安装命令。

    看着屏幕上跳动的一个个下载进度条,他顺手把这些包的版本号,一个不落地记录在了刚才的audit_log里。

    晚上九点四十六分,环境配置完毕。

    第一批百万行的切片数据,终于顺利地被读进了内存。

    屏幕上整齐地打印出了十几个常规行情字段,最后跟着三个由平台方自己生成的辅助字段。

    session_id,source_flag,row_weight。

    江临没有急着去看那些价格数字,而是盯着这最后三个字段看几眼,评价为。

    【凡是平台方称作内部质量分组的字段,先不要当特征使用,先当潜在污染分层变量审计。】

    接下来,他开始对这一百万行切片做最基础的侦查审计。

    江临把脑子里的几个基础常识翻译成几行干净利落的聚合代码,点击运行。

    笔记本电脑发出低沉的轰鸣,cpU风扇开始高速转动,像是在抗议这种压榨。

    第一轮审计脚本跑了足足二十多分钟。

    终端里,一行行统计结果慢慢跳了出来。

    和江临预想的一样,大部分记录看起来非常平滑正常,但也有一小撮记录脏得让人没眼看。

    毕竟这个比赛的任务就是找脏数据,有异常是在预料之内的。

    江临平静地写了几行画图脚本,把那些被筛出来的异常样本随机抽了几个,画成走势图。

    这些异常都太浅了。

    写几个if-else的条件过滤就能抓得一清二楚。

    江临心里盘算着,如果只靠这些表层的业务逻辑去提交,应该能稳定拿到一个中等偏上的分数,拿不到奖金,但至少能及格。

    如果任务只停留在这些表层逻辑错误上,就不值得平台设置人工报告评分。

    江临揉了揉有些发酸的眼睛,喝了一口水,继续往下看第四个问题的统计结果。

    凌晨一点二十,当缺失值的分布矩阵渲染在屏幕上时,他终于发现了第一处让他皱起眉头的异常现象。

    数据里的缺失值,不是均匀出现的。

    如果是一般的低流动性标的,出现偶尔的数据缺失是很正常的。

    又或者,是某一只股票的交易所接口突然卡顿,造成几分钟的断档,这也说得通。

    但现在屏幕上显示的问题是,缺失极其密集地集中在若干个date_id的同一段nute_id上。

    而且,更诡异的是,这些nute_id的缺失,横跨样本里成百上千个不同的syol_id。

    为了看清楚,江临把这百万行数据的缺失分布状态画成了一张二维热力图。

    横轴是时间,纵轴是标的代码,有数据的地方是深蓝色,缺失的地方是刺眼的亮黄色。

    屏幕上赫然出现了几条横贯全图的亮黄色条带,就像一整块深蓝色的布料上,被人用刀残忍地划出了几道平行的巨大伤口。

    这不是某一只股票的交易出了问题,不是标的自身的市场行为!

    这更像是在那个特定的时间段,负责收集市场数据的某一台核心服务器突然宕机了,或者是底层供应商的某根专线断了,导致整个市场在这一段切片上的数据,经历了全链路的集体丢包。

    江临立刻切回audit_log,在日志里重重地敲下一行字。

    【异常类型 A:横向时间截面级缺失。】

    【推断:此异常不属于市场本身的交易特征,极大概率是数据供应商底层接口故障,或平台拼接多源数据时发生的时间轴对齐失误。】

    他顺着这个思路往下查,试图把所有出现过横向断层的时间段全部圈出来。

    接着,他犯了一个非常小但足以致命的常识性错误。

    他在热力图上框选时,发现不仅是某些随机的日子有横向伤口,几乎每一个date_id的中间段,都有一大块规则的、横贯全市场的空白区域。

    江临毫不犹豫地把这段规则的空白也标记成了异常缺失。

    但在按下保存键的那一瞬间,他的手指悬停在了半空。

    “等等,所有标的,每一天,在中间完全相同的位置,准时切断,又准时恢复?“

    江临忽然意识到什么,快速切出代码界面,打开浏览器,在搜索引擎里输入了A股交易时间。

    页面立刻跳出结果:上午 9:30 - 11:30,下午 13:00 - 15:00。

    中午有一个半小时的休市。

    江临拍了一下自己的脑门。

    自己把这部分规则的空白当成了数据丢失

本章未完,请点击下一页继续阅读>>

章节目录