Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce tutoriel montre comment détecter les relations dans le jeu de données Synthea public à l’aide d’un lien sémantique.
Lorsque vous travaillez avec de nouvelles données ou que vous travaillez sans modèle de données existant, il peut être utile de découvrir automatiquement les relations. Cette détection de relation peut vous aider à :
- comprendre le modèle à un niveau élevé,
- obtenir plus d’informations lors de l’analyse exploratoire des données,
- valider les données mises à jour ou nouvelles, les données entrantes et
- nettoyer les données.
Même si les relations sont connues à l’avance, une recherche de relations peut vous aider à mieux comprendre le modèle de données ou l’identification des problèmes de qualité des données.
Dans ce tutoriel, vous commencez par un exemple de base simple où vous expérimentez seulement trois tables afin que les connexions entre elles soient faciles à suivre. Ensuite, vous affichez un exemple plus complexe avec un ensemble de tables plus volumineux.
Dans ce tutoriel, vous allez apprendre à :
- Utilisez des composants de la bibliothèque Python du lien sémantique (SemPy) qui prennent en charge l’intégration à Power BI et aident à automatiser l’analyse des données. Ces composants sont les suivants :
- FabricDataFrame : structure de type pandas améliorée avec des informations sémantiques supplémentaires.
- Fonctions permettant d’extraire des modèles sémantiques d’un espace de travail Fabric dans votre bloc-notes.
- Fonctions qui automatisent la découverte et la visualisation des relations dans vos modèles sémantiques.
- Résolvez les problèmes liés au processus de découverte de relations pour les modèles sémantiques comportant plusieurs tables et interdépendances.
Conditions préalables
Obtenez un abonnement Microsoft Fabric . Vous pouvez également vous inscrire à une version d’évaluation gratuite de Microsoft Fabric .
Connectez-vous à Microsoft Fabric.
Basculez vers Fabric à l’aide du sélecteur d’expérience situé en bas à gauche de votre page d’accueil.
- 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.
Suivre le notebook
Le notebook relationships_detection_tutorial.ipynb accompagne ce tutoriel.
Pour ouvrir le bloc-notes associé pour ce didacticiel, suivez les instructions de Préparer votre système pour les didacticiels de science des données pour importer le bloc-notes dans votre espace de travail.
Si vous préférez copier et coller le code à partir de cette page, vous pouvez créer un bloc-notes.
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 données nécessaires.
Installez
SemPyà partir de PyPI à l’aide de la fonctionnalité d’installation en ligne%pipdans le notebook :%pip install semantic-linkEffectuez les importations nécessaires de modules SemPy dont vous aurez besoin ultérieurement :
import pandas as pd from sempy.samples import download_synthea from sempy.relationships import ( find_relationships, list_relationship_violations, plot_relationship_metadata )Importez pandas pour appliquer une option de configuration qui permet de mettre en forme la sortie :
import pandas as pd pd.set_option('display.max_colwidth', None)Extrayez les exemples de données. Pour ce tutoriel, vous utilisez le jeu de données Synthea de dossiers médicaux synthétiques (petite version pour plus de simplicité) :
download_synthea(which='small')
Détecter les relations sur un petit sous-ensemble de tables Synthea
Sélectionnez trois tables dans un ensemble plus grand :
-
patientsspécifie des informations sur les patients -
encountersspécifie les patients qui avaient des rencontres médicales (par exemple, un rendez-vous médical, une procédure) -
providersspécifie quels prestataires médicaux ont assisté aux patients
La table
encountersrésout une relation de plusieurs à plusieurs entrepatientsetproviderset peut être décrite comme une entité associative :patients = pd.read_csv('synthea/csv/patients.csv') providers = pd.read_csv('synthea/csv/providers.csv') encounters = pd.read_csv('synthea/csv/encounters.csv')-
Recherchez des relations entre les tables à l’aide de la fonction
find_relationshipssemPy :suggested_relationships = find_relationships([patients, providers, encounters]) suggested_relationshipsVisualisez les relations DataFrame en tant que graphique à l’aide de la fonction
plot_relationship_metadatasemPy.plot_relationship_metadata(suggested_relationships)La fonction définit la hiérarchie de relation du côté gauche vers le côté droit, qui correspond aux tables « from » et « to » dans la sortie. En d’autres termes, les tables indépendantes « from » situées à gauche utilisent leurs clés étrangères pour pointer vers leurs tables de dépendance « to » sur le côté droit. Chaque zone d’entité affiche les colonnes qui participent du côté « from » ou « to » d’une relation.
Par défaut, les relations sont générées sous la forme « m :1 » (pas comme « 1 :m ») ou « 1:1 ». Les relations « 1:1 » peuvent être générées d’une ou des deux façons, selon que le ratio des valeurs mappées à toutes les valeurs dépasse
coverage_thresholddans une ou les deux directions. Plus loin dans ce tutoriel, vous couvrez le cas moins fréquent de relations « m :m ».
Résoudre les problèmes de détection des relations
L’exemple de base montre une détection de relation réussie sur des données Synthea propres. En pratique, les données sont rarement propres, ce qui empêche la détection réussie. Il existe plusieurs techniques qui peuvent être utiles lorsque les données ne sont pas propres.
Cette section de ce didacticiel traite de la détection des relations lorsque le modèle sémantique contient des données incorrectes.
Commencez par manipuler les DataFrames d’origine pour obtenir des données « sales » et imprimer la taille des données sales.
# create a dirty 'patients' dataframe by dropping some rows using head() and duplicating some rows using concat() patients_dirty = pd.concat([patients.head(1000), patients.head(50)], axis=0) # create a dirty 'providers' dataframe by dropping some rows using head() providers_dirty = providers.head(5000) # the dirty dataframes have fewer records than the clean ones print(len(patients_dirty)) print(len(providers_dirty))Pour la comparaison, les tailles d’impression des tables d’origine :
print(len(patients)) print(len(providers))Recherchez des relations entre les tables à l’aide de la fonction
find_relationshipssemPy :find_relationships([patients_dirty, providers_dirty, encounters])La sortie du code indique qu’aucune relation n’est détectée en raison des erreurs que vous avez introduites précédemment pour créer le modèle sémantique « sale ».
Utiliser la validation
La validation est le meilleur outil pour résoudre les échecs de détection des relations, car :
- Il signale clairement pourquoi une relation particulière ne suit pas les règles de clé étrangère et ne peut donc pas être détectée.
- Il s’exécute rapidement avec des modèles sémantiques volumineux, car il se concentre uniquement sur les relations déclarées et n’effectue pas de recherche.
La validation peut utiliser n’importe quel DataFrame avec des colonnes similaires à celles générées par find_relationships. Dans le code suivant, le dataFrame suggested_relationships fait référence à patients plutôt qu’à patients_dirty, mais vous pouvez alias les DataFrames avec un dictionnaire :
dirty_tables = {
"patients": patients_dirty,
"providers" : providers_dirty,
"encounters": encounters
}
errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors
Assouplir les critères de recherche
Dans des scénarios plus sombres, vous pouvez essayer de relâcher vos critères de recherche. Cette méthode augmente la possibilité de faux positifs.
Définissez
include_many_to_many=Trueet évaluez s’il aide à :find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=1)Les résultats montrent que la relation entre
encountersetpatientsa été détectée, mais il existe deux problèmes :- La relation indique une direction de
patientsàencounters, qui est une inverse de la relation attendue. Cela est dû au fait que toutes lespatientsont été couvertes parencounters(Coverage Fromest de 1,0) tandis que lesencountersne sont couvertes que partiellement parpatients(Coverage To= 0,85), car les lignes des patients sont manquantes. - Il existe une correspondance accidentelle sur une colonne
GENDERde faible cardinalité, qui correspond par nom et valeur dans les deux tables, mais il ne s’agit pas d’une relation « m:1 » d’intérêt. La cardinalité faible est indiquée par les colonnesUnique Count FrometUnique Count To.
- La relation indique une direction de
Réexécutez
find_relationshipspour rechercher uniquement les relations « m :1 », mais avec unecoverage_threshold=0.5inférieure :find_relationships(dirty_tables, include_many_to_many=False, coverage_threshold=0.5)Le résultat montre la direction correcte des relations entre
encountersetproviders. Toutefois, la relation deencountersàpatientsn’est pas détectée, carpatientsn’est pas unique, de sorte qu’elle ne peut pas être du côté « Un » de la relation « m :1 ».Assouplissez
include_many_to_many=Trueetcoverage_threshold=0.5:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)Maintenant, les deux relations d’intérêt sont visibles, mais il y a beaucoup plus de bruit :
- La correspondance de cardinalité faible sur
GENDERest présente. - Une correspondance m:m de cardinalité plus élevée sur
ORGANIZATIONest apparue, ce qui indique queORGANIZATIONest probablement une colonne dé-normalisée pour les deux tables.
- La correspondance de cardinalité faible sur
Mettre en correspondance les noms de colonnes
Par défaut, SemPy considère comme correspondant uniquement aux attributs qui affichent la similarité du nom, en tirant parti du fait que les concepteurs de base de données nomment généralement les colonnes associées de la même façon. Ce comportement permet d’éviter les relations erronées, qui se produisent le plus fréquemment avec des clés entières de cardinalité faible. Par exemple, s’il existe 1,2,3,...,10 catégories de produits et 1,2,3,...,10 code d’état de commande, ils sont confondus les uns avec les autres lorsque vous examinez uniquement les mappages de valeurs sans prendre en compte les noms de colonnes. Les relations erronées ne devraient pas être un problème avec les clés de type GUID.
SemPy examine une similarité entre les noms de colonnes et les noms de table. La correspondance est approximative et ne respecte pas la casse. Elle ignore les substrings « decorator » les plus fréquemment rencontrées, telles que « id », « code », « name », « key », « pk », « fk ». Par conséquent, les cas de correspondance les plus classiques sont les suivants :
- un attribut appelé « column » dans l’entité « foo » correspond à un attribut appelé « column » (également « COLUMN » ou « Column ») dans l’entité « bar ».
- un attribut appelé 'column' dans l’entité 'foo' correspond à un attribut appelé 'column_id' dans 'bar'.
- un attribut appelé « bar » dans l’entité « foo » correspond à un attribut appelé « code » dans « bar ».
En mettant en correspondance les noms de colonnes en premier, la détection s’exécute plus rapidement.
Mettre en correspondance les noms des colonnes :
- Pour comprendre les colonnes sélectionnées pour une évaluation ultérieure, utilisez l’option
verbose=2(verbose=1répertorie uniquement les entités en cours de traitement). - Le paramètre
name_similarity_thresholddétermine la façon dont les colonnes sont comparées. Le seuil de 1 indique que vous êtes intéressé uniquement par les correspondances à 100 %.
find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);L’exécution avec une similarité à 100 % ne tient pas compte des petites différences entre les noms. Dans votre exemple, les tables ont une forme plurielle avec le suffixe « s », ce qui n’entraîne aucune correspondance exacte. Ceci est géré correctement avec la
name_similarity_threshold=0.8par défaut .- Pour comprendre les colonnes sélectionnées pour une évaluation ultérieure, utilisez l’option
Réexécuter avec la
name_similarity_threshold=0.8par défaut :find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0.8);Notez que les ID de la forme plurielle
patientssont maintenant comparés à la forme singulièrepatientsans ajouter trop d’autres comparaisons superflues au temps d’exécution.Réexécuter avec la
name_similarity_threshold=0par défaut :find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0);La modification de
name_similarity_thresholdà 0 est l’autre extrême et indique que vous souhaitez comparer toutes les colonnes. Cela est rarement nécessaire et entraîne une augmentation du temps d’exécution et des correspondances erronées qui doivent être examinées. Observez le nombre de comparaisons dans la sortie détaillée.
Résumé des conseils de résolution des problèmes
- Commencez à partir d’une correspondance exacte pour les relations « m :1 » (autrement dit, les
include_many_to_many=Falsepar défaut et lescoverage_threshold=1.0). C’est généralement ce que vous voulez. - Utilisez un focus étroit sur des sous-ensembles de tables plus petits.
- Utilisez la validation pour détecter les problèmes de qualité des données.
- Utilisez
verbose=2si vous souhaitez comprendre les colonnes prises en compte pour la relation. Cela peut générer une grande quantité de résultats. - Soyez conscient des compromis liés aux arguments de recherche.
include_many_to_many=Trueetcoverage_threshold<1.0peuvent produire des relations erronées qui peuvent être plus difficiles à analyser et qui devront être filtrées.
Détecter les relations sur le jeu de données complet Synthea
L’exemple de base simple était un outil pratique d’apprentissage et de résolution des problèmes. Dans la pratique, vous pouvez commencer à partir d’un modèle sémantique tel que le jeu de données Synthea complet, qui a beaucoup plus de tables. Explorez le jeu de données complet synthea comme suit.
Lisez tous les fichiers du répertoire synthea/csv :
all_tables = { "allergies": pd.read_csv('synthea/csv/allergies.csv'), "careplans": pd.read_csv('synthea/csv/careplans.csv'), "conditions": pd.read_csv('synthea/csv/conditions.csv'), "devices": pd.read_csv('synthea/csv/devices.csv'), "encounters": pd.read_csv('synthea/csv/encounters.csv'), "imaging_studies": pd.read_csv('synthea/csv/imaging_studies.csv'), "immunizations": pd.read_csv('synthea/csv/immunizations.csv'), "medications": pd.read_csv('synthea/csv/medications.csv'), "observations": pd.read_csv('synthea/csv/observations.csv'), "organizations": pd.read_csv('synthea/csv/organizations.csv'), "patients": pd.read_csv('synthea/csv/patients.csv'), "payer_transitions": pd.read_csv('synthea/csv/payer_transitions.csv'), "payers": pd.read_csv('synthea/csv/payers.csv'), "procedures": pd.read_csv('synthea/csv/procedures.csv'), "providers": pd.read_csv('synthea/csv/providers.csv'), "supplies": pd.read_csv('synthea/csv/supplies.csv'), }Recherchez des relations entre les tables à l’aide de la fonction
find_relationshipssemPy :suggested_relationships = find_relationships(all_tables) suggested_relationshipsVisualiser les relations :
plot_relationship_metadata(suggested_relationships)Comptez le nombre de nouvelles relations « m :m » découvertes avec
include_many_to_many=True. Ces relations s'ajoutent aux relations de type « m:1 » précédemment affichées ; par conséquent, vous devez filtrer surmultiplicity:suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) suggested_relationships[suggested_relationships['Multiplicity']=='m:m']Vous pouvez trier les données de relation par différentes colonnes pour mieux comprendre leur nature. Par exemple, vous pouvez choisir de classer la sortie par
Row Count FrometRow Count To, ce qui permet d’identifier les tables les plus volumineuses.suggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)Dans un modèle sémantique différent, il serait peut-être important de se concentrer sur le nombre de valeurs null
Null Count FromouCoverage To.Cette analyse peut vous aider à comprendre si l’une des relations peut être non valide et si vous devez les supprimer de la liste des candidats.
Contenu connexe
Consultez d’autres didacticiels pour le lien sémantique / SemPy :
- Didacticiel : Nettoyer les données avec des dépendances fonctionnelles
- didacticiel : Analyser les dépendances fonctionnelles dans un exemple de modèle sémantique
- Tutoriel : Découvrir les relations dans un modèle sémantique, à l’aide d’un lien sémantique
- Tutoriel : Extraire et calculer des mesures Power BI à partir d’un notebook Jupyter