Compartilhar via


Tutorial: Analisar o sentimento dos comentários do site com classificação binária no ML.NET

Este tutorial mostra como criar um aplicativo de console do .NET que classifica o sentimento dos comentários do site e toma a ação apropriada. O classificador de sentimento binário usa C# no Visual Studio 2022.

Neste tutorial, você aprenderá como:

  • Criar um aplicativo de console
  • Preparar dados
  • Carregar os dados
  • Compilar e treinar o modelo
  • Avaliar o modelo
  • Usar o modelo para fazer uma previsão
  • Veja os resultados

Você pode encontrar o código-fonte deste tutorial no repositório dotnet/samples .

Pré-requisitos

Criar um aplicativo de console

  1. Crie um aplicativo de console C# chamado "SentimentAnalysis". Clique no botão Avançar.

  2. Escolha .NET 8 como a estrutura a ser usada. Clique no botão Criar .

  3. Crie um diretório chamado Dados em seu projeto para salvar os arquivos do conjunto de dados.

  4. Instale o Microsoft.ML Pacote NuGet:

    Observação

    Este exemplo usa a versão estável mais recente dos pacotes NuGet mencionados, a menos que indicado de outra forma.

    No Gerenciador de Soluções, clique com o botão direito do mouse em seu projeto e selecione Gerenciar Pacotes NuGet. Escolha "nuget.org" como a origem do pacote e selecione a guia Procurar . Pesquise Microsoft.ML, selecione o pacote desejado e selecione Instalar. Prossiga com a instalação concordando com os termos de licença do pacote escolhido.

Preparar seus dados

Observação

Os conjuntos de dados deste tutorial são de 'De Grupo a Rótulos Individuais usando Recursos Profundos', Kotzias et. Al. KDD 2015 e hospedado no Repositório de Machine Learning da UCI – Dua, D. e Karra Taniskidou, E. (2017). Repositório de Machine Learning da UCI [http://archive.ics.uci.edu/ml]. Irvine, CA: Universidade da Califórnia, Escola de Informações e Ciência da Computação.

  1. Baixe o arquivo ZIP do conjunto de dados de sentenças rotuladas por sentimento da UCI e descompacte-o.

  2. Copie o yelp_labelled.txt arquivo para o diretório de dados que você criou.

  3. No Gerenciador de Soluções, clique com o botão direito do mouse no yelp_labelled.txt arquivo e selecione Propriedades. Em Avançado, altere o valor de Copiar para Diretório de Saída para Copiar se for mais recente.

Criar classes e definir caminhos

  1. Adicione as seguintes diretivas adicionais using à parte superior do arquivo Program.cs :

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using SentimentAnalysis;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Adicione o seguinte código à linha logo abaixo das using diretivas, para criar um campo para manter o caminho do arquivo do conjunto de dados baixado recentemente:

    string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
    
  3. Em seguida, crie classes para seus dados de entrada e previsões. Adicione uma nova classe ao seu projeto:

    • No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar>Novo Item.

    • Na caixa de diálogo Adicionar Novo Item , selecione Classe e altere o campo Nome para SentimentData.cs. Em seguida, selecione Adicionar.

  4. O arquivo SentimentData.cs é aberto no editor de código. Adicione a seguinte using diretiva à parte superior do SentimentData.cs:

    using Microsoft.ML.Data;
    
  5. Remova a definição de classe existente e adicione o seguinte código, que tem duas classes SentimentData e SentimentPrediction, ao arquivo SentimentData.cs :

    public class SentimentData
    {
        [LoadColumn(0)]
        public string? SentimentText;
    
        [LoadColumn(1), ColumnName("Label")]
        public bool Sentiment;
    }
    
    public class SentimentPrediction : SentimentData
    {
    
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

Como os dados foram preparados

A classe de conjunto de dados de entrada, SentimentData, tem um string para comentários do usuário (SentimentText) e um valor bool (Sentiment) de 1 (positivo) ou 0 (negativo) para sentimento. Ambos os campos têm atributos LoadColumn anexados a eles, o que descreve a ordem do arquivo de dados de cada campo. Além disso, a Sentiment propriedade tem um atributo ColumnName para designá-la como o Label campo. O arquivo de exemplo a seguir não tem uma linha de cabeçalho e tem esta aparência:

SentimentText Sentimento (rótulo)
Garçonete estava um pouco lenta no serviço. 0
A crosta não é boa. 0
Uau... Amei esse lugar. 1
O serviço foi muito rápido. 1

SentimentPrediction é a classe de previsão usada após o treinamento do modelo. Ele herda de SentimentData modo que a entrada SentimentText possa ser exibida junto com a previsão de saída. O Prediction booliano é o valor que o modelo prevê quando fornecido com a nova entrada SentimentText.

A classe SentimentPrediction de saída contém duas outras propriedades calculadas pelo modelo: Score - a pontuação bruta calculada pelo modelo e Probability - a pontuação calibrada para a probabilidade de o texto ter sentimento positivo.

Para este tutorial, a propriedade mais importante é Prediction.

Carregar os dados

Os dados em ML.NET são representados como uma interface IDataView. IDataView é uma maneira flexível e eficiente de descrever dados tabulares (numérico e texto). Os dados podem ser carregados de um arquivo de texto ou em tempo real (por exemplo, banco de dados SQL ou arquivos de log) para um IDataView objeto.

A classe MLContext é um ponto de partida para todas as operações de ML.NET. A inicialização mlContext cria um novo ambiente ML.NET que pode ser compartilhado entre os objetos de fluxo de trabalho de criação de modelo. É semelhante, conceitualmente, ao DBContext Entity Framework.

Prepare o aplicativo e carregue os dados:

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

    MLContext mlContext = new MLContext();
    
  2. Adicione o seguinte como a próxima linha de código:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Crie um LoadData() método na parte inferior do Program.cs arquivo usando o seguinte código:

    TrainTestData LoadData(MLContext mlContext)
    {
    
    }
    

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

    • Carrega os dados.
    • Divide o conjunto de dados carregado em conjuntos de dados de treinamento e teste.
    • Retorna os conjuntos de dados de treinamento e teste divididos.
  4. Adicione o seguinte código como a primeira linha do LoadData() método:

    IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
    

    O método LoadFromTextFile() define o esquema de dados e as leituras no arquivo. Ele recebe as variáveis de caminho de dados e retorna um IDataView.

Dividir o conjunto de dados para treinamento e teste de modelo

Ao preparar um modelo, você usa parte do conjunto de dados para treiná-lo e parte do conjunto de dados para testar a precisão do modelo.

  1. Para dividir os dados carregados nos conjuntos de dados necessários, adicione o seguinte código como a próxima linha no LoadData() método:

    TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
    

    O código anterior usa o método TrainTestSplit() para dividir o conjunto de dados carregado em conjuntos de dados de treinamento e teste e devolvê-los na DataOperationsCatalog.TrainTestData classe. Especifique com o parâmetro testFraction a porcentagem de dados do conjunto de testes. O padrão é 10%, nesse caso, você usa 20% para avaliar mais dados.

  2. Retorne no splitDataView final do LoadData() método:

    return splitDataView;
    

Compilar e treinar o modelo

  1. Adicione a seguinte chamada ao BuildAndTrainModelmétodo abaixo da chamada ao LoadData método:

    ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
    

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

    • Extrai e transforma os dados.
    • Treina o modelo.
    • Prevê o sentimento com base nos dados de teste.
    • Retorna o modelo.
  2. Crie o BuildAndTrainModel() método, abaixo do LoadData() método, usando o seguinte código:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Extrair e transformar os dados

  1. Chame FeaturizeText como a próxima linha de código:

    var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
    

    O FeaturizeText() método no código anterior converte a coluna de texto (SentimentText) em uma coluna de tipo Features de chave numérica usada pelo algoritmo de machine learning e a adiciona como uma nova coluna de conjunto de dados:

    SentimentText Sentimento Features
    Garçonete estava um pouco lenta no serviço. 0 [0.76, 0.65, 0.44, …]
    A crosta não é boa. 0 [0.98, 0.43, 0.54, …]
    Uau... Amei esse lugar. 1 [0.35, 0.73, 0.46, …]
    O serviço foi muito rápido. 1 [0.39, 0, 0.75, …]

Adicionar um algoritmo de aprendizado

Esse aplicativo usa um algoritmo de classificação que categoriza itens ou linhas de dados. O aplicativo categoriza os comentários do site como positivos ou negativos, portanto, use a tarefa de classificação binária.

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

.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));

O SdcaLogisticRegressionBinaryTrainer é o algoritmo de treinamento de classificação. Isso é acrescentado ao estimator e aceita o SentimentText caracterizado (Features) e os parâmetros de entrada Label para aprender com os dados históricos.

Treinar o modelo

Ajuste o modelo aos splitTrainSet dados e retorne o modelo treinado adicionando o seguinte como a próxima linha de código no BuildAndTrainModel() método:

Console.WriteLine("=============== Create and Train the Model ===============");
var model = estimator.Fit(splitTrainSet);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();

O método Fit() treina seu modelo transformando o conjunto de dados e aplicando o treinamento.

Retornar o modelo treinado para uso para avaliação

Retorne o modelo no final do BuildAndTrainModel() método:

return model;

Avaliar o modelo

Depois que o modelo for treinado, use os dados de teste para validar o desempenho do modelo.

  1. Crie o Evaluate() método, logo depois BuildAndTrainModel(), com o seguinte código:

    void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet)
    {
    
    }
    

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

    • Carrega o conjunto de dados de teste.
    • Cria o avaliador BinaryClassification.
    • Avalia o modelo e cria métricas.
    • Exibe as métricas.
  2. Adicione uma chamada ao novo método abaixo da chamada de BuildAndTrainModel método usando o seguinte código:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Transforme os splitTestSet dados adicionando o seguinte código a Evaluate():

    Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
    IDataView predictions = model.Transform(splitTestSet);
    

    O código anterior usa o método Transform() para fazer previsões para várias linhas de entrada fornecidas de um conjunto de dados de teste.

  4. Avalie o modelo adicionando o seguinte como a próxima linha de código no Evaluate() método:

    CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
    

Depois de ter o conjunto de previsão (predictions), o método Evaluate() avalia o modelo, que compara os valores previstos com o real Labels no conjunto de dados de teste e retorna um objeto CalibratedBinaryClassificationMetrics sobre como o modelo está sendo executado.

Exibindo as métricas para validação de modelo

Use o seguinte código para exibir as métricas:

Console.WriteLine();
Console.WriteLine("Model quality metrics evaluation");
Console.WriteLine("--------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.AreaUnderRocCurve:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
Console.WriteLine("=============== End of model evaluation ===============");
  • A Accuracy métrica obtém a precisão de um modelo, que é a proporção de previsões corretas no conjunto de testes.

  • A AreaUnderRocCurve métrica indica o quão confiante o modelo está classificando corretamente as classes positivas e negativas. Você quer que seja o AreaUnderRocCurve mais próximo possível de um.

  • A F1Score métrica obtém a pontuação F1 do modelo, que é uma medida de equilíbrio entre precisão e recall. Você quer que seja o F1Score mais próximo possível de um.

Prever o resultado dos dados de teste

  1. Crie o UseModelWithSingleItem() método, logo após o Evaluate() método, usando o seguinte código:

    void UseModelWithSingleItem(MLContext mlContext, ITransformer model)
    {
    
    }
    

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

    • Cria um único comentário de dados de teste.
    • Prevê o sentimento com base nos dados de teste.
    • Combina dados de teste e previsões para relatórios.
    • Exibe os resultados previstos.
  2. Adicione uma chamada ao novo método diretamente após a chamada do método Evaluate() usando o seguinte código:

    UseModelWithSingleItem(mlContext, model);
    
  3. Adicione o seguinte código para criar como a primeira linha no UseModelWithSingleItem() Método:

    PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
    

    O PredictionEngine é uma API de conveniência, que permite que você execute uma previsão em uma única instância de dados. PredictionEngine não é thread-safe. É aceitável usar em ambientes monothread ou de protótipo. Para melhorar o desempenho e a segurança de threads em ambientes de produção, use o PredictionEnginePool serviço, que cria um ObjectPool dos PredictionEngine objetos para uso em todo o aplicativo. Consulte este guia sobre como usar PredictionEnginePool em uma API Web do ASP.NET Core.

    Observação

    PredictionEnginePool A extensão de serviço está atualmente em versão prévia.

  4. Adicione um comentário para testar a previsão do modelo treinado no UseModelWithSingleItem() método criando uma instância de SentimentData:

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Passe os dados de comentário de teste ao PredictionEngine adicionando o seguinte como as próximas linhas de código no método UseModelWithSingleItem().

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    A função Predict() faz uma previsão em uma única linha de dados.

  6. Exibir SentimentText e a previsão de sentimento correspondente usando o seguinte código:

    Console.WriteLine();
    Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
    
    Console.WriteLine();
    Console.WriteLine($"Sentiment: {resultPrediction.SentimentText} | Prediction: {(Convert.ToBoolean(resultPrediction.Prediction) ? "Positive" : "Negative")} | Probability: {resultPrediction.Probability} ");
    
    Console.WriteLine("=============== End of Predictions ===============");
    Console.WriteLine();
    

Usar o modelo para previsão

Implantar e prever itens em lotes

  1. Crie o UseModelWithBatchItems() método, logo após o UseModelWithSingleItem() método, usando o seguinte código:

    void UseModelWithBatchItems(MLContext mlContext, ITransformer model)
    {
    
    }
    

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

    • Cria dados de teste em lote.
    • Prevê o sentimento com base nos dados de teste.
    • Combina dados de teste e previsões para relatórios.
    • Exibe os resultados previstos.
  2. Adicione uma chamada ao novo método diretamente após a chamada do método UseModelWithSingleItem() usando o seguinte código:

    UseModelWithBatchItems(mlContext, model);
    
  3. Adicione alguns comentários para testar as previsões do modelo treinado no UseModelWithBatchItems() método:

    IEnumerable<SentimentData> sentiments = new[]
    {
        new SentimentData
        {
            SentimentText = "This was a horrible meal"
        },
        new SentimentData
        {
            SentimentText = "I love this spaghetti."
        }
    };
    

Prever sentimento de comentário

Use o modelo para prever o sentimento de dados de comentário usando o método Transform():

IDataView batchComments = mlContext.Data.LoadFromEnumerable(sentiments);

IDataView predictions = model.Transform(batchComments);

// Use model to predict whether comment data is Positive (1) or Negative (0).
IEnumerable<SentimentPrediction> predictedResults = mlContext.Data.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false);

Combinar e exibir as previsões

Crie um cabeçalho para as previsões usando o seguinte código:

Console.WriteLine();

Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");

Como SentimentPrediction é herdado, SentimentDatao Transform() método preenchido SentimentText com os campos previstos. À medida que o ML.NET processa, cada componente adiciona suas colunas, e isso facilita a exibição dos resultados.

foreach (SentimentPrediction prediction  in predictedResults)
{
    Console.WriteLine($"Sentiment: {prediction.SentimentText} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative")} | Probability: {prediction.Probability} ");
}
Console.WriteLine("=============== End of predictions ===============");

Results

Seus resultados devem ser semelhantes aos seguintes. Durante o processamento, as mensagens são exibidas. Você pode ver avisos ou mensagens de processamento. Eles foram removidos dos seguintes resultados para maior clareza.

Model quality metrics evaluation
--------------------------------
Accuracy: 83.96%
Auc: 90.51%
F1Score: 84.04%

=============== End of model evaluation ===============

=============== Prediction Test of model with a single sample and test dataset ===============

Sentiment: This was a very bad steak | Prediction: Negative | Probability: 0.1027377
=============== End of Predictions ===============

=============== Prediction Test of loaded model with a multiple samples ===============

Sentiment: This was a horrible meal | Prediction: Negative | Probability: 0.1369192
Sentiment: I love this spaghetti. | Prediction: Positive | Probability: 0.9960636
=============== End of predictions ===============

=============== End of process ===============
Press any key to continue . . .

Parabéns! Agora você criou com êxito um modelo de machine learning para classificar e prever o sentimento das mensagens.

A criação de modelos bem-sucedidos é um processo iterativo. Esse modelo tem menor qualidade inicial, pois o tutorial usa pequenos conjuntos de dados para fornecer treinamento rápido de modelo. Se você não estiver satisfeito com a qualidade do modelo, poderá tentar melhorá-lo fornecendo conjuntos de dados de treinamento maiores ou escolhendo algoritmos de treinamento diferentes com hipermetrâmetros diferentes para cada algoritmo.

Você pode encontrar o código-fonte deste tutorial no repositório dotnet/samples .

Próximas etapas

Neste tutorial, você aprendeu a:

  • Criar um aplicativo de console
  • Preparar dados
  • Carregar os dados
  • Compilar e treinar o modelo
  • Avaliar o modelo
  • Usar o modelo para fazer uma previsão
  • Veja os resultados

Avançar para o próximo tutorial para saber mais