Treinar modelo de regressão com ML Automatizado e Python (SDK v1)

APLICA-SE A: SDK do Python do AzureML v1

Neste artigo, você aprenderá a treinar um modelo de regressão com o SDK do Python do Azure Machine Learning usando o ML Automatizado do Azure Machine Learning. O modelo de regressão prevê tarifas de passageiros para táxis que operam em Nova York (NYC). Você escreve código com o SDK do Python para configurar um workspace com dados preparados, treinar o modelo localmente com parâmetros personalizados e explorar os resultados.

O processo aceita dados de treinamento e configurações. Ele itera automaticamente por meio de combinações de diferentes métodos de normalização/padronização de recursos, modelos e configurações de hiperparâmetro para chegar ao melhor modelo. O diagrama a seguir ilustra o fluxo de processo para o treinamento do modelo de regressão:

Diagrama que ilustra o fluxo de processo para o treinamento do modelo de regressão descrito no artigo.

Pré-requisitos

  • Uma assinatura do Azure. Você pode criar uma conta gratuita ou paga do Azure Machine Learning.

  • Um workspace do Azure Machine Learning e uma instância de computação. Para preparar esses recursos, consulte Início Rápido: Introdução ao Azure Machine Learning.

  • Obtenha os dados de exemplo preparados para os exercícios do tutorial carregando um notebook em seu workspace:

    1. Vá para o workspace no Estúdio do Azure Machine Learning, selecione Notebookse selecione a guia Exemplos.

    2. Na lista de notebooks, expanda o nó Amostras>SDK v1>tutoriais>regression-automl-nyc-taxi-data.

    3. Selecione o notebook regression-automated-ml.ipynb.

    4. Para executar cada célula do notebook como parte deste tutorial, selecione Clonar este arquivo.

    Abordagem alternativa: se preferir, você pode executar os exercícios do tutorial em um ambiente local. O tutorial está disponível no Repositório dos Notebooks do Azure Machine Learning Notebooks no GitHub. Para essa abordagem, siga essas etapas para obter os pacotes necessários:

    1. Instale o cliente automl completo.

    2. Execute o comando pip install azureml-opendatasets azureml-widgets no computador local para obter os pacotes necessários.

Baixar e preparar dados

O pacote dos Conjuntos de Dados em Aberto contém uma classe que representa cada fonte de dados (NycTlcGreen, por exemplo) para filtrar facilmente os parâmetros de data antes de baixar.

O código a seguir importa os pacotes necessários:

from azureml.opendatasets import NycTlcGreen
import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta

A primeira etapa é criar um dataframe para os dados de táxi. Quando você trabalha em um ambiente que não é do Spark, o pacote de Conjunto de Dados em Aberto Datasets permite baixar apenas um mês de dados por vez com determinadas classes. Essa abordagem ajuda a evitar o problema MemoryError que pode ocorrer com conjuntos de dados grandes.

Para baixar os dados de táxi, busque iterativamente um mês de cada vez. Antes de acrescentar o próximo conjunto de dados ao dataframegreen_taxi_df, crie amostras aleatórias de 2.000 registros de cada mês e, em seguida, pré-visualize os dados. Essa abordagem ajuda a evitar a sobrecarga do Dataframe.

O código a seguir cria o dataframe, busca os dados e os carrega no dataframe:

green_taxi_df = pd.DataFrame([])
start = datetime.strptime("1/1/2015","%m/%d/%Y")
end = datetime.strptime("1/31/2015","%m/%d/%Y")

for sample_month in range(12):
   temp_df_green = NycTlcGreen(start + relativedelta(months=sample_month), end + relativedelta(months=sample_month)) \
      .to_pandas_dataframe()
   green_taxi_df = green_taxi_df.append(temp_df_green.sample(2000))

green_taxi_df.head(10)

A tabela a seguir mostra as muitas colunas de valores nos dados de táxi de exemplo:

vendorID lpepPickupDatetime lpepDropoffDatetime passengerCount tripDistance puLocationId doLocationId pickupLongitude pickupLatitude dropoffLongitude ... paymentType fareAmount extra mtaTax improvementSurcharge tipAmount tollsAmount ehailFee totalAmount tripType
2 2015-01-30 18:38:09 2015-01-30 19:01:49 1 1.88 Nenhum Nenhum -73.996155 40.690903 -73.964287 ... 1 15.0 1.0 0.5 0.3 4,00 0,0 Nenhum 20.80 1.0
1 2015-01-17 23:21:39 2015-01-17 23:35:16 1 2.70 Nenhum Nenhum -73.978508 40.687984 -73.955116 ... 1 11,5 0,5 0,5 0.3 2.55 0,0 Nenhum 15.35 1.0
2 2015-01-16 01:38:40 2015-01-16 01:52:55 1 3.54 Nenhum Nenhum -73.957787 40.721779 -73.963005 ... 1 13,5 0,5 0,5 0.3 2,80 0,0 Nenhum 17,60 1.0
2 2015-01-04 17:09:26 2015-01-04 17:16:12 1 1,00 Nenhum Nenhum -73.919914 40.826023 -73.904839 ... 2 6.5 0,0 0.5 0.3 0,00 0,0 Nenhum 7.30 1.0
1 2015-01-14 10:10:57 2015-01-14 10:33:30 1 5.10 Nenhum Nenhum -73.943710 40.825439 -73.982964 ... 1 18.5 0,0 0.5 0.3 3.85 0,0 Nenhum 23.15 1.0
2 2015-01-19 18:10:41 2015-01-19 18:32:20 1 7.41 Nenhum Nenhum -73.940918 40.839714 -73.994339 ... 1 24,0 0,0 0.5 0.3 4,80 0,0 Nenhum 29.60 1.0
2 2015-01-01 15:44:21 2015-01-01 15:50:16 1 1,03 Nenhum Nenhum -73.985718 40.685646 -73.996773 ... 1 6.5 0,0 0.5 0.3 1.30 0,0 Nenhum 8.60 1.0
2 2015-01-12 08:01:21 2015-01-12 08:14:52 5 2.94 Nenhum Nenhum -73.939865 40.789822 -73.952957 ... 2 12.5 0,0 0.5 0.3 0,00 0,0 Nenhum 13,30 1.0
1 2015-01-16 21:54:26 2015-01-16 22:12:39 1 3.00 Nenhum Nenhum -73.957939 40.721928 -73.926247 ... 1 14.0 0,5 0,5 0.3 2,00 0,0 Nenhum 17.30 1.0
2 2015-01-06 06:34:53 2015-01-06 06:44:23 1 2,31 Nenhum Nenhum -73.943825 40.810257 -73.943062 ... 1 10.0 0,0 0.5 0.3 2,00 0,0 Nenhum 12,80 1.0

É útil remover algumas colunas que você não precisa para treinamento ou outra compilação de recursos. Por exemplo, você pode remover a coluna lpepPickupDatetime porque o ML Automatizado lida automaticamente com recursos baseados em tempo.

O código a seguir remove 14 colunas dos dados de exemplo:

columns_to_remove = ["lpepDropoffDatetime", "puLocationId", "doLocationId", "extra", "mtaTax",
                "improvementSurcharge", "tollsAmount", "ehailFee", "tripType", "rateCodeID",
                "storeAndFwdFlag", "paymentType", "fareAmount", "tipAmount"
               ]
for col in columns_to_remove:
   green_taxi_df.pop(col)

green_taxi_df.head(5)

Limpar dados

A próxima etapa é limpar os dados.

O código a seguir executa a função describe() no novo dataframe para produzir estatísticas resumidas para cada campo:

green_taxi_df.describe()

A tabela a seguir mostra estatísticas resumidas dos campos restantes nos dados de exemplo:

vendorID passengerCount tripDistance pickupLongitude pickupLatitude dropoffLongitude dropoffLatitude totalAmount
count 24000.00 24000.00 24000.00 24000.00 24000.00 24000.00 24000.00 24000.00
mean 1.777625 1.373625 2.893981 -73.827403 40.689730 -73.819670 40.684436 14.892744
std 0.415850 1.046180 3.072343 2.821767 1.556082 2.901199 1.599776 12.339749
min 1.00 0,00 0,00 -74.357101 0,00 -74.342766 0,00 -120.80
25% 2,00 1,00 1.05 -73.959175 40.699127 -73.966476 40.699459 8,00
50% 2,00 1,00 1,93 -73.945049 40.746754 -73.944221 40.747536 11,30
75% 2,00 1,00 3.70 -73.917089 40.803060 -73.909061 40.791526 17,80
max 2,00 8,00 154.28 0,00 41.109089 0,00 40.982826 425.00

As estatísticas de resumo revelam vários campos que são exceções, que são valores que reduzem a precisão do modelo. Para resolver esse problema, filtre os campos de latitude/longitude (lat/long) para que os valores estejam dentro dos limites da área de Manhattan. Isso filtra viagens de táxi mais longas ou viagens que são exceções no que diz respeito à sua relação com outros recursos.

Além disso, filtre o campo tripDistance para valores maiores que zero, mas menores que 50 km (a distância Haversine entre os dois pares lat/long). Isso elimina viagens mais longas que são exceção e que têm custo divergente.

Por fim, o campo totalAmount tem valores negativos para as tarifas de táxi, o que não faz sentido no contexto do modelo. O campo passengerCount também contém dados incorretos em que o valor mínimo é zero.

O código a seguir filtra essas anomalias de valor usando funções de consulta. Em seguida, o código remove as últimas colunas que não são necessárias para treinamento:

final_df = green_taxi_df.query("pickupLatitude>=40.53 and pickupLatitude<=40.88")
final_df = final_df.query("pickupLongitude>=-74.09 and pickupLongitude<=-73.72")
final_df = final_df.query("tripDistance>=0.25 and tripDistance<31")
final_df = final_df.query("passengerCount>0 and totalAmount>0")

columns_to_remove_for_training = ["pickupLongitude", "pickupLatitude", "dropoffLongitude", "dropoffLatitude"]
for col in columns_to_remove_for_training:
   final_df.pop(col)

A última etapa nessa sequência é chamar a função describe() novamente nos dados para garantir que a limpeza funcione conforme o esperado. Agora você tem um conjunto preparado e limpo de dados de táxis, feriados e clima para usar no treinamento de modelo de machine learning:

final_df.describe()

Configurar o workspace

Crie um objeto de workspace a partir do workspace existente. Um Workspace é uma classe que aceita suas informações de recursos e assinatura do Azure. Ele também cria um recurso de nuvem para monitorar e acompanhar a execução do seu modelo.

O código a seguir chama a função Workspace.from_config() para ler o arquivo config.json e carregar os detalhes da autenticação em um objeto chamado ws.

from azureml.core.workspace import Workspace
ws = Workspace.from_config()

O objeto ws é usado em todo o restante do código neste tutorial.

Dividir os dados em conjuntos de treinamento e teste

Divida os dados em conjuntos de treinamento e teste usando a função train_test_split na biblioteca scikit-learn. Essa função separa os dados no conjunto de dados X (recursos) para treinamento do modelo e no conjunto de dados Y (valores a serem previstos) para teste.

O parâmetro test_size determina a porcentagem de dados a ser alocada para teste. O parâmetro random_state define uma semente para o gerador aleatório, de modo que suas divisões de teste de treinamento sejam determinísticas.

O código a seguir chama a função train_test_split para carregar os conjuntos de dados x e y:

from sklearn.model_selection import train_test_split

x_train, x_test = train_test_split(final_df, test_size=0.2, random_state=223)

A finalidade desta etapa é preparar pontos de dados para testar o modelo concluído que não é usado para treinar o modelo. Esses pontos são usados para medir a precisão verdadeira. Um modelo bem treinado é aquele que pode fazer previsões precisas de dados não vistos. Agora, você tem dados preparados para treinar automaticamente um modelo de machine learning.

Treinar um modelo automaticamente

Para treinar o modelo automaticamente, execute as seguintes etapas:

  1. Defina configurações para a execução do experimento. Anexe seus dados de treinamento à configuração e modifique as configurações que controlam o processo de treinamento.

  2. Envie o experimento para ajuste do modelo. Depois de enviar o experimento, o processo itera diferentes algoritmos de aprendizado de máquina e configurações de hiperparâmetro, aderindo às restrições definidas. Ele escolhe o modelo mais adequado otimizando uma métrica de precisão.

Definir configurações de treinamento

Defina as configurações de modelos e os parâmetros do experimento para o treinamento. Exiba a lista completa das configurações. O envio do experimento com essas configurações padrão leva aproximadamente de 5 a 20 minutos. Para diminuir o tempo de execução, reduza o parâmetro experiment_timeout_hours.

Propriedade Valor neste tutorial Descrição
iteration_timeout_minutes 10 Limite de tempo em minutos para cada iteração. Aumente esse valor para conjuntos de dados maiores que precisam de mais tempo para cada iteração.
experiment_timeout_hours 0.3 Quantidade máxima de tempo em horas que todas as iterações combinadas podem levar antes que o experimento seja encerrado.
enable_early_stopping Verdadeiro Sinalizador para permitir o encerramento antecipado se a pontuação não estiver melhorando em curto prazo.
primary_metric spearman_correlation Métrica que você deseja otimizar. O modelo mais adequado é o escolhido com base nessa métrica.
featurization auto O valor auto permite que o experimento pré-processe os dados de entrada, incluindo o tratamento de dados ausentes, a conversão de texto em numérico e assim por diante.
verbosity logging.INFO Controla o nível de registro em log.
n_cross_validations 5 Número de divisões de validação cruzada para executar quando os dados de validação não são especificados.

O código a seguir envia o experimento:

import logging

automl_settings = {
   "iteration_timeout_minutes": 10,
   "experiment_timeout_hours": 0.3,
   "enable_early_stopping": True,
   "primary_metric": 'spearman_correlation',
   "featurization": 'auto',
   "verbosity": logging.INFO,
   "n_cross_validations": 5
}

O código a seguir permite que você use as configurações de treinamento definidas como um parâmetro **kwargs para um objeto AutoMLConfig. Além disso, especifique os dados de treinamento e o tipo de modelo, que é regression, neste caso.

from azureml.train.automl import AutoMLConfig

automl_config = AutoMLConfig(task='regression',
                      debug_log='automated_ml_errors.log',
                      training_data=x_train,
                      label_column_name="totalAmount",
                      **automl_settings)

Observação

As etapas de pré-processamento do Machine Learning Automatizado (normalização de recursos, manipulação de dados ausentes, conversão de texto em números etc.) tornam-se parte do modelo subjacente. Ao usar o modelo para previsões, as mesmas etapas de pré-processamento aplicadas durante o treinamento são aplicadas aos dados de entrada automaticamente.

Treinar o modelo de regressão automática

Criar um objeto de experimento em seu workspace. Um experimento atua como um contêiner para seus trabalhos individuais. Transmita o objeto automl_config definido para o experimento e defina a saída como True para exibir o andamento durante a execução.

Depois de iniciar o experimento, as atualizações de saída exibidas estão ativas à medida que o experimento é executado. Para cada iteração, você vê o tipo de modelo, a duração da execução e a precisão do treinamento. O campo BEST monitora a melhor pontuação de treinamento em execução com base no tipo de métrica:

from azureml.core.experiment import Experiment
experiment = Experiment(ws, "Tutorial-NYCTaxi")
local_run = experiment.submit(automl_config, show_output=True)

Esta é a saída:

Running on local machine
Parent Run ID: AutoML_1766cdf7-56cf-4b28-a340-c4aeee15b12b
Current status: DatasetFeaturization. Beginning to featurize the dataset.
Current status: DatasetEvaluation. Gathering dataset statistics.
Current status: FeaturesGeneration. Generating features for the dataset.
Current status: DatasetFeaturizationCompleted. Completed featurizing the dataset.
Current status: DatasetCrossValidationSplit. Generating individually featurized CV splits.
Current status: ModelSelection. Beginning model selection.

****************************************************************************************************
ITERATION: The iteration being evaluated.
PIPELINE: A summary description of the pipeline being evaluated.
DURATION: Time taken for the current iteration.
METRIC: The result of computing score on the fitted pipeline.
BEST: The best observed score thus far.
****************************************************************************************************

 ITERATION   PIPELINE                              DURATION     METRIC     BEST
       0   StandardScalerWrapper RandomForest          0:00:16      0.8746   0.8746
       1   MinMaxScaler RandomForest                 0:00:15      0.9468   0.9468
       2   StandardScalerWrapper ExtremeRandomTrees      0:00:09      0.9303   0.9468
       3   StandardScalerWrapper LightGBM             0:00:10      0.9424   0.9468
       4   RobustScaler DecisionTree                 0:00:09      0.9449   0.9468
       5   StandardScalerWrapper LassoLars            0:00:09      0.9440   0.9468
       6   StandardScalerWrapper LightGBM             0:00:10      0.9282   0.9468
       7   StandardScalerWrapper RandomForest          0:00:12      0.8946   0.9468
       8   StandardScalerWrapper LassoLars            0:00:16      0.9439   0.9468
       9   MinMaxScaler ExtremeRandomTrees            0:00:35      0.9199   0.9468
      10   RobustScaler ExtremeRandomTrees            0:00:19      0.9411   0.9468
      11   StandardScalerWrapper ExtremeRandomTrees      0:00:13      0.9077   0.9468
      12   StandardScalerWrapper LassoLars            0:00:15      0.9433   0.9468
      13   MinMaxScaler ExtremeRandomTrees            0:00:14      0.9186   0.9468
      14   RobustScaler RandomForest                 0:00:10      0.8810   0.9468
      15   StandardScalerWrapper LassoLars            0:00:55      0.9433   0.9468
      16   StandardScalerWrapper ExtremeRandomTrees      0:00:13      0.9026   0.9468
      17   StandardScalerWrapper RandomForest          0:00:13      0.9140   0.9468
      18   VotingEnsemble                         0:00:23      0.9471   0.9471
      19   StackEnsemble                          0:00:27      0.9463   0.9471

Explorar os resultados

Explore os resultados do treinamento automático com um widget do Jupyter. O widget permite que você veja um grafo e uma tabela de todas as iterações de trabalho individuais, em conjunto com metadados e métricas de precisão de treinamento. Além disso, você pode filtrar em métricas de precisão diferentes da métrica primária com o seletor de lista suspensa.

O código a seguir produz um grafo para explorar os resultados:

from azureml.widgets import RunDetails
RunDetails(local_run).show()

Os detalhes de execução do widget do Jupyter:

Captura de tela que mostra os detalhes de execução do widget do Jupyter no Estúdio do Azure Machine Learning.

O gráfico de gráfico para o widget do Jupyter:

Captura de tela que mostra o diagrama de gráfico do widget do Jupyter no Azure Estúdio do Azure Machine Learning.

Recuperar o melhor modelo

O código a seguir permite que você selecione o melhor modelo em suas iterações. A função get_output retorna a melhor execução e o modelo ajustado para a última invocação de ajuste. Ao usar as sobrecargas em get_output, você pode recuperar o modelo de melhor execução e ajuste para qualquer métrica registrada em log ou iteração em particular.

best_run, fitted_model = local_run.get_output()
print(best_run)
print(fitted_model)

Precisão do melhor modelo:

Use o melhor modelo para executar previsões no conjunto de dados de teste e prever as tarifas de táxi. A função predict usa o melhor modelo e prevê os valores de Y, custo da corrida, do conjunto de dados x_test.

O código a seguir imprime os primeiros 10 valores de custo previstos do y_predict conjunto de dados:

y_test = x_test.pop("totalAmount")

y_predict = fitted_model.predict(x_test)
print(y_predict[:10])

Calcule o root mean squared error dos resultados. Converta o dataframe y_test em uma lista para comparar com os valores previstos. A função mean_squared_error usa duas matrizes de valores e calcula o erro médio ao quadrado entre elas. Usar a raiz quadrada do resultado gera um erro nas mesmas unidades que a variável y, custo. Indica aproximadamente o quão distantes as previsões das tarifas de táxi estão das tarifas reais.

from sklearn.metrics import mean_squared_error
from math import sqrt

y_actual = y_test.values.flatten().tolist()
rmse = sqrt(mean_squared_error(y_actual, y_predict))
rmse

Execute o código a seguir para calcular o MAPE (desvio percentual absoluto médio) usando os conjuntos de dados y_actual e y_predict completos. Essa métrica calcula uma diferença absoluta entre cada valor previsto e real e somas todas as diferenças. Em seguida, expressa a soma como uma porcentagem do total de valores reais.

sum_actuals = sum_errors = 0

for actual_val, predict_val in zip(y_actual, y_predict):
   abs_error = actual_val - predict_val
   if abs_error < 0:
      abs_error = abs_error * -1

   sum_errors = sum_errors + abs_error
   sum_actuals = sum_actuals + actual_val

mean_abs_percent_error = sum_errors / sum_actuals
print("Model MAPE:")
print(mean_abs_percent_error)
print()
print("Model Accuracy:")
print(1 - mean_abs_percent_error)

Esta é a saída:

Model MAPE:
0.14353867606052823

Model Accuracy:
0.8564613239394718

Nas duas métricas de precisão da previsão, você vê que o modelo é razoavelmente bom em prever as tarifas de táxi por meio dos recursos do conjunto de dados, normalmente dentro de +- $ 4,00 e com erro de aproximadamente 15%.

O processo tradicional de desenvolvimento de modelo de machine learning é altamente intensivo em recursos. Ele requer um investimento de tempo e conhecimento de domínio significativo para executar e comparar os resultados de dezenas de modelos. A utilização do aprendizado de máquina automatizado é uma ótima maneira de testar rapidamente muitos modelos diferentes para seu cenário.

Limpar os recursos

Se você não planeja trabalhar em outros tutoriais do Azure Machine Learning, conclua as etapas a seguir para remover os recursos de que você não precisa mais.

Parar a computação

Se você usou uma computação, poderá parar a máquina virtual quando não estiver usando-a e reduzir seus custos:

  1. Acesse seu workspace no estúdio do Estúdio do Azure Machine Learning e selecione Computação.

  2. Na lista, selecione a computação que você deseja parar e, em seguida, selecione Parar.

Quando estiver pronto para usar a computação novamente, você poderá reiniciar a máquina virtual.

Excluir outros recursos

Se você não planeja usar os recursos criados neste tutorial, poderá excluí-los e evitar incorrer em encargos adicionais.

Siga essas etapas para remover o grupo de recursos e todos os recursos:

  1. No portal do Azure, acesse Grupo de recursos.

  2. Na lista, selecione o grupo de recursos que você criou neste tutorial e selecione Excluir grupo de recursos.

  3. Na página de confirmação, insira o nome do grupo de recursos e selecione Excluir.

Se você quiser manter o grupo de recursos e excluir apenas um único workspace, siga estas etapas:

  1. No portal do Azure, vá para o grupo de recursos que contém o workspace que você deseja remover.

  2. Selecione o workspace, selecione Propriedades e, em seguida, selecione Excluir.

Próxima etapa