Kurz: Detekce anomálií v prodeji produktů pomocí ML.NET

Zjistěte, jak vytvořit aplikaci pro detekci anomálií pro data o prodeji produktů. Tento kurz vytvoří konzolovou aplikaci .NET Core pomocí jazyka C# v sadě Visual Studio.

V tomto kurzu se naučíte:

  • Načtení dat
  • Vytvoření transformace pro detekci anomálií špičky
  • Detekce anomálií špičky pomocí transformace
  • Vytvoření transformace pro detekci anomálií v bodech změn
  • Detekce anomálií bodu změny pomocí transformace

Zdrojový kód pro tento kurz najdete v úložišti dotnet/samples .

Požadavky

Poznámka

Formát dat v product-sales.csv souboru je založený na datové sadě "Shampoo Sales Over a Three Year Period" původně z DataMarketu a poskytované knihovnou TSDL (Time Series Data Library) vytvořenou Robem Hyndmanem. Datová sada "Shampoo Sales Over a Three Year Period" (Prodej šampónů za období tří let) licencovaná v rámci výchozí otevřené licence DataMarket.

Vytvoření konzolové aplikace

  1. Vytvořte konzolovou aplikaci jazyka C# s názvem ProductSalesAnomalyDetection. Klikněte na tlačítko Další .

  2. Jako architekturu, kterou chcete použít, zvolte .NET 6. Klikněte na tlačítko Vytvořit.

  3. Vytvořte v projektu adresář s názvem Data a uložte soubory datových sad.

  4. Nainstalujte balíček NuGet Microsoft.ML:

    Poznámka

    Tato ukázka používá nejnovější stabilní verzi uvedených balíčků NuGet, pokud není uvedeno jinak.

    V Průzkumník řešení klikněte pravým tlačítkem na projekt a vyberte Spravovat balíčky NuGet. Jako zdroj balíčku zvolte "nuget.org", vyberte kartu Procházet, vyhledejte Microsoft.ML a vyberte tlačítko Nainstalovat . V dialogovém okně Náhled změn vyberte tlačítko OK a pak v dialogovém okně Přijetí licence vyberte tlačítko Souhlasím, pokud souhlasíte s licenčními podmínkami pro uvedené balíčky. Opakujte tento postup pro Microsoft.ML.TimeSeries.

  5. Na začátek souboru Program.cs přidejte následující using příkazy:

    using Microsoft.ML;
    using ProductSalesAnomalyDetection;
    

Stažení vašich dat

  1. Stáhněte si datovou sadu a uložte ji do dříve vytvořené složky Data :

    • Klikněte pravým tlačítkem na product-sales.csv a vyberte Uložit odkaz (nebo cíl) jako.

      Ujistěte se, že soubor *.csv uložíte do složky Data , nebo ho po uložení někam .csv jinam přesuňte do složky Data .

  2. V Průzkumník řešení klikněte pravým tlačítkem na soubor *.csv a vyberte Vlastnosti. V části Upřesnit změňte hodnotu Kopírovat do výstupního adresáře na Kopírovat, pokud je novější.

Následující tabulka obsahuje náhled dat ze souboru *.csv:

Month (Měsíc) ProduktSales
1. leden 271
2. leden 150.9
..... .....
1. únor 199.3
..... .....

Vytváření tříd a definování cest

Dále definujte datové struktury vstupních a prediktivních tříd.

Přidejte do projektu novou třídu:

  1. V Průzkumník řešení klikněte pravým tlačítkem myši na projekt a pak vyberte Přidat > novou položku.

  2. V dialogovém okně Přidat novou položku vyberte Třída a změňte pole Název na ProductSalesData.cs. Pak vyberte tlačítko Přidat .

    Soubor ProductSalesData.cs se otevře v editoru kódu.

  3. Na začátek souboru ProductSalesData.cs přidejte následující using příkaz:

    using Microsoft.ML.Data;
    
  4. Odeberte existující definici třídy a do souboru ProductSalesData.cs přidejte následující kód, který má dvě třídy ProductSalesData a ProductSalesPrediction:

    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; }
    }
    

    ProductSalesData určuje vstupní datovou třídu. Atribut LoadColumn určuje, které sloupce (podle indexu sloupců) v datové sadě se mají načíst.

    ProductSalesPrediction určuje datnou třídu predikce. Pro detekci anomálií se predikce skládá z výstrahy, která označuje, jestli existuje anomálie, nezpracované skóre a p-hodnota. Čím blíže je p-hodnota k 0, tím pravděpodobnější je anomálie.

  5. Vytvořte dvě globální pole, která budou obsahovat nedávno staženou cestu k souboru datové sady a cestu k souboru uloženého modelu:

    • _dataPath má cestu k datové sadě použité k trénování modelu.
    • _docsize má počet záznamů v souboru datové sady. Použijete _docSize k výpočtu pvalueHistoryLength.
  6. Přidejte následující kód na řádek přímo pod příkazy using pro určení těchto cest:

    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;
    

Inicializace proměnných

  1. Console.WriteLine("Hello World!") Nahraďte řádek následujícím kódem pro deklaraci a inicializaci mlContext proměnné:

    MLContext mlContext = new MLContext();
    

    Třída MLContext je výchozím bodem pro všechny operace ML.NET a inicializace mlContext vytvoří nové ML.NET prostředí, které lze sdílet napříč objekty pracovního postupu vytváření modelu. Koncepčně DBContext je to podobné jako v Entity Frameworku.

Načtení dat

Data v ML.NET jsou reprezentována jako rozhraní IDataView. IDataView je flexibilní a efektivní způsob popisu tabulkových dat (číselných a textových). Data je možné načíst z textového souboru nebo z jiných zdrojů (například z databáze SQL nebo souborů protokolu) do objektu IDataView .

  1. Po vytvoření mlContext proměnné přidejte následující kód:

    IDataView dataView = mlContext.Data.LoadFromTextFile<ProductSalesData>(path: _dataPath, hasHeader: true, separatorChar: ',');
    

    LoadFromTextFile() definuje datové schéma a čte v souboru. Přebírá proměnné cesty k datům a vrací IDataViewhodnotu .

Detekce anomálií časových řad

Detekce anomálií označuje neočekávané nebo neobvyklé události nebo chování. Poskytuje vodítka, kde hledat problémy, a pomáhá vám odpovědět na otázku "Je to divné?".

Příklad detekce anomálií

Detekce anomálií je proces zjišťování odlehlých hodnot dat časových řad; body v dané vstupní časové řadě, kde chování není to, co bylo očekáváno, neboli "divné".

Detekce anomálií může být užitečná mnoha způsoby. Například:

Pokud máte auto, možná budete chtít vědět: Je tento olejoměr normální, nebo mám únik? Pokud monitorujete spotřebu energie, chcete vědět: Došlo k výpadku?

Existují dva typy anomálií časových řad, které je možné detekovat:

  • Špičky označují dočasné nárazy neobvyklého chování v systému.

  • Body změn označují začátek trvalých změn v průběhu času v systému.

V ML.NET jsou algoritmy detekce špiček IID nebo DETEKCE bodu změny IID vhodné pro nezávislé a identicky distribuované datové sady. Předpokládají, že vstupní data jsou posloupností datových bodů, které jsou nezávisle vzorkovány z jednoho statického rozdělení.

Na rozdíl od modelů v jiných kurzech fungují transformace detektoru anomálií časových řad přímo na vstupních datech. Metoda IEstimator.Fit() k vytvoření transformace nepotřebuje trénovací data. Potřebuje ale schéma dat, které poskytuje zobrazení dat vygenerované z prázdného seznamu .ProductSalesData

Budete analyzovat stejná data o prodeji produktů, abyste zjistili špičky a body změn. Proces vytváření a trénování modelu je stejný pro detekci špiček a detekci bodu změny; hlavním rozdílem je konkrétní použitý algoritmus detekce.

Detekce špičky

Cílem detekce špičky je identifikovat náhlé, ale dočasné nárazy, které se výrazně liší od většiny datových hodnot časových řad. Tyto podezřelé vzácné položky, události nebo pozorování je důležité včas detekovat, aby se minimalizovaly. Následující přístup lze použít k detekci různých anomálií, jako jsou výpadky, kybernetické útoky nebo virální webový obsah. Následující obrázek je příkladem špiček v datové sadě časových řad:

Snímek obrazovky znázorňující dvě detekce špiček

Přidání metody CreateEmptyDataView()

Přidejte následující metodu do :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);
}

Vytvoří CreateEmptyDataView() prázdný objekt zobrazení dat se správným schématem, který se použije jako vstup do IEstimator.Fit() metody.

Vytvoření metody DetectSpike()

Metoda DetectSpike():

  • Vytvoří transformaci z odhadce.
  • Detekuje špičky na základě historických prodejních dat.
  • Zobrazí výsledky.
  1. Vytvořte metodu DetectSpike() v dolní části souboru Program.cs pomocí následujícího kódu:

    DetectSpike(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Pomocí nástroje IidSpikeEstimator vytrénujte model pro detekci špičky. Přidejte ho DetectSpike() do metody s následujícím kódem:

    var iidSpikeEstimator = mlContext.Transforms.DetectIidSpike(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, pvalueHistoryLength: docSize / 4);
    
  3. Vytvořte transformaci detekce špičky přidáním následujícího řádku kódu do DetectSpike() metody:

    Tip

    Parametry confidence a pvalueHistoryLength mají vliv na to, jak se detekuje špičky. confidence určuje, jak citlivý je model na špičky. Čím nižší je spolehlivost, tím pravděpodobnější je, že algoritmus detekuje "menší" špičky. Parametr pvalueHistoryLength definuje počet datových bodů v posuvné okně. Hodnota tohoto parametru je obvykle procento celé datové sady. pvalueHistoryLengthNižší hodnota , tím rychleji model zapomene předchozí velké špičky.

    ITransformer iidSpikeTransform = iidSpikeEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Přidejte následující řádek kódu, který transformuje productSales data jako další řádek v DetectSpike() metodě:

    IDataView transformedData = iidSpikeTransform.Transform(productSales);
    

    Předchozí kód používá metodu Transform() k předpovědím pro více vstupních řádků datové sady.

  5. Pomocí metody CreateEnumerable() s následujícím kódem převeďte transformedData do silného typu IEnumerable pro snadnější zobrazení:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Pomocí následujícího Console.WriteLine() kódu vytvořte řádek záhlaví zobrazení:

    Console.WriteLine("Alert\tScore\tP-Value");
    

    Ve výsledcích detekce špičky zobrazíte následující informace:

    • Alert označuje upozornění na špičku pro daný datový bod.
    • ScoreProductSales je hodnota daného datového bodu v datové sadě.
    • P-Value "P" je zkratka pro pravděpodobnost. Čím blíže je p-hodnota k 0, tím pravděpodobnější je, že datový bod je anomálie.
  7. Pomocí následujícího kódu iterujte a predictionsIEnumerable zobrazte výsledky:

    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("");
    
  8. Pod volání LoadFromTextFile() metody přidejte volání DetectSpike() metody:

    DetectSpike(mlContext, _docsize, dataView);
    

Výsledky detekce špičky

Výsledky by se měly podobat následujícímu. Během zpracování se zobrazují zprávy. Může se zobrazit upozornění nebo zpracování zpráv. Některé zprávy byly odebrány z následujících výsledků pro přehlednost.

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

Detekce bodu změny

Change points jsou trvalé změny v distribuci datových proudů událostí časové řady, jako jsou změny úrovně a trendy. Tyto trvalé změny trvají mnohem déle než spikes a můžou znamenat katastrofické události. Change points nejsou obvykle viditelné pouhým okem, ale dají se detekovat v datech pomocí přístupů, jako je následující metoda. Následující obrázek je příkladem detekce bodu změny:

Snímek obrazovky znázorňující detekci bodu změny

Vytvoření metody DetectChangepoint()

Metoda DetectChangepoint() provede následující úlohy:

  • Vytvoří transformaci z odhadce.
  • Zjišťuje body změn na základě historických prodejních dat.
  • Zobrazí výsledky.
  1. Vytvořte metodu DetectChangepoint() hned za deklarací DetectSpike() metody pomocí následujícího kódu:

    void DetectChangepoint(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Vytvořte v metodě iidChangePointEstimatorDetectChangepoint() s následujícím kódem:

    var iidChangePointEstimator = mlContext.Transforms.DetectIidChangePoint(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, changeHistoryLength: docSize / 4);
    
  3. Stejně jako dříve vytvořte transformaci z estimátoru přidáním následujícího řádku kódu do DetectChangePoint() metody:

    Tip

    Detekce bodů změn probíhá s malou prodlevou, protože model musí před vytvořením výstrahy zajistit, aby aktuální odchylka byla trvalou změnou, a ne pouze náhodnými špičkami. Množství tohoto zpoždění se rovná parametru changeHistoryLength . Zvýšením hodnoty tohoto parametru upozorní detekce změn na trvalejší změny, ale kompromis by byl delší.

    var iidChangePointTransform = iidChangePointEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Transform() Pomocí metody transformujte data přidáním následujícího kódu do DetectChangePoint():

    IDataView transformedData = iidChangePointTransform.Transform(productSales);
    
  5. Stejně jako dříve převeďte transformedData ho do silného typu IEnumerable pro snadnější zobrazení pomocí CreateEnumerable()metody s následujícím kódem:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Vytvořte záhlaví zobrazení s následujícím kódem jako dalším řádkem DetectChangePoint() v metodě:

    Console.WriteLine("Alert\tScore\tP-Value\tMartingale value");
    

    Ve výsledcích detekce bodu změny zobrazíte následující informace:

    • Alert označuje upozornění na bod změny pro daný datový bod.
    • ScoreProductSales je hodnota daného datového bodu v datové sadě.
    • P-Value "P" je zkratka pro pravděpodobnost. Čím blíže je hodnota P k hodnotě 0, tím pravděpodobnější je datový bod anomálie.
    • Martingale value se používá k identifikaci "divného" datového bodu na základě posloupnosti P-hodnot.
  7. Proveďte iteraci a zobrazte predictionsIEnumerable výsledky pomocí následujícího kódu:

    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("");
    
  8. Za volání DetectSpike() metody přidejte do DetectChangepoint()metody následující volání:

    DetectChangepoint(mlContext, _docsize, dataView);
    

Výsledky detekce bodu změny

Výsledky by se měly podobat následujícímu. Během zpracování se zobrazují zprávy. Může se zobrazit upozornění nebo zpracování zpráv. Některé zprávy byly z následujících výsledků odebrány pro přehlednost.

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

Gratulujeme! Nyní jste úspěšně vytvořili modely strojového učení pro detekci špiček a anomálií v bodech změn v prodejních datech.

Zdrojový kód pro tento kurz najdete v úložišti dotnet/samples .

V tomto kurzu jste se naučili:

  • Načtení dat
  • Trénování modelu pro detekci anomálií špičky
  • Detekce anomálií špičky pomocí natrénovaného modelu
  • Trénování modelu pro detekci anomálií v bodech změn
  • Detekce anomálií v bodech změn pomocí trénovaného režimu

Další kroky

Podívejte se na úložiště Ukázek služby Machine Learning na GitHubu a prozkoumejte ukázku detekce sezónnosti dat anomálií.