Oktatóanyag: Termékértékesítések rendellenességeinek észlelése ML.NET

Ismerje meg, hogyan hozhat létre anomáliadetektálási alkalmazást a termékértékesítési adatokhoz. Ez az oktatóanyag létrehoz egy .NET Core-konzolalkalmazást a C# használatával a Visual Studióban.

Eben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • Az adatok betöltése
  • Átalakítás létrehozása a kiugrás anomáliadetektálásához
  • Csúcsanomáliák észlelése az átalakítással
  • Átalakítás létrehozása változáspont-anomáliadetektáláshoz
  • Változáspont-anomáliák észlelése az átalakítással

Az oktatóanyag forráskódját a dotnet/samples adattárban találja.

Előfeltételek

Megjegyzés

Az adatformátum product-sales.csv alapja a "Samponértékesítés három év alatt" adatkészlet, amely eredetileg a DataMarketből származik, és amelyet a Rob Hyndman által létrehozott Time Series Data Library (TSDL) biztosít. A DataMarket alapértelmezett nyílt licencével licencelt "Samponértékesítés három év alatt" adatkészlet.

Konzolalkalmazás létrehozása

  1. Hozzon létre egy "ProductSalesAnomalyDetection" nevű C#- konzolalkalmazást . Kattintson a Tovább gombra.

  2. Válassza a .NET 6-ot a használni kívánt keretrendszerként. Kattintson a Létrehozás gombra.

  3. Hozzon létre egy Data (Adatok ) nevű könyvtárat a projektben az adatkészletfájlok mentéséhez.

  4. Telepítse a Microsoft.ML NuGet-csomagot:

    Megjegyzés

    Ez a minta az említett NuGet-csomagok legújabb stabil verzióját használja, hacsak másként nem rendelkezik.

    A Megoldáskezelő kattintson a jobb gombbal a projektre, és válassza a Manage NuGet Packages (NuGet-csomagok kezelése) lehetőséget. Válassza a "nuget.org" lehetőséget a Csomag forrásaként, válassza a Tallózás lapot, keresse meg a Microsoft.ML , és válassza a Telepítés gombot. Válassza az OK gombot a Módosítások előnézete párbeszédpanelen, majd válassza az Elfogadom gombot a Licenc elfogadása párbeszédpanelen, ha elfogadja a felsorolt csomagok licencfeltételét. Ismételje meg ezeket a lépéseket a Microsoft.ML.TimeSeries esetében.

  5. Adja hozzá a következő using utasításokat a Program.cs fájl elejéhez:

    using Microsoft.ML;
    using ProductSalesAnomalyDetection;
    

Adatok letöltése

  1. Töltse le az adatkészletet, és mentse a korábban létrehozott Adatok mappába:

    • Kattintson a jobb gombbal aproduct-sales.csv , és válassza a "Hivatkozás mentése (vagy cél) másként..." lehetőséget.

      Győződjön meg arról, hogy a *.csv fájlt az Adatok mappába menti, vagy miután máshová mentette, helyezze át a *.csv fájlt az Adatok mappába.

  2. A Megoldáskezelő kattintson a jobb gombbal a *.csv fájlra, és válassza a Tulajdonságok parancsot. A Speciális területen módosítsa a Másolás kimeneti könyvtárra értékét Másolás, ha újabb értékre.

Az alábbi táblázat a *.csv fájlból származó adatelőnézet:

Month (hónap) Termékértékesítések
Január 1. 271
Január 2. 150.9
..... .....
Február 1. 199.3
..... .....

Osztályok létrehozása és elérési utak definiálása

Ezután definiálja a bemeneti és előrejelzési osztály adatstruktúráját.

Adjon hozzá egy új osztályt a projekthez:

  1. A Megoldáskezelő kattintson a jobb gombbal a projektre, majd válassza az Új elem hozzáadása >lehetőséget.

  2. Az Új elem hozzáadása párbeszédpanelen válassza az Osztály lehetőséget, és módosítsa a Név mezőt ProductSalesData.cs értékre. Ezután válassza a Hozzáadás gombot.

    Megnyílik a ProductSalesData.cs fájl a kódszerkesztőben.

  3. Adja hozzá a következő using utasítást a ProductSalesData.cs fájl elejéhez:

    using Microsoft.ML.Data;
    
  4. Távolítsa el a meglévő osztálydefiníciót, és adja hozzá a következő kódot, amelynek két osztálya ProductSalesData és ProductSalesPredictionvan, a ProductSalesData.cs fájlhoz:

    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 egy bemeneti adatosztályt határoz meg. A LoadColumn attribútum határozza meg, hogy az adathalmaz mely oszlopait (oszlopindex alapján) kell betölteni.

    ProductSalesPrediction az előrejelzési adatosztályt adja meg. Az anomáliadetektáláshoz az előrejelzés egy riasztásból áll, amely jelzi, hogy van-e rendellenesség, nyers pontszám és p-érték. Minél közelebb van a p-érték a 0-hoz, annál valószínűbb, hogy anomália történt.

  5. Hozzon létre két globális mezőt a nemrég letöltött adathalmaz-fájl elérési útjának és a mentett modellfájl elérési útjának tárolásához:

    • _dataPath a modell betanítása során használt adathalmaz elérési útját használja.
    • _docsize az adathalmazfájl rekordjainak számát adja meg. A használatával _docSize kiszámíthatja a függvényt pvalueHistoryLength.
  6. Adja hozzá a következő kódot a using utasítások alatti sorhoz az elérési utak megadásához:

    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;
    

Változók inicializálása

  1. Cserélje le a Console.WriteLine("Hello World!") sort a következő kódra a változó deklarálásához és inicializálásához mlContext :

    MLContext mlContext = new MLContext();
    

    Az MLContext osztály minden ML.NET művelet kiindulási pontja, és az inicializálás mlContext egy új ML.NET környezetet hoz létre, amely megosztható a modelllétrehozási munkafolyamat-objektumok között. Ez fogalmilag hasonló az Entity Frameworkhez DBContext .

Az adatok betöltése

A ML.NET adatai IDataView-felületként jelennek meg. IDataView rugalmas, hatékony módja a táblázatos adatok (numerikus és szöveges) leírásának. Az adatok betölthetők szövegfájlból vagy más forrásokból (például SQL-adatbázisból vagy naplófájlokból) egy IDataView objektumba.

  1. Adja hozzá a következő kódot a mlContext változó létrehozása után:

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

    A LoadFromTextFile() meghatározza az adatsémát, és beolvassa a fájlt. Az adatelérési út változóit veszi fel, és egy IDataViewértéket ad vissza.

Idősor anomáliadetektálása

Az anomáliadetektálás váratlan vagy szokatlan eseményeket vagy viselkedéseket jelöl. Ez nyomokat ad, hol kell keresni a problémákat, és segít megválaszolni a kérdést: "Ez furcsa?".

Példa a

Az anomáliadetektálás az idősoros adat kiugró értékek észlelésének folyamata; egy adott bemeneti idősorra mutat, ahol a viselkedés nem a várt, vagy "furcsa".

Az anomáliadetektálás sokféleképpen hasznos lehet. Ilyenek például a következők:

Ha van egy autó, akkor érdemes tudni: Ez az olaj mérőműszer olvasó normál, vagy van egy szivárgás? Ha az energiafogyasztást figyeli, érdemes tudnia, hogy van-e szolgáltatáskimaradás?

Az idősor-anomáliáknak két típusa észlelhető:

  • A kiugrások a rendszer rendellenes viselkedésének átmeneti kiugrását jelzik.

  • A változáspontok jelzik az állandó változások kezdetét a rendszerben.

A ML.NET az IID csúcsészlelés vagy az IID változáspont-észlelési algoritmusok független és azonos eloszlású adathalmazokhoz használhatók. Feltételezik, hogy a bemeneti adatok olyan adatpontok sorozatai, amelyek egy helyhez kötött eloszlástól függetlenül mintavételezésre kerülnek.

A többi oktatóanyagban szereplő modellekkel ellentétben az idősorozat-anomáliadetektor-átalakítások közvetlenül a bemeneti adatokon működnek. A IEstimator.Fit() metódusnak nincs szüksége betanítási adatokra az átalakítás létrehozásához. Ehhez azonban szükség van az adatsémára, amelyet egy üres listából ProductSalesDatalétrehozott adatnézet biztosít.

Ugyanazokat a termékértékesítési adatokat fogja elemezni, hogy észlelje a kiugró értékeket és a változási pontokat. Az épület- és betanítási modell folyamata megegyezik a csúcsok észleléséhez és a változáspont-észleléshez; a fő különbség a használt specifikus észlelési algoritmus.

Kiugró érték észlelése

A kiugró csúcsok észlelésének célja a hirtelen, de átmeneti adatcsúcsok azonosítása, amelyek jelentősen eltérnek az idősor adatértékeinek többségétől. Fontos, hogy ezeket a gyanús ritka elemeket, eseményeket vagy megfigyeléseket időben észlelje, hogy minimalizálni lehessen őket. A következő megközelítéssel számos rendellenességet észlelhet, például kimaradásokat, kibertámadásokat vagy vírusos webes tartalmakat. Az alábbi képen egy idősor adathalmazának kiugró csúcsai láthatóak:

Két csúcsészlelést ábrázoló képernyőkép.

A CreateEmptyDataView() metódus hozzáadása

Adja hozzá a következő metódust a következőhöz 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);
}

A CreateEmptyDataView() egy üres adatnézet-objektumot hoz létre a metódus bemeneteként IEstimator.Fit() használni kívánt megfelelő sémával.

A DetectSpike() metódus létrehozása

A DetectSpike() metódus:

  • Létrehozza az átalakítást a becslőből.
  • Észleli a kiugró értékeket az előzmény értékesítési adatok alapján.
  • Megjeleníti az eredményeket.
  1. Hozza létre a DetectSpike() metódust a Program.cs fájl alján a következő kóddal:

    DetectSpike(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Az IidSpikeEstimator használatával betaníthatja a modellt a csúcsok észlelésére. Adja hozzá a DetectSpike() metódushoz a következő kóddal:

    var iidSpikeEstimator = mlContext.Transforms.DetectIidSpike(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, pvalueHistoryLength: docSize / 4);
    
  3. Hozza létre a csúcsészlelési átalakítást a metódus következő kódsoraként DetectSpike() a következő kóddal:

    Tipp

    A confidence és pvalueHistoryLength a paraméter hatással van a kiugró csúcsok észlelésére. confidence meghatározza, hogy mennyire érzékeny a modell a csúcsokra. Minél kisebb a megbízhatóság, annál valószínűbb, hogy az algoritmus észleli a "kisebb" csúcsokat. A pvalueHistoryLength paraméter határozza meg az adatpontok számát egy csúszóablakban. Ennek a paraméternek az értéke általában a teljes adathalmaz százalékos értéke. Minél alacsonyabb a pvalueHistoryLength, annál gyorsabban felejti el a modell a korábbi nagy kiugró értékeket.

    ITransformer iidSpikeTransform = iidSpikeEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Adja hozzá a következő kódsort az productSales adatok átalakításához a metódus következő soraként DetectSpike() :

    IDataView transformedData = iidSpikeTransform.Transform(productSales);
    

    Az előző kód a Transform() metódussal készít előrejelzéseket egy adathalmaz több bemeneti sorához.

  5. A CreateEnumerable() metódussal alakítsa át a transformedData gépét egy erősen beírt IEnumerable típussá a könnyebb megjelenítés érdekében az alábbi kóddal:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Hozzon létre egy megjelenítendő fejlécsort a következő Console.WriteLine() kóddal:

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

    A kiugró csúcsok észlelési eredményei között a következő információk jelennek meg:

    • Alert egy adott adatpontra vonatkozó kiugró riasztást jelez.
    • Score az ProductSales adathalmaz egy adott adatpontjának értéke.
    • P-Value A "P" a valószínűség. Minél közelebb van a p-érték a 0-hoz, annál valószínűbb, hogy az adatpont anomália.
  7. Az alábbi kóddal iterálhatja a-t, predictionsIEnumerable és megjelenítheti az eredményeket:

    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. Adja hozzá a hívást a DetectSpike() metódushoz a hívás alatti metódushoz LoadFromTextFile() :

    DetectSpike(mlContext, _docsize, dataView);
    

Kiugró csúcsok észlelési eredményei

Az eredményeknek az alábbihoz hasonlónak kell lenniük. A feldolgozás során üzenetek jelennek meg. Megjelenhetnek figyelmeztetések vagy üzenetek feldolgozása. Néhány üzenet el lett távolítva az alábbi eredményekből az egyértelműség érdekében.

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

Változáspont-észlelés

Change points az értékek idősorozatbeli eseménystream-eloszlásának állandó változásai, például a szintváltozások és a trendek. Ezek az állandó változások sokkal tovább tartanak, mint spikes , és katasztrofális esemény(ek)et jelezhetnek. Change points általában nem láthatók szabad szemmel, de az adatokban olyan módszerekkel észlelhetők, mint a következő módszer. Az alábbi kép egy példa a változáspont-észlelésre:

Képernyőkép a változáspont-észlelésről.

A DetectChangepoint() metódus létrehozása

A DetectChangepoint() metódus a következő feladatokat hajtja végre:

  • Létrehozza az átalakítást a becslőből.
  • Észleli a változáspontokat az előzmény értékesítési adatok alapján.
  • Megjeleníti az eredményeket.
  1. Hozza létre a metódust DetectChangepoint() közvetlenül a metódus deklarációja DetectSpike() után a következő kóddal:

    void DetectChangepoint(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Hozza létre az iidChangePointEstimatort a DetectChangepoint() metódusban a következő kóddal:

    var iidChangePointEstimator = mlContext.Transforms.DetectIidChangePoint(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, changeHistoryLength: docSize / 4);
    
  3. Ahogy korábban is tette, hozza létre az átalakítást a becslőből az alábbi kódsor hozzáadásával a DetectChangePoint() metódusban:

    Tipp

    A változáspontok észlelése kis késéssel történik, mivel a modellnek meg kell győződnie arról, hogy az aktuális eltérés állandó változás, és nem csak néhány véletlenszerű kiugró érték a riasztás létrehozása előtt. A késleltetés mértéke megegyezik a changeHistoryLength paraméterével. A paraméter értékének növelésével a változásészlelés riasztásokat küld az állandóbb változásokról, de a kompromisszum hosszabb késést okozna.

    var iidChangePointTransform = iidChangePointEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Transform() A metódussal átalakíthatja az adatokat a következő kód DetectChangePoint()hozzáadásával:

    IDataView transformedData = iidChangePointTransform.Transform(productSales);
    
  5. Ahogy korábban is tette, alakítsa át erősen transformedData gépeltre IEnumerable a könnyebb megjelenítés érdekében a metódussal az CreateEnumerable()alábbi kóddal:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Hozzon létre egy megjelenítési fejlécet a metódus következő soraként DetectChangePoint() a következő kóddal:

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

    A változáspont-észlelési eredmények között a következő információk jelennek meg:

    • Alert egy adott adatponthoz tartozó változáspont-riasztást jelez.
    • Score az ProductSales adathalmaz egy adott adatpontjának értéke.
    • P-Value A "P" a valószínűség. Minél közelebb van a P-érték a 0-hoz, annál valószínűbb, hogy az adatpont anomália.
    • Martingale value az adatpont "furcsa" módjának azonosítására szolgál a P-értékek sorozata alapján.
  7. Iterálja végig a kódot, predictionsIEnumerable és jelenítse meg az eredményeket a következő kóddal:

    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. Adja hozzá a következő hívást a metódushoz a DetectChangepoint()metódus hívása DetectSpike() után:

    DetectChangepoint(mlContext, _docsize, dataView);
    

Változáspont-észlelési eredmények

Az eredményeknek az alábbihoz hasonlónak kell lenniük. A feldolgozás során üzenetek jelennek meg. Megjelenhetnek figyelmeztetések vagy üzenetek feldolgozása. Néhány üzenet el lett távolítva az alábbi eredményekből az egyértelműség érdekében.

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

Gratulálunk! Sikeresen létrehozott gépi tanulási modelleket az értékesítési adatok kiugró csúcsainak és változási pontanomáliáinak észleléséhez.

Az oktatóanyag forráskódját a dotnet/samples adattárban találja.

Ez az oktatóanyag bemutatta, hogyan végezheti el az alábbi műveleteket:

  • Az adatok betöltése
  • A modell betanítása kiugró anomáliadetektáláshoz
  • Kiugróan magas anomáliák észlelése a betanított modellel
  • A modell betanítása változáspont-anomáliadetektáláshoz
  • Változáspont-rendellenességek észlelése a betanított módban

Következő lépések

Tekintse meg a Machine Learning-minták GitHub-adattárát a szezonalitási adatok anomáliadetektálási mintájának megismeréséhez.