Détection d’anomalie multivariée

Ce tutoriel vous montre comment entraîner un modèle de détection d’anomalies multivarié dans un notebook Fabric à l’aide d’exemples de données stockées dans un eventhouse. Vous utilisez ensuite le modèle entraîné dans un ensemble de requêtes KQL pour noter de nouvelles données et visualiser les anomalies.

Pour plus d’informations sur l’arrière-plan, consultez Détection d’anomalies multivariées dans Microsoft Fabric - vue d’ensemble.

Prérequis

Partie 1 : Activer la disponibilité de OneLake

Activez la disponibilité de OneLake avant de charger des données dans l’eventhouse. Ce paramètre rend les données ingérées disponibles dans OneLake afin que vous puissiez accéder à la même table à partir d’un bloc-notes plus loin dans le tutoriel.

  1. Dans votre espace de travail, ouvrez l’eventhouse que vous avez créé dans les conditions préalables, puis sélectionnez la base de données dans laquelle vous souhaitez stocker vos données.

  2. Dans le volet Détails de la base de données , définissez la disponibilité de OneLakesur Activé.

    Capture d’écran de l’activation de la disponibilité de OneLake dans votre eventhouse.

Partie 2 : Activer le plug-in KQL Python

Dans cette étape, vous activez le plug-in Python dans votre eventhouse. Cette étape est nécessaire pour exécuter le code Python dans l’ensemble de requêtes KQL dans la partie 9 : prédire les anomalies dans un ensemble de requêtes KQL. Sélectionnez l’image Python qui inclut le package de détecteur d’anomalies de série chronologique.

  1. Dans Eventhouse, sélectionnez Eventhouse>Plugins dans le ruban.

  2. Dans le volet Plug-ins, réglez l’extension de langage Python sur Activé.

  3. Sélectionnez Python 3.11.7 DL.

  4. Cliquez sur Terminé.

    Capture d’écran montrant comment activer le package Python 3.11.7 DL dans l’eventhouse.

Partie 3 : Créer un environnement Spark

Dans cette étape, vous créez un environnement Spark pour exécuter le notebook qui sert à entraîner le modèle de détection d’anomalies multivariables. Pour plus d’informations, consultez Créer et gérer des environnements.

  1. Dans votre espace de travail, sélectionnez + Nouvel élément, puis sélectionnez Environnement.

    Capture d’écran de la vignette Environnement dans la fenêtre Nouvel élément.

  2. Entrez MVAD_ENV le nom de l’environnement, puis sélectionnez Créer.

  3. Sous Bibliothèques, sélectionnez Bibliothèques publiques.

  4. Sélectionnez Ajouter à partir de PyPI.

  5. Dans la zone de recherche, entrez time-series-anomaly-detector. Dans la zone Version , entrez 0.3.9.

  6. Cliquez sur Enregistrer.

    Capture d’écran de l’ajout du package PyPI à l’environnement Spark.

  7. Sélectionnez l’onglet Accueil dans l’environnement.

  8. Dans le ruban en haut, cliquez sur l’icône Publier.

  9. Sélectionnez Publier tous. Cette étape peut prendre plusieurs minutes.

    Capture d’écran montrant la publication de l’environnement.

Partie 4 : Charger des données dans la maison d’événements

  1. Dans l’eventhouse, pointez sur la base de données KQL où vous souhaitez stocker vos données, puis sélectionnez Plus de menu [...]>Obtenir des données>Fichier local.

    Capture d’écran de l’obtention de données à partir du fichier local.

  2. Sélectionnez + Nouvelle table, puis entrez demo_stocks_change le nom de la table.

  3. Dans la boîte de dialogue de chargement, sélectionnez Rechercher les fichiers, puis chargez l’exemple de fichier de données que vous avez téléchargé dans Les conditions préalables.

  4. Cliquez sur Suivant.

  5. Dans la section Inspecter les données, vérifiez que première ligne est l’en-tête de colonne est sur Activé.

  6. Sélectionnez Terminer.

  7. Une fois que les données sont chargées, cliquez sur Fermer.

Partie 5 : Copier le chemin OneLake

Sélectionnez la table demo_stocks_change. Dans le volet Détails du tableau, sélectionnez Dossier OneLake pour copier le chemin d’accès OneLake dans le Presse-papiers. Enregistrez le chemin d’accès dans un éditeur de texte pour une utilisation ultérieure.

Capture d’écran de la copie du chemin OneLake.

Partie 6 : Préparer le bloc-notes

  1. Sélectionnez votre espace de travail.

  2. Sélectionnez Importer>un bloc-notes>à partir de cet ordinateur.

  3. Sélectionnez Charger, puis choisissez le bloc-notes que vous avez téléchargé dans Prérequis.

  4. Une fois le notebook chargé, vous pouvez rechercher et ouvrir votre notebook à partir de votre espace de travail.

  5. Dans le ruban supérieur, sélectionnez la liste déroulante Par défaut de l’espace de travail, puis sélectionnez l’environnement que vous avez créé à l’étape précédente.

    Capture d’écran de la sélection de l’environnement dans le notebook.

Partie 7 : Exécuter le carnet

  1. Importer des packages standard.

    import numpy as np
    import pandas as pd
    
  2. Spark a besoin d’un URI ABFSS pour se connecter en toute sécurité au stockage OneLake. Définissez donc une fonction d’assistance qui convertit l’URI OneLake en URI ABFSS.

    def convert_onelake_to_abfss(onelake_uri):
        if not onelake_uri.startswith('https://'):
            raise ValueError("Invalid OneLake URI. It should start with 'https://'.")
        uri_without_scheme = onelake_uri[8:]
        parts = uri_without_scheme.split('/')
        if len(parts) < 3:
            raise ValueError("Invalid OneLake URI format.")
        container_name = parts[1]
        path = '/'.join(parts[2:])
        abfss_uri = f"abfss://{container_name}@{parts[0]}/{path}"
        return abfss_uri
    
  3. Remplacez OneLakeTableURI par l’URI OneLake que vous avez copié dans la partie 5 : copiez le chemin OneLake, puis chargez la demo_stocks_change table dans un dataframe pandas.

    onelake_uri = "OneLakeTableURI"  # Replace with your OneLake table URI.
    abfss_uri = convert_onelake_to_abfss(onelake_uri)
    print(abfss_uri)
    
    df = spark.read.format('delta').load(abfss_uri)
    df = df.toPandas()
    df['Date'] = pd.to_datetime(df['Date'])
    df = df.set_index('Date').sort_index()
    print(df.shape)
    df.head(3)
    
  4. Exécutez les cellules suivantes pour préparer les dataframes d’entraînement et de prédiction.

    Remarque

    Les prédictions réelles s’exécutent dans l’Eventhouse de la Partie 9 : Prédire les anomalies dans un jeu de requêtes KQL. Dans un scénario de production, vous notez généralement de nouvelles données de streaming. Dans ce tutoriel, le jeu de données est divisé par date en plages d’apprentissage et de prédiction pour simuler des données historiques et entrantes.

    features_cols = ['AAPL', 'AMZN', 'GOOG', 'MSFT', 'SPY']
    cutoff_date = pd.Timestamp('2023-01-01')
    
    train_df = df.loc[df.index < cutoff_date, features_cols]
    print(train_df.shape)
    train_df.head(3)
    
    train_len = len(train_df)
    predict_len = len(df) - train_len
    print(f'Total samples: {len(df)}. Split to {train_len} for training, {predict_len} for testing')
    
  5. Exécutez les cellules pour entraîner le modèle et l’enregistrer dans le registre de modèles MLflow Fabric.

    from anomaly_detector import MultivariateAnomalyDetector
    model = MultivariateAnomalyDetector()
    
    sliding_window = 200
    params = {"sliding_window": sliding_window}
    
    model.fit(train_df, params=params)
    
    model_name = "mvad_5_stocks_model"
    
    import mlflow
    
    with mlflow.start_run():
        mlflow.log_params(params)
        mlflow.set_tag("Training Info", "MVAD on 5 Stocks Dataset")
    
        model_info = mlflow.pyfunc.log_model(
            python_model=model,
            artifact_path="mvad_artifacts",
            registered_model_name=model_name,
        )
    
  6. Exécutez la cellule suivante pour obtenir le chemin d’accès du modèle enregistré que vous utiliserez ensuite pour effectuer des prédictions dans le bac à sable Python KQL.

    from mlflow.tracking import MlflowClient
    
    client = MlflowClient()
    mvs = client.search_model_versions(f"name='{model_name}'")
    latest = max(mvs, key=lambda v: v.creation_timestamp)
    model_abfss = latest.source
    print(model_abfss)
    
  7. Copiez l’URI du modèle à partir de la sortie de la dernière cellule. Vous l’utilisez dans la partie 9.

Partie 8 : Créer un ensemble de requêtes KQL

Pour obtenir des informations générales, consultez Créer un ensemble de requêtes KQL.

  1. Dans votre espace de travail, sélectionnez + Nouvel élément>KQL Queryset.
  2. Entrez MultivariateAnomalyDetectionTutorial, puis sélectionnez Créer.
  3. Dans la fenêtre du catalogue OneLake , sélectionnez la base de données KQL où vous avez stocké les données.
  4. Sélectionnez Connecter.

Partie 9 : Prédire les anomalies dans un ensemble de requêtes KQL

  1. Exécutez la requête suivante .create-or-alter function pour définir la predict_fabric_mvad_fl() fonction stockée :

    .create-or-alter function with (folder = "Packages\\ML", docstring = "Predict MVAD model in Microsoft Fabric")
    predict_fabric_mvad_fl(samples:(*), features_cols:dynamic, artifacts_uri:string, trim_result:bool=false)
    {
        let s = artifacts_uri;
        let artifacts = bag_pack('MLmodel', strcat(s, '/MLmodel;impersonate'), 'conda.yaml', strcat(s, '/conda.yaml;impersonate'),
                                 'requirements.txt', strcat(s, '/requirements.txt;impersonate'), 'python_env.yaml', strcat(s, '/python_env.yaml;impersonate'),
                                 'python_model.pkl', strcat(s, '/python_model.pkl;impersonate'));
        let kwargs = bag_pack('features_cols', features_cols, 'trim_result', trim_result);
        let code = ```if 1:
            import os
            import shutil
            import mlflow
            work_dir = os.environ.get("UPLOAD_PATH")
            model_dir = work_dir + '/mvad_model'
            model_data_dir = model_dir + '/data'
            os.mkdir(model_dir)
            shutil.move(work_dir + '/MLmodel', model_dir)
            shutil.move(work_dir + '/conda.yaml', model_dir)
            shutil.move(work_dir + '/requirements.txt', model_dir)
            shutil.move(work_dir + '/python_env.yaml', model_dir)
            shutil.move(work_dir + '/python_model.pkl', model_dir)
            features_cols = kargs["features_cols"]
            trim_result = kargs["trim_result"]
            test_data = df[features_cols]
            model = mlflow.pyfunc.load_model(model_dir)
            predictions = model.predict(test_data)
            predict_result = pd.DataFrame(predictions)
            samples_offset = len(df) - len(predict_result)        # this model doesn't output predictions for the first sliding_window-1 samples
            if trim_result:                                       # trim the prefix samples
                result = df[samples_offset:]
                result.iloc[:,-4:] = predict_result.iloc[:, 1:]   # no need to copy 1st column which is the timestamp index
            else:
                result = df                                       # output all samples
                result.iloc[samples_offset:,-4:] = predict_result.iloc[:, 1:]
            ```;
        samples
        | evaluate python(typeof(*), code, kwargs, external_artifacts=artifacts)
    }
    
  2. Exécutez la requête de prédiction suivante. Remplacez enter your model URI here par l’URI que vous avez copié à la fin de la partie 7 : exécutez le notebook.

    La requête détecte les anomalies multivariées pour les cinq actions à l’aide du modèle entraîné, puis affiche les résultats sous la forme d’un anomalychart. Les points anormaux sont affichés sur le premier stock (AAPL), mais ils représentent des anomalies dans le comportement conjoint des cinq actions à une date donnée.

    let cutoff_date=datetime(2023-01-01);
    let num_predictions=toscalar(demo_stocks_change | where Date >= cutoff_date | count);   //  number of latest points to predict
    let sliding_window=200;                                                                 //  should match the window that was set for model training
    let prefix_score_len = sliding_window/2+min_of(sliding_window/2, 200)-1;
    let num_samples = prefix_score_len + num_predictions;
    demo_stocks_change
    | top num_samples by Date desc
    | order by Date asc
    | extend is_anomaly=bool(false), score=real(null), severity=real(null), interpretation=dynamic(null)
    | invoke predict_fabric_mvad_fl(pack_array('AAPL', 'AMZN', 'GOOG', 'MSFT', 'SPY'),
                // NOTE: Update artifacts_uri to model path
                artifacts_uri='enter your model URI here',
                trim_result=true)
    | summarize Date=make_list(Date), AAPL=make_list(AAPL), AMZN=make_list(AMZN), GOOG=make_list(GOOG), MSFT=make_list(MSFT), SPY=make_list(SPY), anomaly=make_list(toint(is_anomaly))
    | render anomalychart with(anomalycolumns=anomaly, title='Stock price changes in % with anomalies')
    

Le graphique d’anomalies résultant ressemble à l’image suivante :

Capture d’écran de la sortie d’anomalie multivariée.

Nettoyer les ressources

Lorsque vous avez terminé le didacticiel, supprimez les ressources que vous avez créées pour éviter les coûts inutiles :

  1. Accédez à la page d’accueil de votre espace de travail.
  2. Supprimez l’environnement que vous avez créé dans ce tutoriel.
  3. Supprimez le notebook que vous avez créé dans ce tutoriel.
  4. Supprimez l’eventhouse ou la base de données utilisée dans ce didacticiel.
  5. Supprimez l’ensemble de requêtes KQL que vous avez créé dans ce tutoriel.