Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Saiba como criar um aplicativo de detecção de anomalias para dados de vendas de produtos. Este tutorial cria um aplicativo de console do .NET usando C# no Visual Studio.
Neste tutorial, você aprenderá como:
- Carregar os dados
- Criar uma transformação para detecção de anomalias de pico
- Detectar anomalias de pico com a transformação
- Criar uma transformação para detecção de anomalias de ponto de alteração
- Detectar anomalias de ponto de alteração com a transformação
Você pode encontrar o código-fonte deste tutorial no repositório dotnet/samples .
Pré-requisitos
Visual Studio 2022 ou posterior com a carga de trabalho de Desenvolvimento da Área de Trabalho do .NET instalada.
Observação
O formato product-sales.csv de dados é baseado no conjunto de dados "Vendas de Shampoo durante um período de três anos" originalmente proveniente do DataMarket e fornecido pela TSDL (Time Series Data Library), criado por Rob Hyndman.
Conjunto de dados "Vendas de Shampoo durante um período de três anos" licenciado sob a licença de abertura padrão do DataMarket.
Criar um aplicativo de console
Crie um aplicativo de console C# chamado "ProductSalesAnomalyDetection". Clique no botão Avançar.
Escolha .NET 8 como a estrutura a ser usada. Clique no botão Criar .
Crie um diretório chamado Dados em seu projeto para salvar os arquivos do conjunto de dados.
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, selecione a guia Procurar, pesquise Microsoft.ML e selecione Instalar. Selecione o botão OK na caixa de diálogo Alterações de Visualização e, em seguida, selecione o botão I Accept na caixa de diálogo Aceitação da Licença se você concordar com os termos de licença dos pacotes listados. Repita estas etapas para Microsoft.ML.TimeSeries.
Adicione as seguintes
usingdiretivas na parte superior do arquivo Program.cs :using Microsoft.ML; using ProductSalesAnomalyDetection;
Baixe seus dados
Baixe o conjunto de dados e salve-o na pasta Dados que você criou anteriormente:
Clique com o botão direito do mouse noproduct-sales.csv e selecione "Salvar Link (ou Destino) Como..."
Salve o arquivo *.csv na pasta Dados ou, depois de salvá-lo em outro lugar, mova o arquivo *.csv para a pasta Dados .
No Gerenciador de Soluções, clique com o botão direito do mouse no arquivo *.csv e selecione Propriedades. Em Avançado, altere o valor de Copiar para Diretório de Saída para Copiar se for mais recente.
A tabela a seguir é uma visualização de dados do arquivo *.csv:
| Mês | ProductSales |
|---|---|
| 1-Jan | 271 |
| 2-Jan | 150.9 |
| ..... | ..... |
| 1-Feb | 199.3 |
| ..... | ..... |
Criar classes e definir caminhos
Em seguida, defina suas estruturas de dados de classe de entrada e previsão.
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 ProductSalesData.cs. Em seguida, selecione Adicionar.
O arquivo ProductSalesData.cs é aberto no editor de código.
Adicione a seguinte
usingdiretiva à parte superior do ProductSalesData.cs:using Microsoft.ML.Data;Remova a definição de classe existente e adicione o seguinte código, que tem duas classes
ProductSalesDataeProductSalesPrediction, ao arquivo ProductSalesData.cs :public class ProductSalesData { [LoadColumn(0)] public string? Month; [LoadColumn(1)] public float numSales; } public class ProductSalesPrediction { //vector to hold alert,score,p-value values [VectorType(3)] public double[]? Prediction { get; set; } }ProductSalesDataespecifica uma classe de dados de entrada. O atributo LoadColumn especifica quais colunas (por índice de coluna) no conjunto de dados devem ser carregadas.ProductSalesPredictionespecifica a classe de dados de previsão. Para detecção de anomalias, a previsão consiste em um alerta para indicar se há uma anomalia, uma pontuação bruta e um valor p. Quanto mais próximo o valor p for 0, maior a probabilidade de ocorrer uma anomalia.Crie dois campos globais para manter o caminho do arquivo do conjunto de dados baixado recentemente e o caminho do arquivo de modelo salvo:
-
_dataPathtem o caminho para o conjunto de dados usado para treinar o modelo. -
_docsizetem o número de registros no arquivo de conjunto de dados. Você usará_docSizepara calcularpvalueHistoryLength.
-
Adicione o seguinte código à linha logo abaixo das
usingdiretivas para especificar esses caminhos:string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "product-sales.csv"); //assign the Number of records in dataset file to constant variable const int _docsize = 36;
Inicializar variáveis
Substitua a
Console.WriteLine("Hello World!")linha pelo seguinte código para declarar e inicializar amlContextvariável:MLContext mlContext = new MLContext();A classe MLContext é um ponto de partida para todas as operações de ML.NET e a inicialização
mlContextcria um novo ambiente ML.NET que pode ser compartilhado entre os objetos de fluxo de trabalho de criação de modelo. É semelhante, conceitualmente, aoDBContextEntity Framework.
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 de outras fontes (por exemplo, banco de dados SQL ou arquivos de log) para um IDataView objeto.
Adicione o seguinte código depois de criar a
mlContextvariável:IDataView dataView = mlContext.Data.LoadFromTextFile<ProductSalesData>(path: _dataPath, hasHeader: true, separatorChar: ',');O LoadFromTextFile() define o esquema de dados e as leituras no arquivo. Ele usa as variáveis de caminho de dados e retorna um
IDataView.
Detecção de anomalias de série temporal
A detecção de anomalias sinaliza eventos ou comportamentos inesperados ou incomuns. Ele dá pistas de onde procurar problemas e ajuda você a responder a pergunta "Isso é estranho?".
A detecção de anomalias é o processo de detecção de exceções de dados de série temporal; aponta para uma determinada série temporal de entrada em que o comportamento não é o esperado ou "estranho".
A detecção de anomalias pode ser útil de várias maneiras. Por exemplo:
Se você tem um carro, você pode querer saber: Esta leitura do medidor de óleo é normal, ou eu tenho um vazamento? Se você estiver monitorando o consumo de energia, deseja saber: Há uma interrupção?
Há dois tipos de anomalias de série temporal que podem ser detectadas:
Picos indicam intermitências temporárias de comportamento anômalo no sistema.
Os pontos de alteração indicam o início das alterações persistentes ao longo do tempo no sistema.
Em ML.NET, os algoritmos de detecção de ponto de alteração de IID ou detecção de ponto de alteração IID são adequados para conjuntos de dados independentes e distribuídos de forma idêntica. Eles assumem que os dados de entrada são uma sequência de pontos de dados que são amostrados independentemente de uma distribuição estacionária.
Ao contrário dos modelos nos outros tutoriais, as transformações do detector de anomalias de série temporal operam diretamente nos dados de entrada. O IEstimator.Fit() método não precisa de dados de treinamento para produzir a transformação. No entanto, ele precisa do esquema de dados, que é fornecido por uma exibição de dados gerada a partir de uma lista vazia de ProductSalesData.
Você analisará os mesmos dados de vendas de produtos para detectar picos e pontos de alteração. O processo de criação e treinamento do modelo é o mesmo para detecção de pico e detecção de ponto de alteração; a principal diferença é o algoritmo de detecção específico usado.
Detecção de pico
O objetivo da detecção de pico é identificar intermitências repentinas, mas temporárias, que diferem significativamente da maioria dos valores de dados da série temporal. É importante detectar esses itens, eventos ou observações raros suspeitos em tempo hábil para serem minimizados. A abordagem a seguir pode ser usada para detectar uma variedade de anomalias, como: interrupções, ataques cibernéticos ou conteúdo da Web viral. A imagem a seguir é um exemplo de picos em um conjunto de dados de série temporal:
Adicionar o método CreateEmptyDataView()
Adicione o seguinte método a Program.cs:
IDataView CreateEmptyDataView(MLContext mlContext) {
// Create empty DataView. We just need the schema to call Fit() for the time series transforms
IEnumerable<ProductSalesData> enumerableData = new List<ProductSalesData>();
return mlContext.Data.LoadFromEnumerable(enumerableData);
}
O CreateEmptyDataView() produz um objeto de exibição de dados vazio com o esquema correto a ser usado como entrada para o IEstimator.Fit() método.
Criar o método DetectSpike()
O método DetectSpike():
- Cria a transformação do avaliador.
- Detecta picos com base em dados históricos de vendas.
- Exibe os resultados.
Crie o
DetectSpike()método na parte inferior do arquivo Program.cs usando o seguinte código:DetectSpike(MLContext mlContext, int docSize, IDataView productSales) { }Use o IidSpikeEstimator para treinar o modelo para detecção de pico. Adicione-o
DetectSpike()ao método com o seguinte código:var iidSpikeEstimator = mlContext.Transforms.DetectIidSpike(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, pvalueHistoryLength: docSize / 4);Crie a transformação de detecção de pico adicionando o seguinte como a próxima linha de código no
DetectSpike()método:Dica
Os
confidenceparâmetros e ospvalueHistoryLengthparâmetros afetam como os picos são detectados.confidencedetermina o quão sensível é o seu modelo para picos. Quanto menor a confiança, maior a probabilidade de o algoritmo detectar picos "menores". OpvalueHistoryLengthparâmetro define o número de pontos de dados em uma janela deslizante. O valor desse parâmetro geralmente é uma porcentagem de todo o conjunto de dados. Quanto menor,pvalueHistoryLengthmais rápido o modelo esquece os picos grandes anteriores.ITransformer iidSpikeTransform = iidSpikeEstimator.Fit(CreateEmptyDataView(mlContext));Adicione a seguinte linha de código para transformar os
productSalesdados como a próxima linha noDetectSpike()método:IDataView transformedData = iidSpikeTransform.Transform(productSales);O código anterior usa o método Transform() para fazer previsões para várias linhas de entrada de um conjunto de dados.
Converta-o
transformedDataem uma exibição fortemente tipadaIEnumerablepara facilitar o uso do método CreateEnumerable() com o seguinte código:var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);Crie uma linha de cabeçalho de exibição usando o seguinte Console.WriteLine() código:
Console.WriteLine("Alert\tScore\tP-Value");Você exibirá as seguintes informações nos resultados da detecção de pico:
-
Alertindica um alerta de pico para um determinado ponto de dados. -
Scoreé oProductSalesvalor de um determinado ponto de dados no conjunto de dados. -
P-ValueO "P" significa probabilidade. Quanto mais próximo o valor p for 0, maior a probabilidade de o ponto de dados ser uma anomalia.
-
Use o seguinte código para iterar e
predictionsIEnumerableexibir os resultados:foreach (var p in predictions) { if (p.Prediction is not null) { var results = $"{p.Prediction[0]}\t{p.Prediction[1]:f2}\t{p.Prediction[2]:F2}"; if (p.Prediction[0] == 1) { results += " <-- Spike detected"; } Console.WriteLine(results); } } Console.WriteLine("");Adicione a chamada ao
DetectSpike()método abaixo da chamada aoLoadFromTextFile()método:DetectSpike(mlContext, _docsize, dataView);
Resultados da detecção de pico
Seus resultados devem ser semelhantes aos seguintes. Durante o processamento, as mensagens são exibidas. Você pode ver avisos ou mensagens de processamento. Algumas das mensagens foram removidas dos seguintes resultados para maior clareza.
Detect temporary changes in pattern
=============== Training the model ===============
=============== End of training process ===============
Alert Score P-Value
0 271.00 0.50
0 150.90 0.00
0 188.10 0.41
0 124.30 0.13
0 185.30 0.47
0 173.50 0.47
0 236.80 0.19
0 229.50 0.27
0 197.80 0.48
0 127.90 0.13
1 341.50 0.00 <-- Spike detected
0 190.90 0.48
0 199.30 0.48
0 154.50 0.24
0 215.10 0.42
0 278.30 0.19
0 196.40 0.43
0 292.00 0.17
0 231.00 0.45
0 308.60 0.18
0 294.90 0.19
1 426.60 0.00 <-- Spike detected
0 269.50 0.47
0 347.30 0.21
0 344.70 0.27
0 445.40 0.06
0 320.90 0.49
0 444.30 0.12
0 406.30 0.29
0 442.40 0.21
1 580.50 0.00 <-- Spike detected
0 412.60 0.45
1 687.00 0.01 <-- Spike detected
0 480.30 0.40
0 586.30 0.20
0 651.90 0.14
Detecção de ponto de alteração
Change points são alterações persistentes em uma distribuição de fluxo de eventos de série temporal de valores, como alterações de nível e tendências. Essas alterações persistentes duram muito mais do que spikes e podem indicar eventos catastróficos.
Change points geralmente não são visíveis a olho nu, mas podem ser detectados em seus dados usando abordagens como no método a seguir. A imagem a seguir é um exemplo de uma detecção de ponto de alteração:
Criar o método DetectChangepoint()
O DetectChangepoint() método executa as seguintes tarefas:
- Cria a transformação do avaliador.
- Detecta pontos de alteração com base em dados históricos de vendas.
- Exibe os resultados.
Crie o
DetectChangepoint()método, logo após a declaração doDetectSpike()método, usando o seguinte código:void DetectChangepoint(MLContext mlContext, int docSize, IDataView productSales) { }Crie o iidChangePointEstimator no
DetectChangepoint()método com o seguinte código:var iidChangePointEstimator = mlContext.Transforms.DetectIidChangePoint(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, changeHistoryLength: docSize / 4);Como você fez anteriormente, crie a transformação a partir do avaliador adicionando a seguinte linha de código no
DetectChangePoint()método:Dica
A detecção de pontos de alteração ocorre com um pequeno atraso, pois o modelo precisa garantir que o desvio atual seja uma alteração persistente e não apenas alguns picos aleatórios antes de criar um alerta. A quantidade desse atraso é igual ao
changeHistoryLengthparâmetro. Aumentando o valor desse parâmetro, altere os alertas de detecção em alterações mais persistentes, mas a compensação seria um atraso maior.var iidChangePointTransform = iidChangePointEstimator.Fit(CreateEmptyDataView(mlContext));Use o
Transform()método para transformar os dados adicionando o seguinte código aDetectChangePoint():IDataView transformedData = iidChangePointTransform.Transform(productSales);Como você fez anteriormente, converta-o
transformedDataem uma exibição fortemente tipadaIEnumerablepara facilitar o uso doCreateEnumerable()método com o seguinte código:var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);Crie um cabeçalho de exibição com o seguinte código como a próxima linha no
DetectChangePoint()método:Console.WriteLine("Alert\tScore\tP-Value\tMartingale value");Você exibirá as seguintes informações nos resultados da detecção de ponto de alteração:
-
Alertindica um alerta de ponto de alteração para um determinado ponto de dados. -
Scoreé oProductSalesvalor de um determinado ponto de dados no conjunto de dados. -
P-ValueO "P" significa probabilidade. Quanto mais próximo o valor P for 0, maior a probabilidade de o ponto de dados ser uma anomalia. -
Martingale valueé usado para identificar o quão "estranho" é um ponto de dados, com base na sequência de valores P.
-
Iterar e
predictionsIEnumerableexibir os resultados com o seguinte código:foreach (var p in predictions) { if (p.Prediction is not null) { var results = $"{p.Prediction[0]}\t{p.Prediction[1]:f2}\t{p.Prediction[2]:F2}\t{p.Prediction[3]:F2}"; if (p.Prediction[0] == 1) { results += " <-- alert is on, predicted changepoint"; } Console.WriteLine(results); } } Console.WriteLine("");Adicione a seguinte chamada ao
DetectChangepoint()método após a chamada aoDetectSpike()método:DetectChangepoint(mlContext, _docsize, dataView);
Resultados da detecção de ponto de alteração
Seus resultados devem ser semelhantes aos seguintes. Durante o processamento, as mensagens são exibidas. Você pode ver avisos ou mensagens de processamento. Algumas mensagens foram removidas dos seguintes resultados para maior clareza.
Detect Persistent changes in pattern
=============== Training the model Using Change Point Detection Algorithm===============
=============== End of training process ===============
Alert Score P-Value Martingale value
0 271.00 0.50 0.00
0 150.90 0.00 2.33
0 188.10 0.41 2.80
0 124.30 0.13 9.16
0 185.30 0.47 9.77
0 173.50 0.47 10.41
0 236.80 0.19 24.46
0 229.50 0.27 42.38
1 197.80 0.48 44.23 <-- alert is on, predicted changepoint
0 127.90 0.13 145.25
0 341.50 0.00 0.01
0 190.90 0.48 0.01
0 199.30 0.48 0.00
0 154.50 0.24 0.00
0 215.10 0.42 0.00
0 278.30 0.19 0.00
0 196.40 0.43 0.00
0 292.00 0.17 0.01
0 231.00 0.45 0.00
0 308.60 0.18 0.00
0 294.90 0.19 0.00
0 426.60 0.00 0.00
0 269.50 0.47 0.00
0 347.30 0.21 0.00
0 344.70 0.27 0.00
0 445.40 0.06 0.02
0 320.90 0.49 0.01
0 444.30 0.12 0.02
0 406.30 0.29 0.01
0 442.40 0.21 0.01
0 580.50 0.00 0.01
0 412.60 0.45 0.01
0 687.00 0.01 0.12
0 480.30 0.40 0.08
0 586.30 0.20 0.03
0 651.90 0.14 0.09
Parabéns! Agora você criou com êxito modelos de machine learning para detectar picos e anomalias de ponto de alteração nos dados de vendas.
Você pode encontrar o código-fonte deste tutorial no repositório dotnet/samples .
Neste tutorial, você aprendeu a:
- Carregar os dados
- Treinar o modelo para detecção de anomalias de pico
- Detectar anomalias de pico com o modelo treinado
- Treinar o modelo para detecção de anomalias de ponto de alteração
- Detectar anomalias de ponto de alteração com o modo treinado
Próximas etapas
Confira os exemplos do repositório GitHub de exemplos do Machine Learning para explorar um exemplo de detecção de anomalias de dados de sazonalidade.