Partager via


Tutoriel : valider des données à l’aide de SemPy et Great Expectations (GX)

Dans ce tutoriel, vous allez apprendre à utiliser SemPy avec Great Expectations (GX) pour effectuer la validation des données sur des modèles sémantiques Power BI.

Ce didacticiel vous explique les procédures suivantes :

  • Validez les contraintes sur un jeu de données dans votre espace de travail Fabric avec la source de données Fabric de Great Expectations (basée sur un lien sémantique).
    • Configurez un contexte de données GX, des ressources de données et des attentes.
    • Affichez les résultats de validation avec un point de contrôle GX.
  • Utilisez un lien sémantique pour analyser les données brutes.

Prérequis

  • Sélectionnez Espaces de travail dans le volet de navigation gauche pour rechercher et sélectionner votre espace de travail. Cet espace de travail devient votre espace de travail actuel.
  • Téléchargez le fichier Exemple d’analyse des données de vente au détail PBIX.pbix.
  • Dans votre espace de travail, utilisez le bouton Charger pour charger le fichier Exemple d’analyse des données de vente au détail PBIX.pbix dans l’espace de travail.

Suivez dans le notebook

great_expectations_tutorial.ipynb est le notebook qui accompagne ce tutoriel.

Pour ouvrir le notebook accompagnant ce tutoriel, suivez les instructions fournies dans Préparer votre système pour le tutoriel sur la science des données afin d’importer les notebooks dans votre espace de travail.

Si vous préférez copier et coller le code de cette page, vous pouvez créer un nouveau notebook.

Assurez-vous d’attacher un lakehouse au notebook avant de commencer à exécuter du code.

Configurer le notebook

Dans cette section, vous configurez un environnement de notebook avec les modules et les données nécessaires.

  1. Installez SemPy à partir des bibliothèques Great Expectations pertinentes depuis PyPI en utilisant la fonctionnalité d’installation %pip incluse dans le notebook.
# install libraries
%pip install semantic-link great-expectations great_expectations_experimental great_expectations_zipcode_expectations

# load %%dax cell magic
%load_ext sempy
  1. Effectuez les importations nécessaires des modules dont vous aurez besoin plus tard :
import great_expectations as gx
from great_expectations.expectations.expectation import ExpectationConfiguration
from great_expectations_zipcode_expectations.expectations import expect_column_values_to_be_valid_zip5

Configurer le contexte de données GX et la source de données

Pour commencer à utiliser Great Expectations, vous devez d’abord configurer un contexte de données GX. Le contexte sert de point d’entrée pour les opérations GX et contient toutes les configurations pertinentes.

context = gx.get_context()

Vous pouvez maintenant ajouter votre jeu de données Fabric à ce contexte en tant que source de données pour commencer à interagir avec les données. Ce tutoriel utilise un exemple de modèle sémantique Power BI standard Exemple d’analyse des données de vente au détail PBIX.pbix.

ds = context.sources.add_fabric_powerbi("Retail Analysis Data Source", dataset="Retail Analysis Sample PBIX")

Spécifier des ressources de données

Définissez des ressources de données pour spécifier le sous-ensemble de données avec lequel vous souhaitez travailler. La ressource peut être aussi simple que les tables complètes ou aussi complexe qu’une requête DAX (Data Analysis Expressions) personnalisée.

Ici, vous allez ajouter plusieurs ressources :

Table Power BI

Ajoutez une table Power BI en tant que ressource de données.

ds.add_powerbi_table_asset("Store Asset", table="Store")

Mesure Power BI

Si votre jeu de données contient des mesures préconfigurées, vous ajoutez les mesures en tant que ressources à la suite d’une API similaire à evaluate_measure de SemPy.

ds.add_powerbi_measure_asset(
    "Total Units Asset",
    measure="TotalUnits",
    groupby_columns=["Time[FiscalYear]", "Time[FiscalMonth]"]
)

DAX

Si vous souhaitez définir vos propres mesures ou avoir plus de contrôle sur des lignes spécifiques, vous pouvez ajouter une ressource DAX avec une requête DAX personnalisée. Ici, nous définissons une mesure Total Units Ratio en divisant deux mesures existantes.

ds.add_powerbi_dax_asset(
    "Total Units YoY Asset",
    dax_string=
    """
    EVALUATE SUMMARIZECOLUMNS(
        'Time'[FiscalYear],
        'Time'[FiscalMonth],
        "Total Units Ratio", DIVIDE([Total Units This Year], [Total Units Last Year])
    )    
    """
)

Requête DMV

Dans certains cas, il peut être utile d’utiliser les calculs de la vue de gestion dynamique (DMV) dans le cadre du processus de validation des données. Par exemple, vous pouvez suivre le nombre de violations d’intégrité référentielle au sein de votre jeu de données. Pour plus d'informations, consultez « Nettoyer les données = rapports plus rapides »

ds.add_powerbi_dax_asset(
    "Referential Integrity Violation",
    dax_string=
    """
    SELECT
        [Database_name],
        [Dimension_Name],
        [RIVIOLATION_COUNT]
    FROM $SYSTEM.DISCOVER_STORAGE_TABLES
    """
)

Attentes

Pour ajouter des contraintes spécifiques aux ressources, vous devez d'abord configurer Suites d'attentes. Après avoir ajouté des attentes individuelles à chaque suite, vous pouvez ensuite mettre à jour le contexte de données configuré au début de la nouvelle suite. Pour obtenir la liste complète des attentes disponibles, consultez la Galerie d’attentes GX.

Commencez par ajouter une « Suite de magasin de vente au détail » avec deux attentes :

  • un code postal valide
  • une table dont le nombre de lignes est compris entre 80 et 200
suite_store = context.add_expectation_suite("Retail Store Suite")

suite_store.add_expectation(ExpectationConfiguration("expect_column_values_to_be_valid_zip5", { "column": "PostalCode" }))
suite_store.add_expectation(ExpectationConfiguration("expect_table_row_count_to_be_between", { "min_value": 80, "max_value": 200 }))

context.add_or_update_expectation_suite(expectation_suite=suite_store)

Mesure TotalUnits

Ajoutez une « Suite de mesure de vente au détail » avec une attente :

  • Les valeurs de colonne doivent être supérieures à 50 000
suite_measure = context.add_expectation_suite("Retail Measure Suite")
suite_measure.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_between", 
    {
        "column": "TotalUnits",
        "min_value": 50000
    }
))

context.add_or_update_expectation_suite(expectation_suite=suite_measure)

Total Units Ratio DAX

Ajoutez une « Suite DAX de vente au détail » avec une attente :

  • Les valeurs de colonne pour le ratio total d’unités doivent être comprises entre 0,8 et 1,5
suite_dax = context.add_expectation_suite("Retail DAX Suite")
suite_dax.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_between", 
    {
        "column": "[Total Units Ratio]",
        "min_value": 0.8,
        "max_value": 1.5
    }
))

context.add_or_update_expectation_suite(expectation_suite=suite_dax)

Violations d’intégrité référentielle (DMV)

Ajoutez une « Suite DMV de vente au détail » avec une attente :

  • RIVIOLATION_COUNT doit être 0
suite_dmv = context.add_expectation_suite("Retail DMV Suite")
# There should be no RI violations
suite_dmv.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_in_set", 
    {
        "column": "RIVIOLATION_COUNT",
        "value_set": [0]
    }
))
context.add_or_update_expectation_suite(expectation_suite=suite_dmv)

Validation

Pour exécuter réellement les attentes spécifiées sur les données, commencez par créer un point de contrôle et ajoutez-le au contexte. Pour plus d’informations sur la configuration de point de contrôle, consultez Flux de travail de validation des données.

checkpoint_config = {
    "name": f"Retail Analysis Checkpoint",
    "validations": [
        {
            "expectation_suite_name": "Retail Store Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Store Asset",
            },
        },
        {
            "expectation_suite_name": "Retail Measure Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Total Units Asset",
            },
        },
        {
            "expectation_suite_name": "Retail DAX Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Total Units YoY Asset",
            },
        },
        {
            "expectation_suite_name": "Retail DMV Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Referential Integrity Violation",
            },
        },
    ],
}
checkpoint = context.add_checkpoint(
    **checkpoint_config
)

Exécutez maintenant le point de contrôle et extrayez les résultats en tant que tramedonnées Pandas pour une mise en forme simple.

result = checkpoint.run()

Traitez et imprimez vos résultats.

import pandas as pd

data = []

for run_result in result.run_results:
    for validation_result in result.run_results[run_result]["validation_result"]["results"]:
        row = {
            "Batch ID": run_result.batch_identifier,
            "type": validation_result.expectation_config.expectation_type,
            "success": validation_result.success
        }

        row.update(dict(validation_result.result))
        
        data.append(row)

result_df = pd.DataFrame.from_records(data)    

result_df[["Batch ID", "type", "success", "element_count", "unexpected_count", "partial_unexpected_list"]]

Le tableau affiche les résultats de validation.

À partir de ces résultats, vous pouvez voir que toutes vos attentes ont été validées, à l’exception de l’attente « Total Units YoY Asset » que vous avez définie par le biais d’une requête DAX personnalisée.

Diagnostics

À l’aide d’un lien sémantique, vous pouvez récupérer les données sources pour comprendre quelles années exactes sont hors limites. Le lien sémantique fournit une magic incluse pour l’exécution de requêtes DAX. Utilisez le lien sémantique pour exécuter la même requête que celle que vous avez transférée vers la ressource de données GX et visualiser les valeurs obtenues.

%%dax "Retail Analysis Sample PBIX"

EVALUATE SUMMARIZECOLUMNS(
    'Time'[FiscalYear],
    'Time'[FiscalMonth],
    "Total Units Ratio", DIVIDE([Total Units This Year], [Total Units Last Year])
)

Le tableau affiche les résultats du résumé de la requête DAX.

Enregistrez ces résultats dans une tramedonnées.

df = _

Tracez les résultats.

import matplotlib.pyplot as plt

df["Total Units % Change YoY"] = (df["[Total Units Ratio]"] - 1)

df.set_index(["Time[FiscalYear]", "Time[FiscalMonth]"]).plot.bar(y="Total Units % Change YoY")

plt.axhline(0)

plt.axhline(-0.2, color="red", linestyle="dotted")
plt.axhline( 0.5, color="red", linestyle="dotted")

None

Le tracé affiche les résultats du résumé de la requête DAX.

À partir du tracé, vous pouvez voir que avril et juillet étaient légèrement hors limites et vous pouvez ensuite prendre d’autres mesures pour enquêter.

Stocker la configuration GX

Lorsque les données de votre jeu de données changent au fil du temps, vous pouvez réexécuter les validations GX que vous venez d’effectuer. Actuellement, le contexte de données (contenant les ressources de données connectées, les suites d’attentes et le point de contrôle) est éphémère, mais il peut être converti en contexte de fichier pour une utilisation ultérieure. Vous pouvez également instancier un contexte de fichier (consultez Instancier un contexte de données).

context = context.convert_to_file_context()

Maintenant que vous avez enregistré le contexte, copiez le répertoire gx dans votre lakehouse.

Important

Cette cellule part du principe que vous ajouté un lakehouse au notebook. S’il n’y a pas de lakehouse attaché, vous ne verrez pas d’erreur, mais vous ne pourrez pas plus tard obtenir le contexte. Si vous ajoutez un lakehouse maintenant, le noyau redémarre. Vous devrez donc réexécuter l’intégralité du notebook pour revenir à ce stade.

# copy GX directory to attached lakehouse
!cp -r gx/ /lakehouse/default/Files/gx

À présent, des contextes futurs peuvent être créés avec context = gx.get_context(project_root_dir="<your path here>") pour utiliser toutes les configurations de ce tutoriel.

Par exemple, dans un nouveau notebook, attachez le même lakehouse et utilisez context = gx.get_context(project_root_dir="/lakehouse/default/Files/gx") pour récupérer le contexte.

Découvrez d’autres tutoriels pour le lien sémantique / SemPy :