본문 바로가기

Machine Learning/MLOps

Feast : 머신 러닝을 위한 오픈 소스 피쳐 스토어

https://github.com/feast-dev/feast?tab=readme-ov-file

 

GitHub - feast-dev/feast: The Open Source Feature Store for Machine Learning

The Open Source Feature Store for Machine Learning - feast-dev/feast

github.com

 

 

일반적으로 머신 러닝에서 피쳐는 두번 사용됩니다. 첫 번째는 모델 학습을 진행할 때, 두 번째는 학습된 모델을 사용하여 추론할 때입니다.

 

학습단계에서는 대용량의 피쳐 데이터를 생성하여 모델이 특정 패턴을 학습 할 수 있도록 합니다. 추론 단계에서는 피쳐데이터를 즉각적인 추론 결과를 제공할 필요가 있습니다. 또 이 두 피쳐가 달라지게 되면 모델의 성능에 악영향을 미칠 수 있습니다. 이를 위해서 필요한 것이 피쳐스토어 입니다.

 

 

피쳐 스토어의 구성 요소 중 일부는 다음과 같습니다.

  • 실시간 피쳐 데이터를 제공 할 수 있는 온라인 스토리지
  • 대용량 피쳐 데이터를 저장할 수 있는 오프라인 스토리지
  • 피쳐 데이터를 생성하고, 피쳐 데이터를 저장 해 주는 피쳐 파이프라인
  • 온라인 스토리지에서 피쳐 데이터를 제공하기 위한 피쳐 서빙 서버

 

이 떄 피쳐스토어를 위한 오픈 소스인 Feast라는 것이 있어 Feast에 대해 공부를 해본 후, 소개하려고 합니다.

 

 

Feast 설명

Feast 실시간 ML 모델을 위한 서비스 입니다. ML 팀의 피쳐 플랫폼을 구축하기 위한 서비스 입니다.

머신러닝 서비스의 비즈니스 가치가 정의되지 않은 조직에서는 도입에 고민할 필요가 있습니다.

 

Feast 는 ETL, ELT 시스템, 데이터 통합 도구, 데이터베이스, 데이터 웨어하우스가 아닙니다.

Feast 는 다음과 같은 기능을 제한적으로 제공할 수 있습니다.

  • 모델의 재현 및 모델 백테스팅
  • 배치 피쳐 엔지니어링
  • 스트리밍 기능 통합
  • 데이터 계보(lineage)
  • 데이터 품질 관리 데이터 드리프트 탐지

따라서 Feast 는 실시간 피쳐를 온 오프라인에서 일관성있게 사용할 수 있는 서비스 입니다.

 

 

Feast

Quick Start와 데이터 사용에 필요한 것들을 정리 하였습니다.

 

 

피쳐 데이터 정의

Entity : 의미적으로 관련된 피쳐의 모음을 의미합니다.

엔티티는 없을 수도 있고, 하나일수도 있고, 여러개 일 수 있습니다.

ex) 엔티티가 없는 경우 : XX서비스의 전체 사용자 수

ex) 엔티티가 하나인 경우 : 사용자id의 나이, 물품id의 가격

ex) 엔티티가 여러개인 경우 : 사용자id물품id 페이지 방문 횟수 횟수

 

Feature View : 시계열 피쳐 데이터의 논리적 그룹을 의미합니다.

Feature View 는 다음과 아래와 같은 것들로 구성됩니다.

  • 데이터 소스
  • 엔티티 정보
  • 이 피쳐 뷰를 식별하는 이름
  • 피쳐를 지정을 위한 스키마
  • 메타데이터 (설명, 태그 등)
  • TTL

아래와 같이 피쳐 뷰를 정의할 수 있습니다.

from feast import Entity, PushSource, ValueType, BigQuerySource, FeatureView, Feature, Field
from feast.types import Int64

push_source = PushSource(
    name="push_source",
    batch_source=BigQuerySource(table="test.test"),
)

user = Entity(name="user", join_keys=["user_id"])

fv = FeatureView(
    name="feature view",
    entities=[user],
    schema=[Field(name="life_time_value", dtype=Int64)],
    source=push_source,
)

 

 

피쳐 데이터 입력 (https://docs.feast.dev/reference/data-sources/push)

push 를 통해서 피쳐 값을 온라인 스토어와 오프라인 스토어에 실시간으로 값을 업데이트 할 수 있습니다.

 

 

from feast import FeatureStore
import pandas as pd
from feast.data_source import PushMode

fs = FeatureStore(...)
feature_data_frame = pd.DataFrame()
fs.push("push_source_name", feature_data_frame, to=PushMode.ONLINE_AND_OFFLINE)

 

 

모델 학습을 위한 Feast 사용

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)
    ]
})

# 피쳐 조회를 위한 엔티티 데이터가 있고.
"""
	driver_id	event_timestamp
0	1001	2021-04-12 10:59:42
1	1002	2021-04-12 08:12:10
2	1003	2021-04-12 16:40:26
3	1004	2021-04-12 15:01:12

"""

# Feast를 통해서 학습데치터를 가져오면
store = FeatureStore(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  conv_rate  acc_rate  avg_daily_trips
0       1001 2021-04-12 10:59:42+00:00   0.609114  0.169808              540
1       1002 2021-04-12 08:12:10+00:00   0.545895  0.751415              326
2       1003 2021-04-12 16:40:26+00:00   0.011137  0.130887              464
3       1004 2021-04-12 15:01:12+00:00   0.294819  0.393546              865
"""

 

 

모델 추론을 위한 Feast 사용

먼저 시간 세팅을 진행 해 줍니다.

CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S")
feast materialize-incremental $CURRENT_TIME

 

이후, 다음과 같이 주어진 키와 시간을 기준으로 피쳐 데이터를 생성 할 수 있습니다.

from pprint import pprint
from feast import FeatureStore

store = FeatureStore(repo_path=".")

feature_vector = store.get_online_features(
    features=[
        'driver_hourly_stats:conv_rate',
        'driver_hourly_stats:acc_rate',
        'driver_hourly_stats:avg_daily_trips'
    ],
    entity_rows=[{"driver_id": 1001}] # 기준이 되는 키 값
).to_dict()

pprint(feature_vector)
"""
{'acc_rate': [0.5105873942375183],
 'avg_daily_trips': [732],
 'conv_rate': [0.6736856698989868],
 'driver_id': [1001]}
"""

 

 

 

피쳐데이터 관리를 위한 웹 사이트

feast ui

 

 

 

 

마무리

평소 피쳐 데이터 생성, 사용, 관리를 위해 정의했던 개념과 기능들이 모두 Feast에서 잘 정리되어 있었다고 생각이 들었습니다. ML 프로젝트에서 Feast를 사용하면 효율적으로 피쳐를 사용하고 관리할 수 있을것으로 기대가 됩니다.