Usar recurso para treinar modelos
Este artigo descreve como o senhor pode treinar modelos usando o recurso engenharia em Unity Catalog ou o espaço de trabalho legado Recurso Store. O senhor deve primeiro criar um treinamento dataset, que define o recurso a ser usado e como join eles. Então, quando o senhor treina um modelo, o modelo retém referências ao recurso.
Quando o senhor treina um modelo usando recurso engenharia em Unity Catalog, pode view a linhagem do modelo no Catalog Explorer. Tabelas e funções que foram usadas para criar o modelo são automaticamente rastreadas e exibidas. Ver recurso governança e linhagem.
Ao usar o modelo para inferência, o senhor pode optar por fazer com que ele recupere valores de recurso do armazenamento de recurso. Os modelos de armazenamento de recurso também são compatíveis com a interfaceMLflow pyfunc, portanto, o senhor pode usar MLflow para realizar a inferência de lotes com tabelas de recurso.
Um modelo pode usar no máximo 50 tabelas e 100 funções para treinamento.
Criar um treinamento dataset
Para selecionar um recurso específico de uma tabela de recursos para o modelo de treinamento, o senhor cria um treinamento dataset usando o FeatureEngineeringClient.create_training_set
(para recurso engenharia em Unity Catalog) ou FeatureStoreClient.create_training_set
(para recurso workspace Store) API e um objeto chamado FeatureLookup
. Um FeatureLookup
especifica cada recurso a ser usado no conjunto de treinamento, inclusive o nome da tabela de recursos, o(s) nome(s) do recurso e o(s) key a ser(em) usado(s) ao unir a tabela de recursos com o DataFrame passado para create_training_set
. Consulte Recurso Lookup para obter mais informações.
Use o parâmetro feature_names
ao criar um FeatureLookup
.
feature_names
recebe um único nome de recurso, uma lista de nomes de recurso ou None para procurar todos os recursos (excluindo a chave primária) na tabela de recursos no momento em que o conjunto de treinamento é criado.
O tipo e a ordem das colunas lookup_key
no site DataFrame devem corresponder ao tipo e à ordem da chave primária (excluindo a chave de registro de data e hora) da tabela de recursos de referência.
Este artigo inclui exemplos de código para ambas as versões da sintaxe.
Neste exemplo, o DataFrame retornado por trainingSet.load_df
contém uma coluna para cada recurso em feature_lookups
. Ele preserva todas as colunas do DataFrame fornecido para create_training_set
, exceto aquelas excluídas usando exclude_columns
.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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()
Criar um TrainingSet quando a chave de pesquisa não corresponder à chave primária
Use o argumento lookup_key
em FeatureLookup
para o nome da coluna no conjunto de treinamento. create_training_set
executa um join ordenado entre as colunas do conjunto de treinamento especificado no argumento lookup_key
usando a ordem em que a chave primária foi especificada quando a tabela de recursos foi criada.
Neste exemplo, recommender_system.customer_features
tem a seguinte chave primária: customer_id
, dt
.
A tabela de recursos recommender_system.product_features
tem o endereço primário key product_id
.
Se o training_df
tiver as seguintes colunas:
cid
transaction_dt
product_id
rating
O código a seguir criará as pesquisas de recurso corretas para o site TrainingSet
:
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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'
)
]
Quando create_training_set
é chamado, ele cria um treinamento dataset executando um left join, unindo as tabelas recommender_system.customer_features
e training_df
usando a chave (customer_id
,dt
) correspondente a (cid
,transaction_dt
), conforme mostrado no código a seguir:
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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"
)
Criar um TrainingSet contendo dois recursos com o mesmo nome de tabelas de recursos diferentes
Use o argumento opcional output_name
no FeatureLookup
. O nome fornecido é usado no lugar do nome do recurso no DataFrame retornado por TrainingSet.load_df
. Por exemplo, com o código a seguir, o DataFrame retornado por training_set.load_df
inclui as colunas customer_height
e product_height
.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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()
Criar um TrainingSet usando o mesmo recurso várias vezes
Para criar um TrainingSet usando o mesmo recurso unido por uma chave de pesquisa diferente, use vários FeatureLookups.
Use um output_name
exclusivo para cada saída FeatureLookup.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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'
)
]
Criar um TrainingSet para o modelo não supervisionado de aprendizado de máquina
Defina label=None
ao criar um TrainingSet para modelos de aprendizado não supervisionado. Por exemplo, o seguinte TrainingSet pode
ser usado para agrupar diferentes clientes em grupos com base em seus interesses:
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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()
Criar um TrainingSet ao usar o site view como uma tabela de recurso
Para usar o view como uma tabela de recurso, o senhor deve usar a versão 0.7.0 do databricks-feature-engineering
ou o acima, que está integrado ao Databricks Runtime 16.0 ML.
O view deve ser um simples SELECT view da tabela Delta de origem. Um SELECT view simples é definido como um view criado a partir de uma única tabela Delta em Unity Catalog que pode ser usada como uma tabela de recurso e cuja chave primária é selecionada sem cláusulas join, GROUP BY ou DISTINCT. As palavras-chave aceitáveis na instrução SQL são SELECT, FROM, WHERE, ORDER BY, LIMIT e OFFSET.
No exemplo a seguir, ml.recommender_system.customer_table
tem a chave primária cid
e dt
, em que dt
é uma coluna de série temporal. O exemplo pressupõe que o dataframe training_df
tenha as colunas cid
, dt
e label
:
from databricks.feature_engineering import FeatureEngineeringClient, FeatureLookup
customer_features_df = spark.sql("CREATE OR REPLACE VIEW ml.recommender_system.customer_features AS SELECT cid, dt, pid, rating FROM ml.recommender_system.customer_table WHERE rating > 3")
feature_lookups = [
FeatureLookup(
table_name='ml.recommender_system.customer_features',
feature_names=['pid', 'rating'],
lookup_key=['cid'],
timestamp_lookup_key='dt'
),
]
fe = FeatureEngineeringClient()
training_set = fe.create_training_set(
df=training_df,
feature_lookups=feature_lookups,
label='label'
)
training_df = training_set.load_df()
Treinar modelos e realizar inferência de lotes com tabelas de recursos
Quando o senhor treina um modelo usando recurso do recurso Store, o modelo retém referências ao recurso. Ao usar o modelo para inferência, o senhor pode optar por fazer com que ele recupere valores de recurso do recurso Store. O senhor deve fornecer o key(s) principal (is) do recurso usado no modelo. O modelo recupera o recurso necessário do recurso Store em seu site workspace. Em seguida, ele junta os valores do recurso conforme necessário durante a pontuação.
Para dar suporte à pesquisa de recurso no momento da inferência:
-
O senhor deve log o modelo usando o método
log_model
deFeatureEngineeringClient
(para recurso engenharia em Unity Catalog) ouFeatureStoreClient
(para recurso workspace Store). -
O senhor deve usar o DataFrame retornado por
TrainingSet.load_df
para treinar o modelo. Se o senhor modificar esse DataFrame de alguma forma antes de usá-lo para treinar o modelo, as modificações não serão aplicadas quando o modelo for usado para inferência. Isso diminui o desempenho do modelo. -
O tipo de modelo deve ter um
python_flavor
correspondente no MLflow. O MLflow é compatível com a maioria das estruturas de treinamento de modelos Python, incluindo:- scikit-learn
- Keras
- PyTorch
- SparkML
- LightGBM
- XGBoost
- TensorFlow Keras (usando o site
python_flavor
mlflow.keras
)
-
Modelos pyfunc personalizados do MLflow
- Feature Engineering in Unity Catalog
- Workspace Feature Store
# 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’
Usar valores de recurso personalizados ao pontuar um pacote de modelos com metadados de recurso
Em default, um pacote de modelos com metadados de recurso procura o recurso nas tabelas de recurso na inferência. Para usar valores de recurso personalizados para a pontuação, inclua-os no DataFrame passado para FeatureEngineeringClient.score_batch
(para recurso engenharia em Unity Catalog) ou FeatureStoreClient.score_batch
(para recurso workspace Store).
Por exemplo, suponha que o senhor pacote um modelo com esses dois recursos:
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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',
),
]
Na inferência, o senhor pode fornecer valores personalizados para o recurso account_creation_date
chamando score_batch
em um DataFrame que inclua uma coluna chamada account_creation_date
. Nesse caso, o site API procura apenas o recurso num_lifetime_purchases
do recurso Store e usa os valores de coluna account_creation_date
personalizados fornecidos para a pontuação do modelo.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
# 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
)
Treinar e pontuar um modelo usando uma combinação de recurso Store recurso e dados residentes fora do recurso Store
O senhor pode treinar um modelo usando uma combinação de recurso Store recurso e dados de fora do recurso Store. Quando o senhor empacota o modelo com metadados de recurso, o modelo recupera os valores de recurso do recurso Store para inferência.
Para treinar um modelo, inclua os dados extras como colunas no DataFrame passadas para FeatureEngineeringClient.create_training_set
(para recurso engenharia em Unity Catalog) ou FeatureStoreClient.create_training_set
(para recurso workspace Store). Este exemplo usa o recurso total_purchases_30d
do recurso Store e a coluna externa browser
.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
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
)
Na inferência, o DataFrame usado em FeatureStoreClient.score_batch
deve incluir a coluna browser
.
- Feature Engineering in Unity Catalog
- Workspace Feature Store
# 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
)
Carregar modelos e realizar inferência de lotes usando MLflow
Após um modelo ter sido registrado usando o método log_model
de FeatureEngineeringClient
(para recurso engenharia em Unity Catalog) ou FeatureStoreClient
(para recurso workspace Store), MLflow pode ser usado na inferência. mlflow.pyfunc.predict
recupera valores de recurso do recurso Store e também junta quaisquer valores fornecidos no momento da inferência. O senhor deve fornecer o key(s) principal (is) do recurso usado no modelo.
A inferência de lotes com MLflow requer MLflow versão 2.11 e acima. Não há suporte para modelos que usam tabelas de recurso de série temporal. Para fazer inferência de lotes com tabelas de recurso de séries temporais, use score_batch
. Consulte Treinar modelos e realizar inferência de lotes com tabelas de recursos.
# 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)
Lidar com valores de recurso ausentes
Quando uma pesquisa inexistente key é passada para o modelo para previsão, o valor do recurso buscado por FeatureLookup
é NaN
.