Использование функций для обучения моделей

В этой статье описывается, как обучать модели с помощью конструктора компонентов в каталоге Unity или локальном хранилище компонентов рабочей области. Сначала необходимо создать обучающий набор данных, который определяет используемые признаки и способы их присоединения. Затем, когда вы обучаете модель, модель сохраняет ссылки на признаки.

При обучении модели с помощью конструктора компонентов в каталоге Unity можно просмотреть происхождение модели в Обозреватель каталога. Таблицы и функции, используемые для создания модели, автоматически отслеживаются и отображаются. Просмотр происхождения хранилища функций.

При использовании модели для вывода можно выбрать получение значений признаков из хранилища компонентов. Вы также можете обслуживать модель с помощью службы моделей, и она автоматически будет искать функции , опубликованные в интернет-магазинах. Модели хранилища функций также совместимы с интерфейсом MLflow pyfunc, поэтому можно использовать MLflow для выполнения пакетного вывода с таблицами компонентов.

Если в модели используются переменные среды, узнайте больше о том, как использовать их при обслуживании модели в сети при настройке доступа к ресурсам из конечных точек обслуживания моделей.

Модель может использовать не более 50 таблиц и 100 функций для обучения.

Создание набора данных для обучения

Чтобы выбрать определенные функции из таблицы компонентов для обучения модели, создайте обучающий набор данных с помощью FeatureEngineeringClient.create_training_set API (для проектирования компонентов в каталоге Unity) или FeatureStoreClient.create_training_set (для хранилища компонентов рабочей области) и объекта под названием FeatureLookup. Объект FeatureLookup задает каждый признак, используемый в обучающем наборе, включая имя таблицы признаков, имена признаков и ключи, которые следует использовать для соединении таблицы признаков с переданным в create_training_set объектом DataFrame. Дополнительные сведения см. в разделе "Поиск компонентов".

Используйте параметр feature_names при создании FeatureLookup. feature_names принимает одно имя признака, список имен признаков или нет значение None для поиска всех признаков (исключая первичные ключи) в таблице признаков во время создания обучающего набора.

Примечание.

Тип и порядок столбцов в кадре данных должен соответствовать типу и порядку lookup_key первичных ключей (за исключением ключей метки времени) эталонной таблицы признаков.

Эта статья содержит примеры кода для обеих версий синтаксиса.

В этом примере объект DataFrame, возвращаемый методом trainingSet.load_df, содержит столбец для каждого признака в feature_lookups. Он сохраняет все столбцы объекта DataFrame, переданного методу create_training_set, за исключением тех, которые исключены с помощью exclude_columns.

Проектирование компонентов в каталоге unity

from databricks.feature_engineering import FeatureEngineeringClient, FeatureLookup

# The model training uses two features from the 'customer_features' feature table and
# a single feature from 'product_features'
feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['total_purchases_30d', 'total_purchases_7d'],
      lookup_key='customer_id'
    ),
    FeatureLookup(
      table_name='ml.recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

fe = FeatureEngineeringClient()

# Create a training set using training DataFrame and features from Feature Store
# The training DataFrame must contain all lookup keys from the set of feature lookups,
# in this case 'customer_id' and 'product_id'. It must also contain all labels used
# for training, in this case 'rating'.
training_set = fe.create_training_set(
  df=training_df,
  feature_lookups=feature_lookups,
  label='rating',
  exclude_columns=['customer_id', 'product_id']
)

training_df = training_set.load_df()

Хранилище функций рабочей области

from databricks.feature_store import FeatureLookup, FeatureStoreClient

# The model training uses two features from the 'customer_features' feature table and
# a single feature from 'product_features'
feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['total_purchases_30d', 'total_purchases_7d'],
      lookup_key='customer_id'
    ),
    FeatureLookup(
      table_name='recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

fs = FeatureStoreClient()

# Create a training set using training DataFrame and features from Feature Store
# The training DataFrame must contain all lookup keys from the set of feature lookups,
# in this case 'customer_id' and 'product_id'. It must also contain all labels used
# for training, in this case 'rating'.
training_set = fs.create_training_set(
  df=training_df,
  feature_lookups=feature_lookups,
  label='rating',
  exclude_columns=['customer_id', 'product_id']
)

training_df = training_set.load_df()

Создание обучающего набора, когда ключи поиска не соответствуют первичным ключам

Укажите имя столбца в обучающем наборе с помощью аргумента lookup_key в объекте FeatureLookup. create_training_set выполняет упорядоченное соединение между столбцами из обучающего набора, указанного в аргументе lookup_key, используя порядок, в котором первичные ключи были указаны при создании таблицы признаков.

В этом примере recommender_system.customer_features содержит следующие первичные ключи: customer_id, dt.

Таблица признаков recommender_system.product_features использует первичный ключ product_id.

Если training_df содержит следующие столбцы:

  • cid
  • transaction_dt
  • product_id
  • rating

следующий код обеспечивает корректный поиск признаков для TrainingSet:

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['total_purchases_30d', 'total_purchases_7d'],
      lookup_key=['cid', 'transaction_dt']
    ),
    FeatureLookup(
      table_name='ml.recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['total_purchases_30d', 'total_purchases_7d'],
      lookup_key=['cid', 'transaction_dt']
    ),
    FeatureLookup(
      table_name='recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

Когда вызывается метод create_training_set, он создает обучающий набор данных, выполняя левое соединение, которое объединяет таблицы recommender_system.customer_features и training_df с помощью ключей (customer_id,dt), соответствующих столбцам (cid,transaction_dt), как показано в следующем коде:

Проектирование компонентов в каталоге unity

customer_features_df = spark.sql("SELECT * FROM ml.recommender_system.customer_features")
product_features_df = spark.sql("SELECT * FROM ml.recommender_system.product_features")

training_df.join(
  customer_features_df,
  on=[training_df.cid == customer_features_df.customer_id,
      training_df.transaction_dt == customer_features_df.dt],
  how="left"
).join(
  product_features_df,
  on="product_id",
  how="left"
)

Хранилище функций рабочей области

customer_features_df = spark.sql("SELECT * FROM recommender_system.customer_features")
product_features_df = spark.sql("SELECT * FROM recommender_system.product_features")

training_df.join(
  customer_features_df,
  on=[training_df.cid == customer_features_df.customer_id,
      training_df.transaction_dt == customer_features_df.dt],
  how="left"
).join(
  product_features_df,
  on="product_id",
  how="left"
)

Создание обучающего набора, содержащего два признака с одинаковым именем из разных таблиц признаков

Используйте в FeatureLookup необязательный аргумент output_name. Указанное имя используется вместо имени признака в объекте DataFrame, возвращаемом методом TrainingSet.load_df. Например, в следующем коде объект DataFrame, возвращаемый методом training_set.load_df, включает столбцы customer_height и product_height.

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['height'],
      lookup_key='customer_id',
      output_name='customer_height',
    ),
    FeatureLookup(
      table_name='ml.recommender_system.product_features',
      feature_names=['height'],
      lookup_key='product_id',
      output_name='product_height'
    ),
  ]

fe = FeatureEngineeringClient()

with mlflow.start_run():
  training_set = fe.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label='rating',
    exclude_columns=['customer_id']
  )
  training_df = training_set.load_df()

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['height'],
      lookup_key='customer_id',
      output_name='customer_height',
    ),
    FeatureLookup(
      table_name='recommender_system.product_features',
      feature_names=['height'],
      lookup_key='product_id',
      output_name='product_height'
    ),
  ]

fs = FeatureStoreClient()

with mlflow.start_run():
  training_set = fs.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label='rating',
    exclude_columns=['customer_id']
  )
  training_df = training_set.load_df()

Создание Набора обучения с помощью одной функции несколько раз

Чтобы создать TrainingSet с помощью одной функции, присоединенной к разным ключам подстановки, используйте несколько featureLookups. Используйте уникальный output_name для каждого вывода FeatureLookup.

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.taxi_data.zip_features',
      feature_names=['temperature'],
      lookup_key=['pickup_zip'],
      output_name='pickup_temp'
    ),
    FeatureLookup(
      table_name='ml.taxi_data.zip_features',
      feature_names=['temperature'],
      lookup_key=['dropoff_zip'],
      output_name='dropoff_temp'
    )
  ]

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='taxi_data.zip_features',
      feature_names=['temperature'],
      lookup_key=['pickup_zip'],
      output_name='pickup_temp'
    ),
    FeatureLookup(
      table_name='taxi_data.zip_features',
      feature_names=['temperature'],
      lookup_key=['dropoff_zip'],
      output_name='dropoff_temp'
    )
  ]

Создание обучающего набора данных для моделей неконтролируемого машинного обучения

При создании обучающего набора для моделей неконтролируемого обучения задайте label=None. Например, следующий обучающий набор можно использовать для кластеризации различных клиентов по группам в зависимости от их интересов:

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['interests'],
      lookup_key='customer_id',
    ),
  ]

fe = FeatureEngineeringClient()
with mlflow.start_run():
  training_set = fe.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label=None,
    exclude_columns=['customer_id']
  )

  training_df = training_set.load_df()

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['interests'],
      lookup_key='customer_id',
    ),
  ]

fs = FeatureStoreClient()
with mlflow.start_run():
  training_set = fs.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label=None,
    exclude_columns=['customer_id']
  )

  training_df = training_set.load_df()

Обучение моделей и пакетный вывод с помощью таблиц признаков

При обучении модели с использованием признаков из хранилища признаков модель сохраняет ссылки на эти признаки. При использовании модели для вывода она может загружать значения признаков из хранилища признаков. Вы должны указать первичные ключи признаков, используемых в модели. Модель извлекает необходимые признаки из хранилища в вашей рабочей области. Затем она по мере необходимости соединяет значения признаков во время оценки.

Чтобы обеспечить возможность поиска признаков на этапе вывода:

  • Необходимо записать модель с помощью log_model метода FeatureEngineeringClient (for Feature Engineering in Unity Catalog) или FeatureStoreClient (for Workspace Feature Store).
  • Для обучения модели необходимо использовать объект DataFrame, возвращаемый методом TrainingSet.load_df. Если вы каким-либо образом измените этот объект DataFrame, прежде чем использовать его для обучения модели, ваши изменения не будут применены при использовании модели для вывода. Это снижает производительность модели.
  • Типу модели должен соответствовать параметр python_flavor в MLflow. MLflow поддерживает большинство платформ обучения модели Python, в том числе:
    • scikit-learn
    • keras
    • PyTorch
    • SparkML
    • LightGBM
    • XGBoost
    • TensorFlow Keras (с использованием python_flavormlflow.keras)
  • Пользовательские модели MLflow pyfunc

Проектирование компонентов в каталоге unity

# Train model
import mlflow
from sklearn import linear_model

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['total_purchases_30d'],
      lookup_key='customer_id',
    ),
    FeatureLookup(
      table_name='ml.recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

fe = FeatureEngineeringClient()

with mlflow.start_run():

  # df has columns ['customer_id', 'product_id', 'rating']
  training_set = fe.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label='rating',
    exclude_columns=['customer_id', 'product_id']
  )

  training_df = training_set.load_df().toPandas()

  # "training_df" columns ['total_purchases_30d', 'category', 'rating']
  X_train = training_df.drop(['rating'], axis=1)
  y_train = training_df.rating

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

  fe.log_model(
    model=model,
    artifact_path="recommendation_model",
    flavor=mlflow.sklearn,
    training_set=training_set,
    registered_model_name="recommendation_model"
  )

# Batch inference

# If the model at model_uri is packaged with the features, the FeatureStoreClient.score_batch()
# call automatically retrieves the required features from Feature Store before scoring the model.
# The DataFrame returned by score_batch() augments batch_df with
# columns containing the feature values and a column containing model predictions.

fe = FeatureEngineeringClient()

# batch_df has columns ‘customer_id’ and ‘product_id’
predictions = fe.score_batch(
    model_uri=model_uri,
    df=batch_df
)

# The ‘predictions’ DataFrame has these columns:
# ‘customer_id’, ‘product_id’, ‘total_purchases_30d’, ‘category’, ‘prediction’

Хранилище функций рабочей области

# Train model
import mlflow
from sklearn import linear_model

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['total_purchases_30d'],
      lookup_key='customer_id',
    ),
    FeatureLookup(
      table_name='recommender_system.product_features',
      feature_names=['category'],
      lookup_key='product_id'
    )
  ]

fs = FeatureStoreClient()

with mlflow.start_run():

  # df has columns ['customer_id', 'product_id', 'rating']
  training_set = fs.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label='rating',
    exclude_columns=['customer_id', 'product_id']
  )

  training_df = training_set.load_df().toPandas()

  # "training_df" columns ['total_purchases_30d', 'category', 'rating']
  X_train = training_df.drop(['rating'], axis=1)
  y_train = training_df.rating

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

  fs.log_model(
    model=model,
    artifact_path="recommendation_model",
    flavor=mlflow.sklearn,
    training_set=training_set,
    registered_model_name="recommendation_model"
  )

# Batch inference

# If the model at model_uri is packaged with the features, the FeatureStoreClient.score_batch()
# call automatically retrieves the required features from Feature Store before scoring the model.
# The DataFrame returned by score_batch() augments batch_df with
# columns containing the feature values and a column containing model predictions.

fs = FeatureStoreClient()

# batch_df has columns ‘customer_id’ and ‘product_id’
predictions = fs.score_batch(
    model_uri=model_uri,
    df=batch_df
)

# The ‘predictions’ DataFrame has these columns:
# ‘customer_id’, ‘product_id’, ‘total_purchases_30d’, ‘category’, ‘prediction’

Использование настраиваемых значений признаков при оценке модели, упакованной с метаданными признаков

По умолчанию модель, упаковаемая с метаданными признаков, ищет функции из таблиц компонентов при выводе. Чтобы использовать пользовательские значения признаков для оценки, включите их в кадр данных, переданный FeatureEngineeringClient.score_batch (для проектирования компонентов в каталоге Unity) или FeatureStoreClient.score_batch (для хранилища компонентов рабочей области).

Например, предположим, что вы упаковываете модель с этими двумя признаками:

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['account_creation_date', 'num_lifetime_purchases'],
      lookup_key='customer_id',
    ),
  ]

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['account_creation_date', 'num_lifetime_purchases'],
      lookup_key='customer_id',
    ),
  ]

На этапе вывода можно указать пользовательские значения для признака account_creation_date, вызвав метод score_batch для объекта DataFrame, содержащего столбец с именем account_creation_date. В этом случае API ищет только признак num_lifetime_purchases в хранилище признаков и использует указанные настраиваемые значения столбца account_creation_date для оценки модели.

Проектирование компонентов в каталоге unity

# batch_df has columns ['customer_id', 'account_creation_date']
predictions = fe.score_batch(
  model_uri='models:/ban_prediction_model/1',
  df=batch_df
)

Хранилище функций рабочей области

# batch_df has columns ['customer_id', 'account_creation_date']
predictions = fs.score_batch(
  model_uri='models:/ban_prediction_model/1',
  df=batch_df
)

Обучение и оценка модели с использованием сочетания признаков из хранилища признаков и данных за его пределами

Вы можете обучить модель, используя сочетание признаков из хранилища признаков и данных за его пределами. При упаковке модели с метаданными признаков модель получает для вывода значения признаков из хранилища признаков.

Чтобы обучить модель, включите дополнительные данные в качестве столбцов в кадр данных, переданных FeatureEngineeringClient.create_training_set (для проектирования компонентов в каталоге Unity) или FeatureStoreClient.create_training_set (для хранилища компонентов рабочей области). В этом примере используется признак total_purchases_30d из хранилища признаков и внешний столбец browser.

Проектирование компонентов в каталоге unity

feature_lookups = [
    FeatureLookup(
      table_name='ml.recommender_system.customer_features',
      feature_names=['total_purchases_30d'],
      lookup_key='customer_id',
    ),
  ]

fe = FeatureEngineeringClient()

# df has columns ['customer_id', 'browser', 'rating']
training_set = fe.create_training_set(
  df=df,
  feature_lookups=feature_lookups,
  label='rating',
  exclude_columns=['customer_id']  # 'browser' is not excluded
)

Хранилище функций рабочей области

feature_lookups = [
    FeatureLookup(
      table_name='recommender_system.customer_features',
      feature_names=['total_purchases_30d'],
      lookup_key='customer_id',
    ),
  ]

fs = FeatureStoreClient()

# df has columns ['customer_id', 'browser', 'rating']
training_set = fs.create_training_set(
  df=df,
  feature_lookups=feature_lookups,
  label='rating',
  exclude_columns=['customer_id']  # 'browser' is not excluded
)

Во время вывода объект DataFrame, используемый в FeatureStoreClient.score_batch, должен содержать столбец browser.

Проектирование компонентов в каталоге unity

# At inference, 'browser' must be provided
# batch_df has columns ['customer_id', 'browser']
predictions = fe.score_batch(
  model_uri=model_uri,
  df=batch_df
)

Хранилище функций рабочей области

# At inference, 'browser' must be provided
# batch_df has columns ['customer_id', 'browser']
predictions = fs.score_batch(
  model_uri=model_uri,
  df=batch_df
)

Загрузка моделей и выполнение пакетного вывода с помощью MLflow

После регистрации модели с помощью log_model метода FeatureEngineeringClient (for Feature Engineering in Unity Catalog) или FeatureStoreClient (for Workspace Feature Store), MLflow можно использовать при выводе. MLflow.pyfunc.predict извлекает значения признаков из хранилища компонентов, а также присоединяет все значения, предоставленные во время вывода. Вы должны указать первичные ключи признаков, используемых в модели.

Примечание.

Для вывода пакетной службы с MLflow требуется MLflow версии 2.11 и выше.

# Train model
import mlflow
from sklearn import linear_model

feature_lookups = [
  FeatureLookup(
    table_name='ml.recommender_system.customer_features',
    feature_names=['total_purchases_30d'],
    lookup_key='customer_id',
  ),
  FeatureLookup(
    table_name='ml.recommender_system.product_features',
    feature_names=['category'],
    lookup_key='product_id'
  )
]

fe = FeatureEngineeringClient()

with mlflow.start_run():

  # df has columns ['customer_id', 'product_id', 'rating']
  training_set = fe.create_training_set(
    df=df,
    feature_lookups=feature_lookups,
    label='rating',
    exclude_columns=['customer_id', 'product_id']
  )

  training_df = training_set.load_df().toPandas()

  # "training_df" columns ['total_purchases_30d', 'category', 'rating']
  X_train = training_df.drop(['rating'], axis=1)
  y_train = training_df.rating

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

  fe.log_model(
    model=model,
    artifact_path="recommendation_model",
    flavor=mlflow.sklearn,
    training_set=training_set,
    registered_model_name="recommendation_model",
    #refers to the default value of "result_type" if not provided at inference
    params={"result_type":"double"},
  )

# Batch inference with MLflow

# NOTE: the result_type parameter can only be used if a default value
# is provided in log_model. This is automatically done for all models
# logged using Databricks Runtime for ML 15.0 or above.
# For earlier Databricks Runtime versions, use set_result as shown below.

# batch_df has columns ‘customer_id’ and ‘product_id’
model = mlflow.pyfunc.load_model(model_version_uri)

# If result_type parameter is provided in log_model
predictions = model.predict(df, {"result_type":"double"})

# If result_type parameter is NOT provided in log_model
model._model_impl.set_result_type("double")
predictions = model.predict(df)