4. River核心数据结构
在River中做在线学习,第一件事不是选模型,而是把数据组织成River能持续消费的结构。River的设计哲学是“单条样本驱动”:模型每次只看到一条样本,立即预测、立即学习、立即丢弃或保留统计量。因此,理解Stream、Dataset、TimeSeries以及它们背后的数据流迭代器,是金融流式机器学习能否落地的基础。本节围绕这四个对象,讲清它们的职责边界、协作方式,以及金融数据如何接入。
一、核心原理:四种结构的分工
River中与数据相关的核心抽象可以分成两层:数据容器层和迭代消费层。容器层负责“数据长什么样、从哪里来”,迭代层负责“如何一条条喂给模型”。
- Stream(流):最基础的迭代器协议。任何实现了
__iter__并逐条产出(x, y)的对象都可以视为Stream。它不关心数据来源,只关心“下一条样本是什么”。 - Dataset(数据集):对静态数据集的封装,通常支持按索引访问、划分训练/测试、批量迭代。它更像“可重复读取的数据表”,适合离线回测和基准测试。
- TimeSeries(时间序列):面向时间戳有序数据的结构,强调时间索引、频率、缺失值处理。金融场景中,价格、成交量、订单簿快照天然是时间序列。
- 数据流迭代器:把上述容器转换为统一的“逐条产出”接口,是River模型
learn_one/predict_one的直接输入。
核心记忆点:Dataset 是“可回放的静态表”,TimeSeries 是“带时间轴的有序序列”,Stream 是“一次性或可重置的样本流”,迭代器是“把前三者统一成模型能吃的格式”。
二、方法流程:从数据源到模型的一条样本
无论数据来自CSV、数据库还是实时行情,接入River的流程都可以归纳为四步:
- 定义样本结构:确定
x是字典(特征名到值)还是向量,y是分类标签还是回归目标。 - 选择容器:离线回测用
Dataset或TimeSeries;实时接入用自定义生成器或消息队列消费者。 - 构造迭代器:通过
iter()或stream.iter_*系列函数,把容器转成逐条样本。 - 驱动在线学习:在循环中调用
predict_one与learn_one,并记录指标。
from river import stream, metrics
# 假设 data 是 TimeSeries 或 Dataset
metric = metrics.Accuracy()
for x, y in stream.iter_csv("trades.csv", target="label"):
y_pred = model.predict_one(x) # 先预测
if y_pred is not None:
metric.update(y, y_pred)
model.learn_one(x, y) # 再学习
注意顺序:先预测、后学习。这是在线学习与批量学习最本质的区别,也是避免数据泄漏的关键。
三、金融数据接入方式与场景
金融数据接入River时,常见有三类来源,处理方式差异明显:
| 数据来源 | 推荐容器 | 接入方式 | 注意事项 |
|---|---|---|---|
| 历史CSV/Parquet | Dataset / TimeSeries | stream.iter_csv、iter_pandas |
需按时间排序,避免未来函数 |
| 数据库快照 | Dataset | 分页查询 + 生成器 | 控制内存,逐批转逐条 |
| 实时行情/消息队列 | 自定义Stream | Kafka/WebSocket消费者 | 处理乱序、重复、断线重连 |
以Tick级行情为例,一条样本通常包含时间戳、最新价、成交量、买卖盘口等字段。接入时建议把时间戳单独保留,特征字典只放模型可用的数值,标签由未来窗口收益生成。这样既符合River的 (x, y) 协议,也便于后续做特征工程。
四、误区与复盘:金融接入中最容易踩的坑
误区一:把Dataset当Stream反复遍历。 很多Dataset迭代器是一次性的,第二次循环会得到空结果。若需多轮训练,应显式重置或重新构造迭代器。
误区二:时间序列未排序就接入。 TimeSeries的价值在于时间有序。若CSV未按时间排序,模型会“看到未来”,回测指标虚高,实盘必然失效。
复盘建议: 接入任何金融数据前,先做三件事——检查时间戳单调性、确认标签生成不依赖未来数据、用小样本跑通
predict_one → learn_one 循环。这三步能过滤掉大部分流式学习的低级错误。
最后强调一点:River的Stream、Dataset、TimeSeries不是互斥的,而是可以组合的。你可以用TimeSeries承载原始行情,用Dataset做特征快照,再用自定义Stream把两者拼成模型输入。理解它们的职责边界,比记住API更重要。金融流式机器学习的稳定性,往往就藏在这些数据结构的细节里。