Treinar modelo de regressão com ML automatizado e Python (SDK v1)
APLICA-SE A: Python SDK azureml v1
Neste artigo, você aprenderá a treinar um modelo de regressão com o SDK Python do Azure Machine Learning usando o Azure Machine Learning Automated ML. O modelo de regressão prevê as tarifas de passageiros para táxis que operam na cidade de Nova York (NYC). Você escreve código com o Python SDK para configurar um espaço de trabalho com dados preparados, treinar o modelo localmente com parâmetros personalizados e explorar os resultados.
O processo aceita dados de treinamento e definições de configuração. Ele itera automaticamente através de combinações de diferentes métodos de normalização/padronização de recursos, modelos e configurações de hiperparâmetros para chegar ao melhor modelo. O diagrama a seguir ilustra o fluxo do processo para o treinamento do modelo de regressão:
Pré-requisitos
Uma subscrição do Azure. Você pode criar uma conta gratuita ou paga do Azure Machine Learning.
Um espaço de trabalho ou instância de computação do Azure Machine Learning. Para preparar esses recursos, consulte Guia de início rápido: introdução ao Azure Machine Learning.
Obtenha os dados de exemplo preparados para os exercícios tutoriais carregando um bloco de anotações em seu espaço de trabalho:
Aceda à sua área de trabalho no estúdio do Azure Machine Learning, selecione Blocos de Notas e, em seguida, selecione o separador Exemplos.
Na lista de blocos de anotações, expanda o nó Samples>SDK v1>tutorials>regression-automl-nyc-taxi-data.
Selecione o bloco de anotações regression-automated-ml.ipynb .
Para executar cada célula do bloco de anotações como parte deste tutorial, selecione Clonar este arquivo.
Abordagem alternativa: Se preferir, você pode executar os exercícios tutoriais em um ambiente local. O tutorial está disponível no repositório de Blocos de Anotações do Azure Machine Learning no GitHub. Para essa abordagem, siga estas etapas para obter os pacotes necessários:
Instale o cliente completo
automl
.Execute o
pip install azureml-opendatasets azureml-widgets
comando em sua máquina local para obter os pacotes necessários.
Transferir e preparar dados
O pacote Open Datasets contém uma classe que representa cada fonte de dados (como NycTlcGreen
) para filtrar facilmente os parâmetros de data antes do download.
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
O primeiro passo é criar um dataframe para os dados do táxi. Quando você trabalha em um ambiente não-Spark, o pacote Open Datasets permite baixar apenas um mês de dados de cada vez com determinadas classes. Essa abordagem ajuda a evitar o MemoryError
problema que pode ocorrer com grandes conjuntos de dados.
Para baixar os dados do táxi, busque iterativamente um mês de cada vez. Antes de acrescentar o próximo conjunto de dados ao green_taxi_df
dataframe, faça uma amostra aleatória de 2.000 registros de cada mês e visualize os dados. Essa abordagem ajuda a evitar o inchaço 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:
ID do fornecedor | lpepPickupDatahora | lpepDropoffDatahora | passengerCount | tripDistância | puLocationId | doLocationId | captaçãoLongitude | captaçãoLatitude | dropoffLongitude | ... | Tipo de pagamento | fareAmount | extra | mtaImposto | melhoriaSobretaxa | gorjetaMontante | PortagensMontante | ehailFee | totalAmount | tripType |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 2015-01-30 18:38:09 | 2015-01-30 19:01:49 | 1 | 1,88 | Nenhuma | Nenhuma | -73.996155 | 40.690903 | -73.964287 | ... | 1 | 15.0 | 1.0 | 0.5 | 0.3 | 4.00 | 0.0 | Nenhuma | 20.80 | 1.0 |
1 | 2015-01-17 23:21:39 | 2015-01-17 23:35:16 | 1 | 2.70 | Nenhuma | Nenhuma | -73.978508 | 40.687984 | -73.955116 | ... | 1 | 11.5 | 0.5 | 0.5 | 0.3 | 2.55 | 0.0 | Nenhuma | 15.35 | 1.0 |
2 | 2015-01-16 01:38:40 | 2015-01-16 01:52:55 | 1 | 3.54 | Nenhuma | Nenhuma | -73.957787 | 40.721779 | -73.963005 | ... | 1 | 13,5 | 0.5 | 0.5 | 0.3 | 2.80 | 0.0 | Nenhuma | 17.60 | 1.0 |
2 | 2015-01-04 17:09:26 | 2015-01-04 17:16:12 | 1 | 1,00 | Nenhuma | Nenhuma | -73.919914 | 40.826023 | -73.904839 | ... | 2 | 6.5 | 0.0 | 0.5 | 0.3 | 0.00 | 0.0 | Nenhuma | 7.30 | 1.0 |
1 | 2015-01-14 10:10:57 | 2015-01-14 10:33:30 | 1 | 5.10 | Nenhuma | Nenhuma | -73.943710 | 40.825439 | -73.982964 | ... | 1 | 18.5 | 0.0 | 0.5 | 0.3 | 3.85 | 0.0 | Nenhuma | 23.15 | 1.0 |
2 | 2015-01-19 18:10:41 | 2015-01-19 18:32:20 | 1 | 7.41 | Nenhuma | Nenhuma | -73.940918 | 40.839714 | -73.994339 | ... | 1 | 24.0 | 0.0 | 0.5 | 0.3 | 4.80 | 0.0 | Nenhuma | 29.60 | 1.0 |
2 | 2015-01-01 15:44:21 | 2015-01-01 15:50:16 | 1 | 1.03 | Nenhuma | Nenhuma | -73.985718 | 40.685646 | -73.996773 | ... | 1 | 6.5 | 0.0 | 0.5 | 0.3 | 1.30 | 0.0 | Nenhuma | 8.60 | 1.0 |
2 | 2015-01-12 08:01:21 | 2015-01-12 08:14:52 | 5 | 2.94 | Nenhuma | Nenhuma | -73.939865 | 40.789822 | -73.952957 | ... | 2 | 12.5 | 0.0 | 0.5 | 0.3 | 0.00 | 0.0 | Nenhuma | 13.30 | 1.0 |
1 | 2015-01-16 21:54:26 | 2015-01-16 22:12:39 | 1 | 3.00 | Nenhuma | Nenhuma | -73.957939 | 40.721928 | -73.926247 | ... | 1 | 14,0 | 0.5 | 0.5 | 0.3 | 2.00 | 0.0 | Nenhuma | 17.30 | 1.0 |
2 | 2015-01-06 06:34:53 | 2015-01-06 06:44:23 | 1 | 2.31 | Nenhuma | Nenhuma | -73.943825 | 40.810257 | -73.943062 | ... | 1 | 10,0 | 0.0 | 0.5 | 0.3 | 2.00 | 0.0 | Nenhuma | 12.80 | 1.0 |
É útil remover algumas colunas que não são necessárias para treinamento ou criação de outros 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
O próximo passo é limpar os dados.
O código a seguir executa a describe()
função no novo dataframe para produzir estatísticas de resumo para cada campo:
green_taxi_df.describe()
A tabela a seguir mostra estatísticas de resumo para os campos restantes nos dados de exemplo:
ID do fornecedor | passengerCount | tripDistância | captaçãoLongitude | captaçãoLatitude | dropoffLongitude | dropoffLatitude | totalAmount | |
---|---|---|---|---|---|---|---|---|
count | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 |
média | 1.777625 | 1.373625 | 2.893981 | -73.827403 | 40.689730 | -73.819670 | 40.684436 | 14.892744 |
DST | 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 |
máx. | 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 outliers, 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. Esta abordagem filtra viagens de táxi mais longas ou viagens que são atípicas em relação à sua relação com outras características.
Em seguida, filtre o tripDistance
campo para valores maiores que zero, mas inferiores a 31 milhas (a distância de haversina entre os dois pares lat/long). Esta técnica elimina longas viagens atípicas que têm custos de viagem inconsistentes.
Por fim, o totalAmount
campo tem valores negativos para as tarifas de táxi, que não fazem sentido no contexto do modelo. O passengerCount
campo também contém dados incorretos onde 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 o 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 novamente nos dados para garantir que a describe()
limpeza funcione conforme o esperado. Agora você tem um conjunto preparado e limpo de dados de táxi, feriados e meteorológicos para usar no treinamento de modelos de aprendizado de máquina:
final_df.describe()
Configurar a área de trabalho
Crie um objeto de área de trabalho a partir da área de trabalho existente. Um espaço de trabalho é uma classe que aceita sua assinatura do Azure e informações de recursos. Ele também cria um recurso de nuvem para monitorar e acompanhar as execuções do seu modelo.
O código a seguir chama a Workspace.from_config()
função para ler o arquivo config.json e carregar os detalhes de autenticação em um objeto chamado ws
.
from azureml.core.workspace import Workspace
ws = Workspace.from_config()
O ws
objeto é usado em todo o resto do código neste tutorial.
Divida os dados em conjuntos de trem e teste
Divida os dados em conjuntos de treinamento e teste usando a train_test_split
função na biblioteca scikit-learn . Essa função segrega os dados no conjunto de dados x (recursos) para treinamento de modelo e no conjunto de dados y (valores para prever) para teste.
O test_size
parâmetro determina a porcentagem de dados a serem alocados para testes. O random_state
parâmetro define uma semente para o gerador aleatório, de modo que suas divisões de teste de trem sejam determinísticas.
O código a seguir chama a train_test_split
função 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)
O objetivo desta etapa é preparar pontos de dados para testar o modelo concluído que não são usados para treinar o modelo. Esses pontos são usados para medir a verdadeira precisão. Um modelo bem treinado é aquele que pode fazer previsões precisas a partir de dados invisíveis. Agora você tem dados preparados para o treinamento automático de um modelo de aprendizado de máquina.
Modelo de trem automático
Para treinar automaticamente um modelo, siga as seguintes etapas:
Defina as 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.
Envie o experimento para ajuste do modelo. Depois de enviar o experimento, o processo itera por meio de diferentes algoritmos de aprendizado de máquina e configurações de hiperparâmetros, aderindo às restrições definidas. Ele escolhe o modelo mais adequado otimizando uma métrica de precisão.
Definir configurações de treinamento
Defina o parâmetro do experimento e as configurações do modelo para treinamento. Veja a lista completa de 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 experiment_timeout_hours
parâmetro.
Property | Valor neste tutorial | Description |
---|---|---|
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 termine. |
enable_early_stopping |
True | Sinalize para permitir a rescisão antecipada se a pontuação não estiver melhorando no curto prazo. |
primary_metric |
spearman_correlation | Métrica que pretende otimizar. O modelo mais adequado é escolhido com base nesta métrica. |
featurization |
auto | O valor automático 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. |
n_cross_validations |
5 | Número de divisões de validação cruzada a serem executadas 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 suas configurações de treinamento definidas como um **kwargs
parâmetro para um AutoMLConfig
objeto. Além disso, você especifica seus 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)
Nota
As etapas automatizadas de pré-processamento de ML (normalização de recursos, manipulação de dados ausentes, conversão de texto em numérico e assim por diante) tornam-se parte do modelo subjacente. Quando você usa o modelo para previsões, as mesmas etapas de pré-processamento aplicadas durante o treinamento são aplicadas automaticamente aos dados de entrada.
Modelo de regressão automática de trem
Crie um objeto de experimento em seu espaço de trabalho. Um experimento funciona como um contêiner para seus trabalhos individuais. Passe o objeto definido automl_config
para o experimento e defina a saída como True para exibir o progresso durante o trabalho.
Depois de iniciar o experimento, a saída exibida é atualizada ao vivo à 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
rastreia a melhor pontuação de treinamento de corrida com base no seu tipo de métrica:
from azureml.core.experiment import Experiment
experiment = Experiment(ws, "Tutorial-NYCTaxi")
local_run = experiment.submit(automl_config, show_output=True)
Eis o resultado:
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
Explore os resultados
Explore os resultados do treinamento automático com um widget Jupyter. O widget permite que você veja um gráfico e uma tabela de todas as iterações de trabalho individuais, juntamente com métricas de precisão de treinamento e metadados. Além disso, você pode filtrar métricas de precisão diferentes da métrica principal com o seletor suspenso.
O código a seguir produz um gráfico para explorar os resultados:
from azureml.widgets import RunDetails
RunDetails(local_run).show()
Os detalhes de execução para o widget Jupyter:
O gráfico de gráfico para o widget Jupyter:
Recuperar o melhor modelo
O código a seguir permite que você selecione o melhor modelo de suas iterações. A get_output
função retorna a melhor execução e o modelo ajustado para a última chamada de ajuste. Usando as sobrecargas na get_output
função, você pode recuperar o melhor modelo de execução e ajuste para qualquer métrica registrada ou uma iteração específica.
best_run, fitted_model = local_run.get_output()
print(best_run)
print(fitted_model)
Testar a melhor precisão do modelo
Use o melhor modelo para executar previsões no conjunto de dados de teste para prever as tarifas de táxi. A predict
função usa o melhor modelo e prevê os valores de y, custo da viagem, a x_test
partir do conjunto de dados.
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 os root mean squared error
resultados. Converta o y_test
dataframe em uma lista e compare com os valores previstos. A mean_squared_error
função usa duas matrizes de valores e calcula o erro quadrado médio entre elas. Tomando a raiz quadrada do resultado dá um erro nas mesmas unidades que a variável y, custo. Ele indica aproximadamente o quão longe as previsões de 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 erro percentual absoluto médio (MAPE) usando os conjuntos completo y_actual
e y_predict
de dados. Esta métrica calcula uma diferença absoluta entre cada valor previsto e real e soma todas as diferenças. Em seguida, expressa essa soma como uma porcentagem do total dos 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)
Eis o resultado:
Model MAPE:
0.14353867606052823
Model Accuracy:
0.8564613239394718
A partir das duas métricas de precisão de previsão, você vê que o modelo é bastante bom em prever tarifas de táxi a partir dos recursos do conjunto de dados, normalmente dentro de +- $ 4,00, e aproximadamente 15% de erro.
O processo tradicional de desenvolvimento do modelo de aprendizado de máquina consome muitos recursos. Requer conhecimento de domínio significativo e investimento de tempo para executar e comparar os resultados de dezenas de modelos. Usar o aprendizado de máquina automatizado é uma ótima maneira de testar rapidamente muitos modelos diferentes para o seu cenário.
Clean up resources (Limpar 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 não precisa mais.
Parar a computação
Se você usou uma computação, pode parar a máquina virtual quando não estiver usando e reduzir seus custos:
Vá para seu espaço de trabalho no estúdio do Azure Machine Learning e selecione Computação.
Na lista, selecione o cálculo que pretende 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, pode excluí-los e evitar incorrer em cobranças adicionais.
Siga estas etapas para remover o grupo de recursos e todos os recursos:
No portal do Azure, aceda a Grupos de recursos.
Na lista, selecione o grupo de recursos criado neste tutorial e, em seguida, selecione Excluir grupo de recursos.
No prompt de confirmação, digite o nome do grupo de recursos e selecione Excluir.
Se você quiser manter o grupo de recursos e excluir apenas um único espaço de trabalho, siga estas etapas:
No portal do Azure, vá para o grupo de recursos que contém o espaço de trabalho que você deseja remover.
Selecione o espaço de trabalho, selecione Propriedades e, em seguida, selecione Excluir.