深入理解creme-ml中的流水线艺术
river 项目地址: https://gitcode.com/gh_mirrors/river12/river
流水线在机器学习中的重要性
流水线(Pipeline)是构建机器学习系统的自然方式。通过流水线,数据科学家可以清晰地看到数据"流动"经过一系列处理步骤的过程。典型的机器学习流程从原始数据开始,经过特征提取、数据标准化、异常值处理等步骤,最终转化为适合机器学习算法输入的格式。
creme-ml作为一个专注于在线学习的Python库,其流水线设计理念与UNIX哲学高度一致,特别适合处理数据流场景。与批处理学习不同,在线学习将数据视为连续不断的观测流,这种场景下流水线的优势尤为明显。
传统过程式编程的局限性
让我们先看一个使用传统过程式编程风格构建的餐厅访客预测模型:
means = (
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 7)),
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 14)),
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 21))
)
scaler = preprocessing.StandardScaler()
lin_reg = linear_model.LinearRegression()
metric = metrics.MAE()
for x, y in datasets.Restaurants():
# 特征工程
x['weekday'] = x['date'].weekday()
x['is_weekend'] = x['date'].weekday() in (5, 6)
# 处理目标变量的滚动均值
for mean in means:
x = {**x, **mean.transform_one(x)}
mean.learn_one(x, y)
# 移除非特征字段
for key in ['store_id', 'date', 'genre_name', 'area_name', 'latitude', 'longitude']:
x.pop(key)
# 数据标准化
scaler.learn_one(x)
x = scaler.transform_one(x)
# 模型预测和训练
y_pred = lin_reg.predict_one(x)
lin_reg.learn_one(x, y)
# 评估指标更新
metric.update(y, y_pred)
这种实现虽然直观,但存在几个问题:
- 代码冗长且重复
- 步骤顺序容易出错
- 难以防止目标泄漏
- 不易复用和扩展
声明式流水线的优势
creme-ml提供了compose.Pipeline
来构建声明式流水线,让我们重构上面的代码:
def get_date_features(x):
weekday = x['date'].weekday()
return {'weekday': weekday, 'is_weekend': weekday in (5, 6)}
model = compose.Pipeline(
('features', compose.TransformerUnion(
('date_features', compose.FuncTransformer(get_date_features)),
('last_7_mean', feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 7))),
('last_14_mean', feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 14))),
('last_21_mean', feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 21)))
)),
('drop_non_features', compose.Discard('store_id', 'date', 'genre_name', 'area_name', 'latitude', 'longitude')),
('scale', preprocessing.StandardScaler()),
('lin_reg', linear_model.LinearRegression())
)
metric = metrics.MAE()
for x, y in datasets.Restaurants():
y_pred = model.predict_one(x)
model.learn_one(x, y)
metric.update(y, y_pred)
这种声明式风格有诸多优势:
- 代码更简洁
- 步骤顺序明确
- 防止了目标泄漏
- 更易维护和扩展
更优雅的流水线写法
creme-ml提供了多种简化流水线构建的方法:
1. 自动命名步骤
可以省略步骤名称,creme-ml会自动推断:
model = compose.Pipeline(
compose.TransformerUnion(
compose.FuncTransformer(get_date_features),
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 7)),
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 14)),
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 21))
),
compose.Discard('store_id', 'date', 'genre_name', 'area_name', 'latitude', 'longitude'),
preprocessing.StandardScaler(),
linear_model.LinearRegression()
)
2. 使用数学运算符组合
可以使用+
运算符合并转换器,|
运算符构建流水线:
model = (
compose.FuncTransformer(get_date_features) +
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 7)) +
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 14)) +
feature_extraction.TargetAgg(by='store_id', how=utils.Rolling(stats.Mean(), 21))
)
to_discard = ['store_id', 'date', 'genre_name', 'area_name', 'latitude', 'longitude']
model = model | compose.Discard(*to_discard) | preprocessing.StandardScaler()
model |= linear_model.LinearRegression()
3. 自动函数包装
函数会自动包装为FuncTransformer
:
# 以下两种写法等价
model = compose.FuncTransformer(get_date_features) + ...
model = get_date_features + ...
使用progressive_val_score简化评估
creme-ml提供了evaluate.progressive_val_score
来简化在线学习的评估过程:
from river import evaluate
evaluate.progressive_val_score(
dataset=datasets.Restaurants(),
model=model,
metric=metrics.MAE()
)
这种方法不仅代码更简洁,而且确保了评估过程的正确性。
流水线内部机制
creme-ml的Pipeline
继承自collections.OrderedDict
,每个步骤都有一个名称和对应的转换器/估计器。可以通过标准字典方法访问和操作流水线:
for name, step in model.steps.items():
print(f"{name}: {type(step).__name__}")
总结
creme-ml的流水线设计提供了以下优势:
- 简洁性:通过运算符重载和自动包装减少样板代码
- 安全性:防止常见错误如目标泄漏
- 可读性:声明式风格更易理解和维护
- 灵活性:支持复杂的数据转换和模型组合
- UNIX哲学:类似UNIX管道的数据流处理方式
对于在线学习场景,流水线不仅是一种编码风格,更是一种思维方式。掌握creme-ml的流水线艺术,可以让你更高效地构建和维护机器学习系统。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考