Partilhar via


Tutorial: Prever preços com a regressão com ML.NET

Este tutorial ilustra como criar um modelo de regressão com ML.NET para prever preços, especificamente, tarifas de táxi de Nova Iorque.

Neste tutorial, ficará a saber como:

  • Preparar e compreender os dados
  • Carregar e transformar os dados
  • Escolher um algoritmo de aprendizagem
  • Preparar o modelo
  • Avaliar o modelo
  • Utilizar o modelo para predições

Pré-requisitos

Criar uma aplicação de consola

  1. Crie uma Aplicação de Consola C# denominada "TaxiFarePrediction".

  2. Selecione .NET 6 como a arquitetura a utilizar. Clique no botão Criar.

  3. Crie um diretório com o nome Dados no seu projeto para armazenar o conjunto de dados e os ficheiros de modelo.

  4. Instale o Microsoft.ML e o Pacote NuGet Microsoft.ML.FastTree :

    Nota

    Este exemplo utiliza a versão estável mais recente dos pacotes NuGet mencionados, salvo indicação em contrário.

    No Explorador de Soluções, clique com o botão direito do rato no projeto e selecione Gerir Pacotes NuGet. Selecione "nuget.org" como origem do pacote, selecione o separador Procurar, procure Microsoft.ML, selecione o pacote na lista e selecione o botão Instalar . Selecione o botão OK na caixa de diálogo Pré-visualizar Alterações e, em seguida, selecione o botão Aceito na caixa de diálogo Aceitação da Licença se concordar com os termos de licença dos pacotes listados. Faça o mesmo para o pacote NuGet Microsoft.ML.FastTree .

Preparar e compreender os dados

  1. Transfira o taxi-fare-train.csv e os conjuntos de dadostaxi-fare-test.csv e guarde-os na pasta Dados que criou no passo anterior. Utilizamos estes conjuntos de dados para preparar o modelo de machine learning e, em seguida, avaliamos a precisão do modelo. Estes conjuntos de dados são originalmente do conjunto de dados Viagem de Táxi TLC de NYC.

  2. Em Explorador de Soluções, clique com o botão direito do rato em cada um dos ficheiros *.csv e selecione Propriedades. Em Avançadas, altere o valor de Copiar para Diretório de Saída para Copiar se for mais recente.

  3. Abra o taxi-fare-train.csv conjunto de dados e observe os cabeçalhos de coluna na primeira linha. Observe cada uma das colunas. Compreenda os dados e decida que colunas são funcionalidades e qual é a etiqueta.

É label a coluna que pretende prever. Os identificados Featuressão as entradas que dá ao modelo para prever o Label.

O conjunto de dados fornecido contém as seguintes colunas:

  • vendor_id: O ID do fornecedor de táxis é uma funcionalidade.
  • rate_code: O tipo de tarifa da viagem de táxi é uma característica.
  • passenger_count: O número de passageiros na viagem é uma característica.
  • trip_time_in_secs: O tempo que a viagem demorou. Quer prever a tarifa da viagem antes de a viagem estar concluída. Naquele momento, não sabes quanto tempo demoraria a viagem. Assim, o tempo de viagem não é uma funcionalidade e irá excluir esta coluna do modelo.
  • trip_distance: A distância da viagem é uma funcionalidade.
  • payment_type: O método de pagamento (dinheiro ou cartão de crédito) é uma funcionalidade.
  • fare_amount: A tarifa total de táxi paga é a etiqueta.

Criar classes de dados

Crie classes para os dados de entrada e as predições:

  1. Em Explorador de Soluções, clique com o botão direito do rato no projeto e, em seguida, selecione Adicionar>Novo Item.

  2. Na caixa de diálogo Adicionar Novo Item , selecione Classe e altere o campo Nome para TaxiTrip.cs. Em seguida, selecione o botão Adicionar .

  3. Adicione as seguintes using diretivas ao novo ficheiro:

    using Microsoft.ML.Data;
    

Remova a definição de classe existente e adicione o seguinte código, que tem duas classes TaxiTrip e TaxiTripFarePrediction, ao ficheiro TaxiTrip.cs :

public class TaxiTrip
{
    [LoadColumn(0)]
    public string? VendorId;

    [LoadColumn(1)]
    public string? RateCode;

    [LoadColumn(2)]
    public float PassengerCount;

    [LoadColumn(3)]
    public float TripTime;

    [LoadColumn(4)]
    public float TripDistance;

    [LoadColumn(5)]
    public string? PaymentType;

    [LoadColumn(6)]
    public float FareAmount;
}

public class TaxiTripFarePrediction
{
    [ColumnName("Score")]
    public float FareAmount;
}

TaxiTrip é a classe de dados de entrada e tem definições para cada uma das colunas do conjunto de dados. Utilize o LoadColumnAttribute atributo para especificar os índices das colunas de origem no conjunto de dados.

A TaxiTripFarePrediction classe representa os resultados previstos. Tem um único campo flutuante, FareAmount, com um ScoreColumnNameAttribute atributo aplicado. No caso da tarefa de regressão, a coluna Pontuação contém valores de etiqueta previstos.

Nota

Utilize o float tipo para representar valores de vírgula flutuante nas classes de dados de entrada e predição.

Definir caminhos de dados e modelos

Adicione as seguintes instruções adicionais using à parte superior do ficheiro Program.cs :

using Microsoft.ML;
using TaxiFarePrediction;

Tem de criar três campos para manter os caminhos para os ficheiros com conjuntos de dados e o ficheiro para guardar o modelo:

  • _trainDataPath contém o caminho para o ficheiro com o conjunto de dados utilizado para preparar o modelo.
  • _testDataPath contém o caminho para o ficheiro com o conjunto de dados utilizado para avaliar o modelo.
  • _modelPath contém o caminho para o ficheiro onde o modelo preparado é armazenado.

Adicione o seguinte código abaixo da secção usings para especificar esses caminhos e para a _textLoader variável:

string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-train.csv");
string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-test.csv");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");

Todas as operações ML.NET começam na classe MLContext. A inicialização mlContext cria um novo ambiente de ML.NET que pode ser partilhado entre os objetos de fluxo de trabalho de criação de modelos. É semelhante, conceptualmente, a DBContext no Entity Framework.

Inicializar variáveis

Substitua a Console.WriteLine("Hello World!") linha pelo seguinte código para declarar e inicializar a mlContext variável:

MLContext mlContext = new MLContext(seed: 0);

Adicione o seguinte como a próxima linha de código para chamar o Train método:

var model = Train(mlContext, _trainDataPath);

O Train() método executa as seguintes tarefas:

  • Carrega os dados.
  • Extrai e transforma os dados.
  • Prepara o modelo.
  • Devolve o modelo.

O Train método prepara o modelo. Crie este método imediatamente abaixo com o seguinte código:

ITransformer Train(MLContext mlContext, string dataPath)
{

}

Carregar e transformar dados

ML.NET utiliza a interface IDataView como uma forma flexível e eficiente de descrever dados tabulares numéricos ou de texto. IDataView pode carregar ficheiros de texto ou em tempo real (por exemplo, base de dados SQL ou ficheiros de registo). Adicione o seguinte código como a primeira linha do Train() método:

IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(dataPath, hasHeader: true, separatorChar: ',');

Como pretende prever a tarifa de viagem de táxi, a FareAmount coluna é a Label que vai prever (a saída do modelo). Utilize a CopyColumnsEstimator classe de transformação para copiar FareAmounte adicionar o seguinte código:

var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName:"FareAmount")

O algoritmo que prepara o modelo requer funcionalidades numéricas , pelo que tem de transformar os valores de dados categóricos (VendorId, RateCodee PaymentType) em números (VendorIdEncoded, RateCodeEncodede PaymentTypeEncoded). Para tal, utilize a classe de transformação OneHotEncodingTransformer , que atribui diferentes valores de chave numérica aos diferentes valores em cada uma das colunas e adicione o seguinte código:

.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "VendorIdEncoded", inputColumnName:"VendorId"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "RateCodeEncoded", inputColumnName: "RateCode"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "PaymentTypeEncoded", inputColumnName: "PaymentType"))

O último passo na preparação de dados combina todas as colunas de funcionalidades na coluna Funcionalidades com a mlContext.Transforms.Concatenate classe de transformação. Por predefinição, um algoritmo de aprendizagem processa apenas funcionalidades da coluna Funcionalidades . Adicione o seguinte código:

.Append(mlContext.Transforms.Concatenate("Features", "VendorIdEncoded", "RateCodeEncoded", "PassengerCount", "TripDistance", "PaymentTypeEncoded"))

Escolher um algoritmo de aprendizagem

Este problema é prever uma viagem de táxi em Nova Iorque. À primeira vista, pode parecer depender simplesmente da distância percorrida. No entanto, os vendedores de táxis em Nova Iorque cobram montantes variados para outros fatores, como passageiros adicionais ou pagamento com cartão de crédito em vez de dinheiro. Quer prever o valor do preço, que é um valor real, com base nos outros fatores do conjunto de dados. Para tal, selecione uma tarefa de aprendizagem automática de regressão .

Acrescente a tarefa de machine learning FastTreeRegressionTrainer às definições de transformação de dados ao adicionar o seguinte como a próxima linha de código em Train():

.Append(mlContext.Regression.Trainers.FastTree());

Preparar o modelo

Ajuste o modelo à preparação dataview e devolva o modelo preparado ao adicionar a seguinte linha de código no Train() método :

var model = pipeline.Fit(dataView);

O método Fit() prepara o seu modelo ao transformar o conjunto de dados e aplicar a preparação.

Devolva o modelo preparado com a seguinte linha de código no Train() método :

return model;

Avaliar o modelo

Em seguida, avalie o desempenho do modelo com os dados de teste para garantir a qualidade e a validação. Crie o Evaluate() método logo após Train(), com o seguinte código:

void Evaluate(MLContext mlContext, ITransformer model)
{

}

O Evaluate método executa as seguintes tarefas:

  • Carrega o conjunto de dados de teste.
  • Cria o avaliador de regressão.
  • Avalia o modelo e cria métricas.
  • Apresenta as métricas.

Adicione uma chamada ao novo método diretamente sob a chamada do Train método, com o seguinte código:

Evaluate(mlContext, model);

Carregue o conjunto de dados de teste com o método LoadFromTextFile( ). Avalie o modelo com este conjunto de dados como uma verificação de qualidade ao adicionar o seguinte código no Evaluate método :

IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(_testDataPath, hasHeader: true, separatorChar: ',');

Em seguida, transforme os Test dados ao adicionar o seguinte código a Evaluate():

var predictions = model.Transform(dataView);

O método Transform() faz predições para as linhas de entrada do conjunto de dados de teste.

O RegressionContext.Evaluate método calcula as métricas de qualidade para utilizar PredictionModel o conjunto de dados especificado. Devolve um RegressionMetrics objeto que contém as métricas gerais calculadas pelos avaliadores de regressão.

Para apresentá-las para determinar a qualidade do modelo, tem de obter as métricas primeiro. Adicione o seguinte código como a linha seguinte no Evaluate método :

var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");

Assim que tiver o conjunto de predição, o método Evaluate() avalia o modelo, que compara os valores previstos com os valores reais Labels no conjunto de dados de teste e devolve métricas sobre o desempenho do modelo.

Adicione o seguinte código para avaliar o modelo e produzir as métricas de avaliação:

Console.WriteLine();
Console.WriteLine($"*************************************************");
Console.WriteLine($"*       Model quality metrics evaluation         ");
Console.WriteLine($"*------------------------------------------------");

RSquared é outra métrica de avaliação dos modelos de regressão. RSquared assume valores entre 0 e 1. Quanto mais próximo estiver o valor de 1, melhor será o modelo. Adicione o seguinte código ao Evaluate método para apresentar o valor RSquared:

Console.WriteLine($"*       RSquared Score:      {metrics.RSquared:0.##}");

O RMS é uma das métricas de avaliação do modelo de regressão. Quanto mais baixo for, melhor será o modelo. Adicione o seguinte código ao Evaluate método para apresentar o valor RMS:

Console.WriteLine($"*       Root Mean Squared Error:      {metrics.RootMeanSquaredError:#.##}");

Utilizar o modelo para predições

Crie o TestSinglePrediction método logo após o Evaluate método, com o seguinte código:

void TestSinglePrediction(MLContext mlContext, ITransformer model)
{

}

O TestSinglePrediction método executa as seguintes tarefas:

  • Cria um único comentário de dados de teste.
  • Prevê o montante das tarifas com base nos dados de teste.
  • Combina dados de teste e predições para relatórios.
  • Apresenta os resultados previstos.

Adicione uma chamada ao novo método diretamente sob a chamada do Evaluate método, com o seguinte código:

TestSinglePrediction(mlContext, model);

Utilize o PredictionEngine para prever a tarifa ao adicionar o seguinte código a TestSinglePrediction():

var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(model);

PredictionEngine é uma API de conveniência, que lhe permite efetuar uma predição numa única instância de dados. PredictionEngine não é seguro para threads. É aceitável utilizar em ambientes de thread único ou protótipo. Para melhorar o desempenho e a segurança dos threads em ambientes de produção, utilize o PredictionEnginePool serviço, que cria um ObjectPool dos PredictionEngine objetos para utilização em toda a sua aplicação. Veja este guia sobre como utilizar PredictionEnginePool numa API Web ASP.NET Core.

Nota

PredictionEnginePool A extensão de serviço está atualmente em pré-visualização.

Este tutorial utiliza uma viagem de teste nesta classe. Posteriormente, pode adicionar outros cenários para experimentar o modelo. Adicione uma viagem para testar a predição do custo do modelo preparado no TestSinglePrediction() método ao criar uma instância de TaxiTrip:

var taxiTripSample = new TaxiTrip()
{
    VendorId = "VTS",
    RateCode = "1",
    PassengerCount = 1,
    TripTime = 1140,
    TripDistance = 3.75f,
    PaymentType = "CRD",
    FareAmount = 0 // To predict. Actual/Observed = 15.5
};

Em seguida, preveja a tarifa com base numa única instância dos dados da viagem de táxi e transmita-a PredictionEngine ao ao adicionar o seguinte como as linhas de código seguintes no TestSinglePrediction() método:

var prediction = predictionFunction.Predict(taxiTripSample);

A função Predict() faz uma predição numa única instância de dados.

Para apresentar a tarifa prevista da viagem especificada, adicione o seguinte código ao TestSinglePrediction método :

Console.WriteLine($"**********************************************************************");
Console.WriteLine($"Predicted fare: {prediction.FareAmount:0.####}, actual fare: 15.5");
Console.WriteLine($"**********************************************************************");

Execute o programa para ver a tarifa de táxi prevista para o seu caso de teste.

Parabéns! Criou com êxito um modelo de machine learning para prever tarifas de viagem de táxi, avaliou a sua precisão e utilizou-o para fazer previsões. Pode encontrar o código fonte para este tutorial no repositório do GitHub dotnet/samples .

Passos seguintes

Neste tutorial, ficou a saber como:

  • Preparar e compreender os dados
  • Criar um pipeline de aprendizagem
  • Carregar e transformar os dados
  • Escolher um algoritmo de aprendizagem
  • Preparar o modelo
  • Avaliar o modelo
  • Utilizar o modelo para predições

Avance para o próximo tutorial para saber mais.