Zelfstudie: Afwijkingen in de productverkoop detecteren met ML.NET

Meer informatie over het bouwen van een anomaliedetectietoepassing voor productverkoopgegevens. In deze zelfstudie maakt u een .NET Core-consoletoepassing met C# in Visual Studio.

In deze zelfstudie leert u het volgende:

  • De gegevens laden
  • Een transformatie maken voor detectie van piekafwijkingen
  • Piekafwijkingen detecteren met de transformatie
  • Een transformatie maken voor anomaliedetectie van wijzigingspunten
  • Afwijkingen van wijzigingspunten detecteren met de transformatie

U vindt de broncode voor deze zelfstudie in de opslagplaats dotnet/samples .

Vereisten

Notitie

De gegevensindeling in product-sales.csv is gebaseerd op de gegevensset 'Shampoo Sales Over a Three Year Period', oorspronkelijk afkomstig van DataMarket en geleverd door Time Series Data Library (TSDL), gemaakt door Rob Hyndman. Gegevensset 'Shampoo-verkoop over een periode van drie jaar' in licentie gegeven onder de DataMarket Default Open License.

Een consoletoepassing maken

  1. Maak een C# -consoletoepassing met de naam ProductSalesAnomalyDetection. Klik op de knop Next

  2. Kies .NET 6 als het framework dat u wilt gebruiken. Klik op de knop Maken.

  3. Maak een map met de naam Gegevens in uw project om uw gegevenssetbestanden op te slaan.

  4. Installeer het Microsoft.ML NuGet-pakket:

    Notitie

    In dit voorbeeld wordt de meest recente stabiele versie van de vermelde NuGet-pakketten gebruikt, tenzij anders vermeld.

    Klik in Solution Explorer met de rechtermuisknop op uw project en selecteer NuGet-pakketten beheren. Kies 'nuget.org' als pakketbron, selecteer het tabblad Bladeren, zoek naar Microsoft.ML en selecteer de knop Installeren . Selecteer de knop OK in het dialoogvenster Voorbeeld van wijzigingen en selecteer vervolgens de knop Ik ga akkoord in het dialoogvenster Licentie-acceptatie als u akkoord gaat met de licentievoorwaarden voor de vermelde pakketten. Herhaal deze stappen voor Microsoft.ML.TimeSeries.

  5. Voeg de volgende using instructies toe aan het begin van het bestand Program.cs :

    using Microsoft.ML;
    using ProductSalesAnomalyDetection;
    

Uw gegevens downloaden

  1. Download de gegevensset en sla deze op in de map Gegevens die u eerder hebt gemaakt:

    • Klik met de rechtermuisknop op product-sales.csv en selecteer 'Koppeling opslaan (of doel) als...'

      Zorg ervoor dat u het bestand *.csv opslaat in de map Gegevens , of verplaats het *.csv-bestand naar de map Gegevens nadat u het ergens anders hebt opgeslagen.

  2. Klik in Solution Explorer met de rechtermuisknop op het bestand *.csv en selecteer Eigenschappen. Wijzig onder Geavanceerd de waarde van Kopiëren naar uitvoermap in Kopiëren indien nieuwer.

De volgende tabel is een voorbeeld van gegevens uit uw *.csv-bestand:

Maand ProductVerkoop
1-jan 271
2-jan 150.9
..... .....
1-feb 199.3
..... .....

Klassen maken en paden definiëren

Definieer vervolgens de gegevensstructuren voor uw invoer- en voorspellingsklasse.

Voeg een nieuwe klasse toe aan uw project:

  1. Klik in Solution Explorer met de rechtermuisknop op het project en selecteer vervolgens Nieuw item toevoegen>.

  2. Selecteer in het dialoogvenster Nieuw item toevoegen de optie Klasse en wijzig het veld Naam in ProductSalesData.cs. Selecteer vervolgens de knop Toevoegen .

    Het bestand ProductSalesData.cs wordt geopend in de code-editor.

  3. Voeg de volgende using instructie toe aan het begin van ProductSalesData.cs:

    using Microsoft.ML.Data;
    
  4. Verwijder de bestaande klassedefinitie en voeg de volgende code, die twee klassen ProductSalesData en ProductSalesPredictionheeft, toe aan het bestand 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; }
    }
    

    ProductSalesData hiermee geeft u een invoergegevensklasse op. Het kenmerk LoadColumn geeft aan welke kolommen (per kolomindex) in de gegevensset moeten worden geladen.

    ProductSalesPrediction hiermee geeft u de voorspellingsgegevensklasse op. Voor anomaliedetectie bestaat de voorspelling uit een waarschuwing om aan te geven of er sprake is van een anomalie, een onbewerkte score en p-waarde. Hoe dichter de p-waarde bij 0 ligt, hoe groter de kans dat er een anomalie is opgetreden.

  5. Maak twee globale velden voor het onlangs gedownloade pad naar het gegevenssetbestand en het pad naar het opgeslagen modelbestand:

    • _dataPath heeft het pad naar de gegevensset die wordt gebruikt om het model te trainen.
    • _docsize bevat het aantal records in het gegevenssetbestand. U gebruikt _docSize om te berekenen pvalueHistoryLength.
  6. Voeg de volgende code toe aan de regel direct onder de using-instructies om deze paden op te geven:

    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;
    

Variabelen initialiseren

  1. Vervang de Console.WriteLine("Hello World!") regel door de volgende code om de mlContext variabele te declareren en te initialiseren:

    MLContext mlContext = new MLContext();
    

    De mlContext-klasse is een startpunt voor alle ML.NET bewerkingen en als u initialiseert mlContext , wordt er een nieuwe ML.NET omgeving gemaakt die kan worden gedeeld met de werkstroomobjecten voor het maken van modellen. Het is conceptueel DBContext vergelijkbaar met in Entity Framework.

De gegevens laden

Gegevens in ML.NET worden weergegeven als een IDataView-interface. IDataView is een flexibele, efficiënte manier om tabelgegevens (numeriek en tekst) te beschrijven. Gegevens kunnen vanuit een tekstbestand of uit andere bronnen (bijvoorbeeld SQL-database of logboekbestanden) naar een IDataView object worden geladen.

  1. Voeg de volgende code toe nadat u de variabele hebt mlContext gemaakt:

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

    Het LoadFromTextFile() definieert het gegevensschema en leest het bestand in. Het neemt de gegevenspadvariabelen op en retourneert een IDataView.

Detectie van afwijkingen in tijdreeksen

Anomaliedetectie markeert onverwachte of ongebruikelijke gebeurtenissen of gedrag. Het geeft aanwijzingen waar u naar problemen moet zoeken en helpt u bij het beantwoorden van de vraag "Is dit raar?".

Voorbeeld van de anomaliedetectie 'Is dit vreemd'.

Anomaliedetectie is het proces van het detecteren van uitbijters van tijdreeksgegevens; punten op een bepaalde invoertijdreeks waarbij het gedrag niet is wat verwacht werd, of 'vreemd'.

Anomaliedetectie kan op verschillende manieren nuttig zijn. Bijvoorbeeld:

Als je een auto hebt, wil je misschien weten: is deze oliemeter normaal, of heb ik een lek? Als u het energieverbruik bewaakt, wilt u weten: Is er een storing?

Er zijn twee soorten afwijkingen in tijdreeksen die kunnen worden gedetecteerd:

  • Pieken duiden op tijdelijke bursts van afwijkend gedrag in het systeem.

  • Wijzigingspunten geven het begin aan van permanente wijzigingen in de loop van de tijd in het systeem.

In ML.NET zijn de algoritmen IID-piekdetectie of IID-wijzigingspuntdetectie geschikt voor onafhankelijke en identiek gedistribueerde gegevenssets. Ze gaan ervan uit dat uw invoergegevens een reeks gegevenspunten zijn die onafhankelijk van één stationaire distributie worden bemonsterd.

In tegenstelling tot de modellen in de andere zelfstudies werken de transformaties van de anomaliedetectie van tijdreeksen rechtstreeks op invoergegevens. De IEstimator.Fit() methode heeft geen trainingsgegevens nodig om de transformatie te produceren. Het heeft echter wel het gegevensschema nodig, dat wordt geleverd door een gegevensweergave die wordt gegenereerd op basis van een lege lijst met ProductSalesData.

U analyseert dezelfde productverkoopgegevens om pieken en wijzigingspunten te detecteren. Het bouw- en trainingsmodelproces is hetzelfde voor piekdetectie en wijzigingspuntdetectie; het belangrijkste verschil is het specifieke detectie-algoritme dat wordt gebruikt.

Piekdetectie

Het doel van piekdetectie is het identificeren van plotselinge maar tijdelijke bursts die aanzienlijk verschillen van de meeste tijdreeksgegevenswaarden. Het is belangrijk dat u deze verdachte, zeldzame items, gebeurtenissen of waarnemingen tijdig detecteert om deze te minimaliseren. De volgende benadering kan worden gebruikt om verschillende afwijkingen te detecteren, zoals: storingen, cyberaanvallen of virale webinhoud. De volgende afbeelding is een voorbeeld van pieken in een tijdreeksgegevensset:

Schermopname van twee piekdetecties.

De methode CreateEmptyDataView() toevoegen

Voeg de volgende methode toe aan 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);
}

De CreateEmptyDataView() produceert een leeg gegevensweergaveobject met het juiste schema dat moet worden gebruikt als invoer voor de IEstimator.Fit() methode.

De methode DetectSpike() maken

De methode DetectSpike():

  • Hiermee maakt u de transformatie op basis van de estimator.
  • Detecteert pieken op basis van historische verkoopgegevens.
  • Geeft de resultaten weer.
  1. Maak de DetectSpike() methode onderaan het bestand Program.cs met behulp van de volgende code:

    DetectSpike(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Gebruik de IidSpikeEstimator om het model te trainen voor piekdetectie. Voeg deze toe aan de DetectSpike() methode met de volgende code:

    var iidSpikeEstimator = mlContext.Transforms.DetectIidSpike(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, pvalueHistoryLength: docSize / 4);
    
  3. Maak de transformatie voor piekdetectie door het volgende toe te voegen als de volgende regel code in de DetectSpike() methode:

    Tip

    De confidence parameters en pvalueHistoryLength zijn van invloed op de wijze waarop pieken worden gedetecteerd. confidence bepaalt hoe gevoelig uw model is voor pieken. Hoe lager de betrouwbaarheid, hoe groter de kans dat het algoritme 'kleinere' pieken detecteert. De pvalueHistoryLength parameter definieert het aantal gegevenspunten in een sliding window. De waarde van deze parameter is meestal een percentage van de hele gegevensset. Hoe lager de pvalueHistoryLength, hoe sneller het model eerdere grote pieken vergeet.

    ITransformer iidSpikeTransform = iidSpikeEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Voeg de volgende regel code toe om de productSales gegevens te transformeren als de volgende regel in de DetectSpike() methode:

    IDataView transformedData = iidSpikeTransform.Transform(productSales);
    

    De vorige code maakt gebruik van de methode Transform() om voorspellingen te doen voor meerdere invoerrijen van een gegevensset.

  5. Converteer uw transformedData naar een sterk getypte IEnumerable voor eenvoudigere weergave met behulp van de methode CreateEnumerable() met de volgende code:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Maak een weergavekopregel met behulp van de volgende Console.WriteLine() code:

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

    U geeft de volgende informatie weer in de resultaten van uw piekdetectie:

    • Alert geeft een piekwaarschuwing voor een bepaald gegevenspunt aan.
    • Score is de ProductSales waarde voor een bepaald gegevenspunt in de gegevensset.
    • P-Value De "P" staat voor waarschijnlijkheid. Hoe dichter de p-waarde bij 0 ligt, hoe groter de kans dat het gegevenspunt een anomalie is.
  7. Gebruik de volgende code om de predictionsIEnumerable te doorlopen en de resultaten weer te geven:

    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. Voeg de aanroep toe aan de DetectSpike() methode onder de aanroep van de LoadFromTextFile() methode:

    DetectSpike(mlContext, _docsize, dataView);
    

Resultaten van piekdetectie

De resultaten moeten er ongeveer als volgt uitzien. Tijdens de verwerking worden berichten weergegeven. Mogelijk ziet u waarschuwingen of worden berichten verwerkt. Sommige berichten zijn voor de duidelijkheid verwijderd uit de volgende resultaten.

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

Detectie van wijzigingspunten

Change points zijn permanente wijzigingen in een tijdreeks-gebeurtenisstroomdistributie van waarden, zoals niveauwijzigingen en trends. Deze permanente wijzigingen duren veel langer dan spikes en kunnen duiden op een of meer catastrofale gebeurtenissen. Change points zijn meestal niet met het blote oog zichtbaar, maar kunnen worden gedetecteerd in uw gegevens met behulp van benaderingen zoals in de volgende methode. De volgende afbeelding is een voorbeeld van een detectie van een wijzigingspunt:

Schermopname van een detectie van een wijzigingspunt.

De methode DetectChangepoint() maken

Met DetectChangepoint() de methode worden de volgende taken uitgevoerd:

  • Hiermee maakt u de transformatie op basis van de estimator.
  • Detecteert wijzigingspunten op basis van historische verkoopgegevens.
  • Geeft de resultaten weer.
  1. Maak de DetectChangepoint() methode, net na de DetectSpike() methodedeclaratie, met behulp van de volgende code:

    void DetectChangepoint(MLContext mlContext, int docSize, IDataView productSales)
    {
    
    }
    
  2. Maak de iidChangePointEstimator in de DetectChangepoint() methode met de volgende code:

    var iidChangePointEstimator = mlContext.Transforms.DetectIidChangePoint(outputColumnName: nameof(ProductSalesPrediction.Prediction), inputColumnName: nameof(ProductSalesData.numSales), confidence: 95d, changeHistoryLength: docSize / 4);
    
  3. Zoals u eerder hebt gedaan, maakt u de transformatie vanuit de estimator door de volgende regel code toe te voegen aan de DetectChangePoint() methode:

    Tip

    De detectie van wijzigingspunten vindt plaats met een kleine vertraging, omdat het model ervoor moet zorgen dat de huidige afwijking een permanente wijziging is en niet slechts enkele willekeurige pieken voordat een waarschuwing wordt gemaakt. De hoeveelheid van deze vertraging is gelijk aan de changeHistoryLength parameter . Door de waarde van deze parameter te verhogen, waarschuwt wijzigingsdetectie voor meer persistente wijzigingen, maar de afweging zou een langere vertraging zijn.

    var iidChangePointTransform = iidChangePointEstimator.Fit(CreateEmptyDataView(mlContext));
    
  4. Gebruik de Transform() methode om de gegevens te transformeren door de volgende code toe te voegen aan DetectChangePoint():

    IDataView transformedData = iidChangePointTransform.Transform(productSales);
    
  5. Zoals u eerder hebt gedaan, converteert u uw transformedData naar een sterk getypte voor een eenvoudigere IEnumerable weergave met behulp van de CreateEnumerable()methode met de volgende code:

    var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(transformedData, reuseRowObject: false);
    
  6. Maak een weergaveheader met de volgende code als de volgende regel in de DetectChangePoint() methode:

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

    U geeft de volgende informatie weer in de resultaten van de detectie van het wijzigingspunt:

    • Alert geeft een waarschuwing voor een wijzigingspunt aan voor een bepaald gegevenspunt.
    • Score is de ProductSales waarde voor een bepaald gegevenspunt in de gegevensset.
    • P-Value De "P" staat voor waarschijnlijkheid. Hoe dichter de P-waarde bij 0 ligt, hoe groter de kans dat het gegevenspunt een anomalie is.
    • Martingale value wordt gebruikt om te bepalen hoe 'vreemd' een gegevenspunt is, op basis van de volgorde van P-waarden.
  7. Doorloop de predictionsIEnumerable en geef de resultaten weer met de volgende code:

    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. Voeg de volgende aanroep toe aan de DetectChangepoint()methode na de aanroep van de DetectSpike() methode:

    DetectChangepoint(mlContext, _docsize, dataView);
    

Resultaten van puntdetectie wijzigen

De resultaten moeten er ongeveer als volgt uitzien. Tijdens de verwerking worden berichten weergegeven. Mogelijk ziet u waarschuwingen of worden berichten verwerkt. Sommige berichten zijn voor de duidelijkheid verwijderd uit de volgende resultaten.

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

Gefeliciteerd U hebt nu machine learning-modellen gebouwd voor het detecteren van pieken en wijzigingspuntafwijkingen in verkoopgegevens.

U vindt de broncode voor deze zelfstudie in de opslagplaats dotnet/samples .

In deze zelfstudie heeft u het volgende geleerd:

  • De gegevens laden
  • Het model trainen voor detectie van piekafwijkingen
  • Piekafwijkingen detecteren met het getrainde model
  • Het model trainen voor anomaliedetectie van wijzigingspunten
  • Afwijkingen van wijzigingspunten detecteren met de getrainde modus

Volgende stappen

Bekijk de GitHub-opslagplaats machine learning-voorbeelden om een voorbeeld van anomaliedetectie voor seizoensgebondenheidsgegevens te verkennen.