You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Feast实现指定历史日期的30天交易数量离线特征查询

Feast离线场景下基于历史日期的窗口特征计算实现

Feast完全支持你描述的离线场景需求——传入指定历史日期,计算该日期前30天的交易数量特征,核心是通过滑动窗口聚合定义和历史时间戳参数传递来实现,无需依赖NOW()这类动态时间函数。

具体实现步骤

1. 重新定义数据源与FeatureView(推荐方式)

放弃硬编码NOW()的聚合查询,改用Feast内置的滑动窗口聚合功能,确保离线/在线逻辑一致:

from feast import FeatureView, Field, aggregation
from feast.infra.offline_stores.contrib.postgres_offline_store.postgres_source import PostgreSQLSource
from datetime import timedelta

# 定义基础数据源:仅获取交易明细的核心字段
order_source = PostgreSQLSource(
    name="client_placed_order_source",
    query="SELECT client_id, event_timestamp FROM events.client_placed_order",
    timestamp_field="event_timestamp",
)

# 定义FeatureView,绑定30天滑动窗口聚合
client_order_features = FeatureView(
    name="client_order_features",
    entities=["client_id"],
    schema=[Field(name="cnt_last_30days", dtype="int64")],
    online=True,
    source=order_source,
    aggregations=[
        aggregation(
            function="count",
            name="cnt_last_30days",
            window=timedelta(days=30),
        )
    ],
)

2. 传入历史日期获取离线特征

构造包含目标历史时间戳的实体DataFrame,调用get_historical_features即可自动计算对应窗口的特征:

import pandas as pd
from feast import FeatureStore

# 初始化Feast Store
store = FeatureStore(repo_path="./your_feast_repo")

# 构造实体请求:指定每个客户需要计算特征的历史时间点(2022-02-01)
entity_df = pd.DataFrame({
    "client_id": ["client_001", "client_002", "client_003"],
    "event_timestamp": pd.to_datetime(["2022-02-01"] * 3)
})

# 获取历史特征:Feast将自动计算每个客户在2022-02-01前30天的交易数量
historical_features = store.get_historical_features(
    entity_df=entity_df,
    features=["client_order_features:cnt_last_30days"]
).to_df()

print(historical_features)

关键逻辑说明

  • 在线场景下,Feast会自动使用当前时间作为event_timestamp计算窗口特征,与你之前用NOW()的逻辑完全一致,保证特征一致性。
  • 离线场景中,Feast会根据你传入的event_timestamp(即历史日期),过滤该时间点之前的交易数据,并计算过去30天的聚合值,完全匹配你需要的2022-01-01至2022-02-01时间范围。

可选:自定义SQL参数化查询(不推荐)

如果需要手动控制SQL逻辑,也可以使用Feast的参数化查询(通过@event_timestamp占位符),但内置窗口聚合更简洁且不易出错:

order_source = PostgreSQLSource(
    name="client_placed_order_source",
    query="""
        SELECT client_id,
               @event_timestamp AS event_timestamp,
               SUM(CASE WHEN event_timestamp >= @event_timestamp - INTERVAL '30 days' THEN 1 ELSE 0 END) AS cnt_last_30days
        FROM events.client_placed_order
        WHERE event_timestamp <= @event_timestamp
        GROUP BY client_id
    """,
    timestamp_field="event_timestamp",
)

内容的提问来源于stack exchange,提问作者Vladislav Zhilmanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:12:47