Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este caderno de exemplo ilustra como treinar um modelo de classificação de aprendizagem automática em Databricks. O Databricks Runtime for Machine Learning vem com muitas bibliotecas pré-instaladas, incluindo scikit-learn para treino e algoritmos de pré-processamento, MLflow para acompanhar o processo de desenvolvimento do modelo, e Optuna para afinação de hiperparâmetros escalável.
Neste caderno, cria um modelo de classificação para prever se um vinho é considerado "de alta qualidade". O conjunto de dados consiste em 11 características de diferentes vinhos (por exemplo, teor alcoólico, acidez e açúcar residual) e uma classificação de qualidade entre 1 e 10.
Este tutorial aborda:
- Parte 1: Treinar um modelo de classificação com rastreamento MLflow
- Parte 2: Ajuste de hiperparâmetros para melhorar o desempenho do modelo
- Parte 3: Guardar resultados e modelos no Unity Catalog
- Parte 4: Implementar o modelo
Para mais detalhes sobre a produção de aprendizagem automática em Databricks, incluindo gestão do ciclo de vida do modelo e inferência de modelos, veja o Exemplo de ML End to End.
O conjunto de dados está disponível no UCI Machine Learning Repository e é apresentado em Modeling wine preferences by data mining from physicochemical properties [Cortez et al., 2009].
Requisitos
- Cluster executando Databricks Runtime 17.3 LTS ML ou posterior. Se estiver a usar Databricks Runtime 16.4 LTS ML ou inferior, veja o Tutorial: Constrói o seu primeiro modelo de aprendizagem automática em Databricks (Hyperopt).
Configuração
Nesta secção, faz o seguinte:
- Configure o cliente MLflow para usar o Unity Catalog como registo de modelos.
- Defina o catálogo e o esquema onde o modelo será registado.
- Leia os dados e guarde-os em tabelas no Unity Catalog.
- Pré-processar os dados.
Configurar o cliente MLflow
Por defeito, o cliente MLflow Python cria modelos no registo de modelos do Databricks workspace. Para guardar modelos no Unity Catalog, configure o cliente MLflow conforme mostrado na célula seguinte.
import mlflow
mlflow.set_registry_uri("databricks-uc")
A célula seguinte define o catálogo e o esquema onde o modelo será registado. Deve ter USE CATALOG privilégio no catálogo, e privilégios USE_SCHEMA, CREATE_TABLE e CREATE_MODEL no esquema. Altere os nomes do catálogo e dos esquemas na célula seguinte, se necessário.
Para mais informações, consulte a documentação do Catálogo Unity.
# Specify the catalog and schema to use. You must have USE_CATALOG privilege on the catalog and USE_SCHEMA, CREATE_TABLE, and CREATE_MODEL privileges on the schema.
# Change the catalog and schema here if necessary.
CATALOG_NAME = "main"
SCHEMA_NAME = "default"
Leia os dados e guarde-os em tabelas no Unity Catalog
O conjunto de dados está disponível em databricks-datasets. Na célula seguinte, lês os dados dos .csv ficheiros para os DataFrames do Spark. Depois escreves os DataFrames em tabelas no Unity Catalog. Isto mantém os dados persistentes e permite-te controlar como os partilhar com os outros.
white_wine = spark.read.csv("/databricks-datasets/wine-quality/winequality-white.csv", sep=';', header=True)
red_wine = spark.read.csv("/databricks-datasets/wine-quality/winequality-red.csv", sep=';', header=True)
# Remove the spaces from the column names
for c in white_wine.columns:
white_wine = white_wine.withColumnRenamed(c, c.replace(" ", "_"))
for c in red_wine.columns:
red_wine = red_wine.withColumnRenamed(c, c.replace(" ", "_"))
# Define table names
red_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine"
white_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine"
# Write to tables in Unity Catalog
spark.sql(f"DROP TABLE IF EXISTS {red_wine_table}")
spark.sql(f"DROP TABLE IF EXISTS {white_wine_table}")
white_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine")
red_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine")
Dados de pré-processamento
# Import required libraries
import numpy as np
import pandas as pd
import sklearn.datasets
import sklearn.metrics
import sklearn.model_selection
import sklearn.ensemble
import matplotlib.pyplot as plt
import optuna
from mlflow.optuna.storage import MlflowStorage
from mlflow.pyspark.optuna.study import MlflowSparkStudy
# Load data from Unity Catalog as Pandas dataframes
white_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine").toPandas()
red_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine").toPandas()
# Add Boolean fields for red and white wine
white_wine['is_red'] = 0.0
red_wine['is_red'] = 1.0
data_df = pd.concat([white_wine, red_wine], axis=0)
# Define classification labels based on the wine quality
data_labels = data_df['quality'].astype('int') >= 7
data_df = data_df.drop(['quality'], axis=1)
# Split 80/20 train-test
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
data_df,
data_labels,
test_size=0.2,
random_state=1
)
Parte 1. Treine um modelo de classificação
# Enable MLflow autologging for this notebook
mlflow.autolog()
De seguida, treine um classificador no contexto de uma execução MLflow, que regista automaticamente o modelo treinado e muitas métricas e parâmetros associados.
Pode complementar o registo com métricas adicionais, como a pontuação AUC do modelo no conjunto de dados de teste.
with mlflow.start_run(run_name='gradient_boost') as run:
model = sklearn.ensemble.GradientBoostingClassifier(random_state=0)
# Models, parameters, and training metrics are tracked automatically
model.fit(X_train, y_train)
predicted_probs = model.predict_proba(X_test)
roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
roc_curve = sklearn.metrics.RocCurveDisplay.from_estimator(model, X_test, y_test)
# Save the ROC curve plot to a file
roc_curve.figure_.savefig("roc_curve.png")
# The AUC score on test data is not automatically logged, so log it manually
mlflow.log_metric("test_auc", roc_auc)
# Log the ROC curve image file as an artifact
mlflow.log_artifact("roc_curve.png")
print("Test AUC of: {}".format(roc_auc))
Ver corridas de MLflow
Para visualizar a execução de treino registada, clique no ícone Experimento
no canto superior direito do caderno para mostrar a barra lateral do experimento. Se necessário, clique no ícone de atualização para buscar e monitorar as execuções mais recentes.
Para mostrar a página mais detalhada do experimento MLflow, clique no ícone da página do experimento. Esta página permite-lhe comparar corridas e ver detalhes de corridas específicas. Consulte Acompanhar o desenvolvimento de modelos usando MLflow.
Modelos de carga
Também pode aceder aos resultados de uma execução específica usando a API MLflow. O código na célula seguinte ilustra como carregar o modelo treinado numa determinada execução de MLflow e usá-lo para fazer previsões. Também pode encontrar excertos de código para carregar modelos específicos na página de execução do MLflow.
# After a model has been logged, you can load it in different notebooks or jobs
# mlflow.pyfunc.load_model makes model prediction available under a common API
model_loaded = mlflow.pyfunc.load_model(
'runs:/{run_id}/model'.format(
run_id=run.info.run_id
)
)
predictions_loaded = model_loaded.predict(X_test)
predictions_original = model.predict(X_test)
# The loaded model should match the original
assert(np.array_equal(predictions_loaded, predictions_original))
Parte 2. Ajuste de hiperparâmetros
Neste ponto, treinaste um modelo simples e usaste o serviço de rastreamento MLflow para organizar o teu trabalho. De seguida, pode realizar afinações mais sofisticadas usando Optuna.
Treino paralelo usando Optuna
Optuna é uma biblioteca Python open-source para ajuste de hiperparâmetros que pode ser escalada horizontalmente em múltiplos recursos de computação. Para mais informações sobre a utilização do Optuna em Databricks, veja Ajuste de Hiperparâmetros com Optuna.
def objective(trial):
# Enable autologging on each worker
mlflow.autolog()
with mlflow.start_run(nested=True):
params = {
'n_estimators': trial.suggest_int('n_estimators', 20, 1000),
'learning_rate': trial.suggest_float('learning_rate', 0.05, 1.0, log=True),
'max_depth': trial.suggest_int('max_depth', 2, 5),
}
model_hp = sklearn.ensemble.GradientBoostingClassifier(
random_state=0,
**params
)
model_hp.fit(X_train, y_train)
predicted_probs = model_hp.predict_proba(X_test)
# Tune based on the test AUC
# In production, you could use a separate validation set instead
roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
mlflow.log_metric('test_auc', roc_auc)
# Negate the AUC because Optuna minimizes the objective by default
return -roc_auc
with mlflow.start_run(run_name='gb_optuna') as run:
# Use the MLflow Tracking Server as the Optuna storage backend
experiment_id = mlflow.active_run().info.experiment_id
mlflow_storage = MlflowStorage(experiment_id=experiment_id)
# MlflowSparkStudy distributes the tuning using Spark workers
mlflow_study = MlflowSparkStudy(
study_name="gb-optuna-tuning",
storage=mlflow_storage,
)
mlflow_study.optimize(objective, n_trials=32, n_jobs=4)
A pesquisa é executada para recuperar o melhor modelo.
Como todas as execuções são acompanhadas pelo MLflow, pode obter as métricas e parâmetros para a melhor execução usando a API de pesquisa de execuções do MLflow para encontrar a execução de ajuste com o maior auc de teste.
Este modelo ajustado deverá ter um desempenho melhor do que os modelos mais simples treinados na Parte 1.
# Sort runs by their test auc. In case of ties, use the most recent run.
best_run = mlflow.search_runs(
order_by=['metrics.test_auc DESC', 'start_time DESC'],
max_results=10,
).iloc[0]
print('Best Run')
print('AUC: {}'.format(best_run["metrics.test_auc"]))
print('Num Estimators: {}'.format(best_run["params.n_estimators"]))
print('Max Depth: {}'.format(best_run["params.max_depth"]))
print('Learning Rate: {}'.format(best_run["params.learning_rate"]))
best_model_pyfunc = mlflow.pyfunc.load_model(
'runs:/{run_id}/model'.format(
run_id=best_run.run_id
)
)
# Make a dataset with all predictions
best_model_predictions = X_test
best_model_predictions["prediction"] = best_model_pyfunc.predict(X_test)
Parte 3. Guardar resultados e modelos no Unity Catalog
predictions_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.predictions"
spark.sql(f"DROP TABLE IF EXISTS {predictions_table}")
results = spark.createDataFrame(best_model_predictions)
# Write results back to Unity Catalog from Python
results.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.predictions")
model_uri = 'runs:/{run_id}/model'.format(
run_id=best_run.run_id
)
mlflow.register_model(model_uri, f"{CATALOG_NAME}.{SCHEMA_NAME}.wine_quality_model")
Parte 4. Implementar o modelo
Depois de guardares o teu modelo no Unity Catalog, podes implementá-lo usando a interface de servimento. As instruções seguintes dão uma breve descrição. Para mais informações, consulte Configurar endpoints de fornecimento de modelos personalizados.
- Clique em Serviço na barra lateral para exibir a UI de Serviço.
Clique em Criar terminal de serviço.
No campo Nome, forneça um nome para o seu ponto de extremidade.
Na secção Entidades servidas
- Clique no campo Entidade para abrir o formulário Selecionar entidade atendida .
- Selecione os meus modelos - Catálogo Unity. O formulário é atualizado dinamicamente com base na sua seleção.
- Seleciona a
wine_quality_modelversão e modelo que queres servir. - Selecione 100 como a percentagem de tráfego que quer encaminhar para o modelo servido.
- Selecione CPU como tipo de computação para este exemplo.
- Em Compute Scale-out, selecione Pequeno como tamanho de escala computacional.
Clique em Criar. A página endpoints de serviço aparece com estado dos endpoints de serviço mostrado como Não Pronto.
Quando o seu endpoint estiver Pronto, selecione Usar para submeter um pedido de inferência ao endpoint.