[추석 연휴 커널로그 챌린지] Feast 실습

ARK_dvlp·2025년 10월 6일

커널 아카데미 16기

목록 보기
13/17

🏋️ Feast 사용 예시

0️⃣ CMD 명령어

특성 저장소 만들기

feast init my_feature_repo
cd my_feature_repo/feature_repo

피처 정의를 등록하고 피처 스토어를 설정

feast apply

UI 보기

feast ui

1️⃣ 프로젝트 정의

project = Project(name="my_feature_repo", description="A project for driver statistics")
  • Feast 레포의 프로젝트 이름과 설명을 정의합니다.
  • 프로젝트 단위로 FeatureView, Entity, FeatureService 등을 관리합니다.

2️⃣ 엔티티(Entity) 정의

driver = Entity(name="driver", join_keys=["driver_id"])
  • 엔티티(Entity)는 ML 피처의 주 키(primary key) 역할입니다.
  • 여기서는 driver_id가 고유 식별자로 사용됩니다.
  • Feast에서는 FeatureView에서 엔티티를 통해 피처 데이터를 조회합니다.

3️⃣ 데이터 소스 정의 (FileSource)

driver_stats_source = FileSource(
    name="driver_hourly_stats_source",
    path="data\driver_stats.parquet",
    timestamp_field="event_timestamp",
    created_timestamp_column="created",
)
  • 로컬 Parquet 파일을 Feast Offline Store 소스로 정의.
  • timestamp_field: 과거 시점 피처 조회 시 기준이 되는 컬럼.
  • created_timestamp_column: 데이터 생성 시점을 추적할 컬럼.

4️⃣ FeatureView 정의

driver_stats_fv = FeatureView(
    name="driver_hourly_stats",
    entities=[driver],
    ttl=timedelta(days=1),
    schema=[
        Field(name="conv_rate", dtype=Float32),
        Field(name="acc_rate", dtype=Float32),
        Field(name="avg_daily_trips", dtype=Int64, description="Average daily trips"),
    ],
    online=True,
    source=driver_stats_source,
    tags={"team": "driver_performance"},
)
  • FeatureView는 실제 피처를 정의하고 조회/서빙할 단위입니다.
  • entities: 어떤 엔티티를 기준으로 피처를 조회할지.
  • ttl: 피처의 유효 기간(Time-To-Live).
  • online=True: 실시간 추론 시 사용할 수 있는 피처임을 의미.
  • source: 데이터를 가져올 소스 정의.
  • tags: 사용자 정의 메타데이터.

5️⃣ RequestSource 정의

input_request = RequestSource(
    name="vals_to_add",
    schema=[
        Field(name="val_to_add", dtype=Int64),
        Field(name="val_to_add_2", dtype=Int64),
    ],
)
  • RequestSource: 요청 시점에서만 제공되는 입력 값.
  • 예: 웹 요청, API 호출에서 오는 실시간 값.
  • On-demand FeatureView에서 조합하여 새로운 피처를 만들 수 있음.

6️⃣ On-Demand FeatureView 정의

@on_demand_feature_view(
    sources=[driver_stats_fv, input_request],
    schema=[
        Field(name="conv_rate_plus_val1", dtype=Float64),
        Field(name="conv_rate_plus_val2", dtype=Float64),
    ],
)
def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame:
    df = pd.DataFrame()
    df["conv_rate_plus_val1"] = inputs["conv_rate"] + inputs["val_to_add"]
    df["conv_rate_plus_val2"] = inputs["conv_rate"] + inputs["val_to_add_2"]
    return df
  • On-Demand FeatureView: 기존 FeatureView와 RequestSource를 기반으로 실시간 계산 피처 생성.
  • inputs로 들어오는 데이터프레임은 sources의 모든 피처가 합쳐진 형태.
  • 여기서는 conv_rate에 실시간 요청값(val_to_add)을 더해 새로운 피처를 생성.

7️⃣ FeatureService 정의

driver_activity_v1 = FeatureService(
    name="driver_activity_v1",
    features=[driver_stats_fv[["conv_rate"]], transformed_conv_rate],
    logging_config=LoggingConfig(
        destination=FileLoggingDestination(path="data")
    ),
)
  • FeatureService는 모델 단위로 피처를 묶는 레이어.
  • 여러 FeatureView와 On-Demand FeatureView를 묶어 ML 모델이 필요한 피처 집합을 정의.
  • logging_config: 피처 사용 로그를 저장할 위치를 지정.
  • 여러 버전(v1, v2, v3)을 만들어 모델별로 피처 조합 관리 가능.

8️⃣ PushSource & Fresh FeatureView

driver_stats_push_source = PushSource(
    name="driver_stats_push_source",
    batch_source=driver_stats_source,
)

driver_stats_fresh_fv = FeatureView(
    name="driver_hourly_stats_fresh",
    entities=[driver],
    ttl=timedelta(days=1),
    schema=[...],
    online=True,
    source=driver_stats_push_source,
    tags={"team": "driver_performance"},
)
  • PushSource: 데이터베이스나 이벤트가 아닌, 실시간으로 데이터를 밀어 넣을 수 있는 소스.
  • Fresh FeatureView는 이 PushSource를 기반으로 실시간/최신 피처를 온라인 스토어에 바로 서빙 가능.

9️⃣ Fresh On-Demand FeatureView

@on_demand_feature_view(
    sources=[driver_stats_fresh_fv, input_request],  # relies on fresh version of FV
    schema=[
        Field(name="conv_rate_plus_val1", dtype=Float64),
        Field(name="conv_rate_plus_val2", dtype=Float64),
    ],
)

def transformed_conv_rate_fresh(inputs: pd.DataFrame) -> pd.DataFrame:
    df = pd.DataFrame()
    df["conv_rate_plus_val1"] = inputs["conv_rate"] + inputs["val_to_add"]
    df["conv_rate_plus_val2"] = inputs["conv_rate"] + inputs["val_to_add_2"]
    return df
  • PushSource 기반 Fresh FeatureView와 RequestSource를 합쳐 실시간 변형 피처 생성.
  • 기존 On-Demand FeatureView와 구조는 동일하지만, 실시간 데이터에 최적화됨.

🔟 사용 예시

from feast import FeatureStore
import pandas as pd
from datetime import datetime

entity_df = pd.DataFrame.from_dict({
    "driver_id": [1001, 1002, 1003, 1004],
    "event_timestamp": [
        datetime(2021, 4, 12, 10, 59, 42),
        datetime(2021, 4, 12, 8,  12, 10),
        datetime(2021, 4, 12, 16, 40, 26),
        datetime(2021, 4, 12, 15, 1 , 12)
    ]
})

store = FeatureStore(repo_path="repo_path")

training_df = store.get_historical_features(
    entity_df=entity_df,
    features = [
        'driver_hourly_stats:conv_rate',
        'driver_hourly_stats:acc_rate',
        'driver_hourly_stats:avg_daily_trips'
    ],
).to_df()

print(training_df.head())
  • 조회 기준: 각 driver_id가 특정 event_timestamp 시점에 어떤 피처 값을 가졌는지
  • Feast 프로젝트 경로 지정 → FeatureStore 객체 생성
  • FeatureView(driver_hourly_stats)에서 지정한 피처를 각 엔티티 + 시점 기준으로 조회
  • .to_df() → Pandas DataFrame 변환
  • 학습용 피처 테이블 확인

0개의 댓글