Compartilhar via


Tutorial: categorizar flores íris usando um clustering k-means com ML.NET

Este tutorial ilustra como usar o ML.NET para criar um modelo de clustering para o conjunto de dados de flor Iris.

Neste tutorial, você aprenderá a:

  • Compreender o problema
  • Selecionar a tarefa de aprendizado de máquina apropriada
  • Preparar os dados
  • Carregar e transformar os dados
  • Escolher um algoritmo de aprendizado
  • Treinar o modelo
  • Usar o modelo para previsões

Pré-requisitos

Compreender o problema

Esse problema abrange como dividir o conjunto de flores Iris em grupos diferentes com base nas características da flor. Essas características são o comprimento e largura de uma sépala e o comprimento e a largura de uma pétala. Para este tutorial, considere que o tipo de cada flor é desconhecido. Você deseja conhecer a estrutura de um conjunto de dados por meio de suas características e prever como uma instância de dados se encaixa nessa estrutura.

Selecionar a tarefa de aprendizado de máquina apropriada

Como você não sabe a qual grupo cada flor pertence, escolha a tarefa aprendizado de máquina não supervisionado. Para dividir um conjunto de dados em grupos de forma que os elementos no mesmo grupo sejam mais semelhantes uns aos outros do que aos elementos de outros grupos, use a tarefa de aprendizado de máquina clustering.

Criar um aplicativo de console

  1. Crie um Aplicativo de Console em C# chamado "IrisFlowerClustering". Clique no botão Avançar.

  2. Escolha o .NET 6 como a estrutura a ser usada. Selecione o botão Criar.

  3. Crie um diretório chamado Dados em seu projeto para armazenar o conjunto de dados e os arquivos de modelo:

    No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar>Nova Pasta. Digite "Dados" e pressione Enter.

  4. Instale o pacote NuGet Microsoft.ML:

    Observação

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

    No Gerenciador de Soluções, clique com o botão direito no projeto e escolha Gerenciar Pacotes NuGet. Escolha "nuget.org" como a origem do Pacote, selecione a guia Procurar, procure Microsoft.ML e selecione o botão Instalar. Selecione o botão OK na caixa de diálogo Visualizar Alterações e selecione o botão Aceito na caixa de diálogo Aceitação da Licença, se concordar com o termos de licença para os pacotes listados.

Preparar os dados

  1. Baixe o conjunto de dados iris.data e salve-o na pasta Dados que você criou na etapa anterior. Para obter mais informações sobre o conjunto de dados Iris, confira a página da Wikipédia Iris flower data set (Conjunto de dados de flor Iris) e a página Iris Data Set (Conjunto de dados Iris), que é a fonte do conjunto de dados.

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

O arquivo iris.data contém cinco colunas que representam:

  • o comprimento da sépala em centímetros
  • a largura da sépala em centímetros
  • o comprimento da pétala em centímetros
  • a largura da pétala em centímetros
  • o tipo de flor Iris

Para exemplificar o clustering, este tutorial ignora a última coluna.

Criar classes de dados

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

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

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

  3. Adicione a seguinte diretiva using ao novo arquivo:

    using Microsoft.ML.Data;
    

Remova a definição de classe existente e adicione o código a seguir, que define as classes IrisData e ClusterPrediction, para o arquivo IrisData.cs:

public class IrisData
{
    [LoadColumn(0)]
    public float SepalLength;

    [LoadColumn(1)]
    public float SepalWidth;

    [LoadColumn(2)]
    public float PetalLength;

    [LoadColumn(3)]
    public float PetalWidth;
}

public class ClusterPrediction
{
    [ColumnName("PredictedLabel")]
    public uint PredictedClusterId;

    [ColumnName("Score")]
    public float[]? Distances;
}

IrisData é a classe de dados de entrada e tem definições de cada característica provenientes do conjunto de dados. Use o atributo LoadColumn para especificar os índices das colunas de origem no arquivo de conjunto de dados.

A classe ClusterPrediction representa a saída do modelo de clustering aplicado a uma instância de IrisData. Use o atributo ColumnName para associar os campos PredictedClusterId e Distances às colunas PredictedLabel e Score, respectivamente. No caso da tarefa clustering, essas colunas têm o seguinte significado:

  • A coluna PredictedLabel contém a ID do cluster previsto.
  • A coluna Score contém uma matriz com as distâncias euclidianas quadradas para os centroides de cluster. O comprimento da matriz é igual ao número de clusters.

Observação

Use o tipo float para representar valores de ponto flutuante nas classes de dados de entrada e previsão.

Definir dados e caminhos de modelo

Volte para o arquivo Program.cs e adicione dois campos para armazenar os caminhos no arquivo de conjunto de dados e no arquivo para salvar o modelo:

  • _dataPath contém o caminho para o arquivo com o conjunto de dados usado para treinar o modelo.
  • _modelPath contém o caminho para o arquivo em que o modelo treinado está armazenado.

Adicione o código a seguir nas instruções de uso para especificar esses caminhos:

string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip");

Criar o contexto de ML

Adicione as seguintes diretivas using adicionais ao início do arquivo Program.cs:

using Microsoft.ML;
using IrisFlowerClustering;

Substitua a linha Console.WriteLine("Hello World!"); pelo código a seguir:

var mlContext = new MLContext(seed: 0);

A classe Microsoft.ML.MLContext representa o ambiente de aprendizado de máquina e fornece mecanismos para pontos de entrada e de log para carregamento de dados, treinamento do modelo, previsão e outras tarefas. Isso é comparável conceitualmente ao uso de DbContext no Entity Framework.

Configurar o carregamento de dados

Adicione o seguinte código ao método MLContext para configurar a forma de carregamento de dados:

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

O método de extensão MLContext.Data.LoadFromTextFile genérico infere o esquema do conjunto de dados do tipo IrisData fornecido e retorna IDataView, que pode ser usado como entrada para transformadores.

Criar um pipeline de aprendizado

Para este tutorial, o pipeline de aprendizado da tarefa de clustering consiste nas duas seguintes etapas:

  • concatenar colunas carregadas em uma coluna Recursos, que é usada por um treinador de clustering;
  • usar um treinador KMeansTrainer para treinar o modelo usando o algoritmo de cluster K-means++.

Adicione os seguintes itens após carregar os dados:

string featuresColumnName = "Features";
var pipeline = mlContext.Transforms
    .Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
    .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: 3));

O código especifica que o conjunto de dados deve ser dividido em três clusters.

Treinar o modelo

As etapas adicionadas nas seções anteriores prepararam o pipeline para treinamento, no entanto, nenhuma foi executada. Adicione a seguinte linha na parte inferior do arquivo para executar o carregamento de dados e o treinamento de modelo:

var model = pipeline.Fit(dataView);

Salvar o modelo

Neste ponto, você tem um modelo que pode ser integrado em qualquer um dos seus aplicativos .NET existentes ou novos. Para salvar o modelo em um arquivo .zip, adicione o seguinte código abaixo da chamada ao método Fit:

using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
    mlContext.Model.Save(model, dataView.Schema, fileStream);
}

Usar o modelo para previsões

Para fazer previsões, use a classe PredictionEngine<TSrc,TDst> que usa instâncias do tipo de entrada por meio do pipeline transformador e produz instâncias do tipo de saída. Adicione a seguinte linha para criar uma instância dessa classe:

var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);

O PredictionEngine é uma API de conveniência, que permite executar uma previsão em uma única instância de dados. PredictionEngine não é thread-safe. É aceitável usá-lo em ambientes de thread único ou de protótipo. Para aprimorar o desempenho e o acesso thread-safe em ambientes de produção, use o serviço PredictionEnginePool, que cria um ObjectPool de objetos PredictionEngine para uso em todo o aplicativo. Confira este guia sobre como usar o PredictionEnginePool em uma API Web ASP.NET Core.

Observação

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

Crie a classe TestIrisData para hospedar as instâncias de dados de teste:

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

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

  3. Modifique a classe para ser estática, como no exemplo a seguir:

    static class TestIrisData
    

Este tutorial apresenta uma instância de dados de Iris dentro dessa classe. Você pode adicionar outros cenários para fazer experimentos com o modelo. Adicione o seguinte código à classe TestIrisData:

internal static readonly IrisData Setosa = new IrisData
{
    SepalLength = 5.1f,
    SepalWidth = 3.5f,
    PetalLength = 1.4f,
    PetalWidth = 0.2f
};

Para descobrir a qual cluster o item especificado pertence, volte para o arquivo Program.cs e adicione o seguinte código na parte inferior do arquivo:

var prediction = predictor.Predict(TestIrisData.Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances ?? Array.Empty<float>())}");

Execute o programa para ver qual cluster contém a instância de dados especificada e a distância quadrada daquela instância aos centroides do cluster. Os resultados devem ser semelhantes aos seguintes:

Cluster: 2
Distances: 11.69127 0.02159119 25.59896

Parabéns! Você agora construiu um modelo de aprendizado de máquina para clustering de Iris e o usou para fazer previsões. Encontre o código-fonte deste tutorial no repositório do GitHub dotnet/samples.

Próximas etapas

Neste tutorial, você aprendeu a:

  • Compreender o problema
  • Selecionar a tarefa de aprendizado de máquina apropriada
  • Preparar os dados
  • Carregar e transformar os dados
  • Escolher um algoritmo de aprendizado
  • Treinar o modelo
  • Usar o modelo para previsões

Confira nosso repositório GitHub para continuar aprendendo e encontrar mais amostras.