Aller au contenu principal

Calcul de fonctionnalités à la demande

Dans Databricks, les fonctionnalités à la demande sont calculées au moment de l'inférence à l'aide de fonctions Python définies par l'utilisateur (UDF), plutôt que d'être matérialisées à l'avance.

Les fonctionnalités à la demande sont générées à partir des valeurs des fonctionnalités et des entrées du modèle. Ils ne sont pas matérialisés, mais sont plutôt compute à la demande pendant l'entraînement du modèle et pendant l'inférence. Un cas d'utilisation typique consiste à post-traiter les fonctionnalités existantes, par exemple pour analyser un champ à partir d'une chaîne JSON. Vous pouvez également utiliser des fonctionnalités à la demande pour compute de nouvelles fonctionnalités basées sur des Transformations de fonctionnalités existantes, comme la normalisation des valeurs dans un tableau.

Dans Databricks, vous utilisez les fonctions Python définées par l'utilisateur (UDF) pour spécifier comment calculer des fonctionnalités à la demande. Ces fonctions sont régies par Unity Catalog et peuvent être découvertes via l'Explorateur de catalogue.

Pour utiliser les fonctionnalités à la demande, votre Workspace doit être activé pour Unity Catalog et vous devez utiliser Databricks Runtime 13,3 LTS ML ou supérieur.

Workflow

Pour calculer des fonctionnalités à la demande, vous spécifiez une fonction définie par l'utilisateur (UDF) Python qui décrit comment calculer les valeurs de la fonctionnalité.

  • Pendant l'entraînement, vous fournissez cette fonction et ses liaisons d'entrée dans le paramètre feature_lookups de l'API create_training_set.
  • Vous devez enregistrer le modèle entraîné à l'aide de la méthode du Magasin de fonctionnalités log_model. Cela garantit que le modèle évalue automatiquement les fonctionnalités à la demande lorsqu'il est utilisé pour l'inférence.
  • Pour le score par lots, l'API score_batch calcule et renvoie automatiquement toutes les valeurs de fonctionnalités, y compris les fonctionnalités à la demande.

Créer une UDF Python

Vous pouvez créer une UDF Python dans un Notebook ou dans Databricks SQL.

Par exemple, l'exécution du code suivant dans une cellule de notebook crée l'UDF Python example_feature dans le catalogue main et le schéma default.

%sql
CREATE FUNCTION main.default.example_feature(x INT, y INT)
RETURNS INT
LANGUAGE PYTHON
COMMENT 'add two numbers'
AS $$
def add_numbers(n1: int, n2: int) -> int:
return n1 + n2

return add_numbers(x, y)
$$

Après avoir exécuté le code, vous pouvez naviguer dans l'espace de noms à trois niveaux dans l'Explorateur de catalogues pour afficher la définition de la fonction :

fonction dans Catalog Explorer

Pour plus de détails sur la création d'UDF Python, consultez Enregistrer une UDF Python dans Unity Catalog et le manuel du langage SQL.

Entraîner un modèle à l'aide de fonctionnalités à la demande

Pour entraîner le modèle, vous utilisez un FeatureFunction, qui est transmis à l’API create_training_set dans le paramètre feature_lookups.

L'exemple de code suivant utilise l'UDF Python main.default.example_feature qui a été défini dans la section précédente.

Python
# Install databricks-feature-engineering first with:
# %pip install databricks-feature-engineering
# dbutils.library.restartPython()

from databricks.feature_engineering import FeatureEngineeringClient
from databricks.feature_engineering import FeatureFunction, FeatureLookup
from sklearn import linear_model

fe = FeatureEngineeringClient()

features = [
# The feature 'on_demand_feature' is computed as the sum of the input value 'new_source_input'
# and the pre-materialized feature 'materialized_feature_value'.
# - 'new_source_input' must be included in base_df and also provided at inference time.
# - For batch inference, it must be included in the DataFrame passed to 'FeatureEngineeringClient.score_batch'.
# - For real-time inference, it must be included in the request.
# - 'materialized_feature_value' is looked up from a feature table.

FeatureFunction(
udf_name="main.default.example_feature", # UDF must be in Unity Catalog so uses a three-level namespace
input_bindings={
"x": "new_source_input",
"y": "materialized_feature_value"
},
output_name="on_demand_feature",
),
# retrieve the prematerialized feature
FeatureLookup(
table_name = 'main.default.table',
feature_names = ['materialized_feature_value'],
lookup_key = 'id'
)
]

# base_df includes the columns 'id', 'new_source_input', and 'label'
training_set = fe.create_training_set(
df=base_df,
feature_lookups=features,
label='label',
exclude_columns=['id', 'new_source_input', 'materialized_feature_value'] # drop the columns not used for training
)

# The training set contains the columns 'on_demand_feature' and 'label'.
training_df = training_set.load_df().toPandas()

# training_df columns ['materialized_feature_value', 'label']
X_train = training_df.drop(['label'], axis=1)
y_train = training_df.label

model = linear_model.LinearRegression().fit(X_train, y_train)

Enregistrer le modèle et l'inscrire dans Unity Catalog

Les modèles packagés avec des métadonnées de fonctionnalités peuvent être enregistrés dans Unity Catalog. Les tables de fonctionnalités utilisées pour créer le modèle doivent être stockées dans Unity Catalog.

Pour vous assurer que le modèle évalue automatiquement les fonctionnalités à la demande lorsqu'il est utilisé pour l'inférence, vous devez définir l'URI du registre, puis journaliser le modèle, comme suit :

Python
import mlflow
mlflow.set_registry_uri("databricks-uc")

fe.log_model(
model=model,
artifact_path="main.default.model",
flavor=mlflow.sklearn,
training_set=training_set,
registered_model_name="main.default.recommender_model"
)

Si l’UDF Python qui définit les fonctionnalités à la demande importe des packages Python, vous devez spécifier ces packages à l’aide de l’argument extra_pip_requirements. Par exemple :

Python
import mlflow
mlflow.set_registry_uri("databricks-uc")

fe.log_model(
model=model,
artifact_path="model",
flavor=mlflow.sklearn,
training_set=training_set,
registered_model_name="main.default.recommender_model",
extra_pip_requirements=["scikit-learn==1.20.3"]
)

Exemple de Notebook

Le notebook suivant montre comment entraîner et évaluer un modèle qui utilise des fonctionnalités à la demande.

Notebook de démonstration des fonctionnalités de base à la demande

Limitations

Pour les Endpoints de Feature Serving, tous les types de données pris en charge par le Magasin de fonctionnalités sont pris en charge en tant que types de sortie des fonctions de fonctionnalité, à l'exception de ArrayType, MapType et StructType. StructType n'est pas non plus pris en charge en tant que type d'entrée de fonction de fonctionnalité.