Zelfstudie: Relaties ontdekken in de Synthea--gegevensset met behulp van een semantische koppeling
In deze zelfstudie ziet u hoe u relaties in de openbare Synthea gegevensset detecteert met behulp van een semantische koppeling.
Wanneer u met nieuwe gegevens werkt of zonder een bestaand gegevensmodel werkt, kan het handig zijn om automatisch relaties te detecteren. Deze relatiedetectie kan u helpen bij het volgende:
- het model op hoog niveau begrijpen,
- krijg meer inzichten tijdens verkennende gegevensanalyse,
- bijgewerkte gegevens of nieuwe, binnenkomende gegevens valideren en
- gegevens opschonen.
Zelfs als relaties van tevoren bekend zijn, kan een zoekopdracht naar relaties helpen bij een beter begrip van het gegevensmodel of het identificeren van problemen met de kwaliteit van gegevens.
In deze zelfstudie begint u met een eenvoudig basislijnvoorbeeld waarin u met slechts drie tabellen experimenteert, zodat verbindingen tussen deze tabellen eenvoudig te volgen zijn. Vervolgens geeft u een complexer voorbeeld weer met een grotere tabelset.
In deze zelfstudie leert u het volgende:
- Gebruik onderdelen van de Python-bibliotheek van semantische koppelingen (SemPy) die ondersteuning bieden voor integratie met Power BI en om gegevensanalyse te automatiseren. Deze onderdelen zijn onder andere:
- FabricDataFrame- een pandas-achtige structuur die is uitgebreid met aanvullende semantische informatie.
- Functies voor het ophalen van semantische modellen uit een Fabric-werkruimte in uw notebook.
- Functies waarmee de detectie en visualisatie van relaties in uw semantische modellen wordt geautomatiseerd.
- Los het proces van relatiedetectie voor semantische modellen met meerdere tabellen en afhankelijkheden op.
Voorwaarden
Een Microsoft Fabric-abonnementophalen. Of meld u aan voor een gratis microsoft Fabric-proefversie.
Meld u aan bij Microsoft Fabric-.
Gebruik de ervaringswisselaar aan de linkerkant van de startpagina om over te schakelen naar Fabric.
- Selecteer Werkruimten in het linkernavigatiedeelvenster om uw werkruimte te zoeken en te selecteren. Deze werkruimte wordt uw huidige werkruimte.
Volg mee in het notitieblok
De notebook relationships_detection_tutorial.ipynb begeleidt deze zelfstudie.
Als u het bijbehorende notitieblok voor deze zelfstudie wilt openen, volgt u de instructies in Uw systeem voorbereiden op zelfstudies voor gegevenswetenschap om het notebook in uw werkruimte te importeren.
Als u liever de code van deze pagina kopieert en plakt, kunt u een nieuw notitieblok maken.
Zorg ervoor dat je een lakehouse aan het notebook koppelt voordat je begint met het uitvoeren van code.
Het notebook instellen
In deze sectie stelt u een notebookomgeving in met de benodigde modules en gegevens.
Installeer
SemPy
vanuit PyPI met behulp van de%pip
inline-installatiemogelijkheid in het notebook:%pip install semantic-link
Voer de benodigde importbewerkingen uit van SemPy-modules die u later nodig hebt:
import pandas as pd from sempy.samples import download_synthea from sempy.relationships import ( find_relationships, list_relationship_violations, plot_relationship_metadata )
Importeer pandas voor het afdwingen van een configuratieoptie die helpt bij het opmaken van uitvoer:
import pandas as pd pd.set_option('display.max_colwidth', None)
Haal de voorbeeldgegevens op. Voor deze zelfstudie gebruikt u de Synthea gegevensset van synthetische medische records (kleine versie voor eenvoud):
download_synthea(which='small')
Relaties detecteren op een kleine subset van Synthea- tabellen
Selecteer drie tabellen uit een grotere set:
-
patients
geeft patiëntgegevens op -
encounters
geeft de patiënten aan die medische ontmoeting hadden (bijvoorbeeld een medische afspraak, procedure) -
providers
geeft aan welke medische dienstverleners zorg hebben verleend aan de patiënten
De
encounters
tabel lost een veel-op-veel-relatie tussenpatients
enproviders
op en kan worden beschreven als een associatieve entiteit:patients = pd.read_csv('synthea/csv/patients.csv') providers = pd.read_csv('synthea/csv/providers.csv') encounters = pd.read_csv('synthea/csv/encounters.csv')
-
Relaties tussen de tabellen zoeken met behulp van de
find_relationships
functie van SemPy:suggested_relationships = find_relationships([patients, providers, encounters]) suggested_relationships
Visualiseer de relaties dataframe als een grafiek met behulp van de
plot_relationship_metadata
functie van SemPy.plot_relationship_metadata(suggested_relationships)
De functie legt de relatiehiërarchie van links naar rechts uit, wat overeenkomt met de 'van' en 'naar' tabellen in de uitvoer. Met andere woorden, de onafhankelijke 'from'-tabellen aan de linkerkant gebruiken hun refererende sleutels om te verwijzen naar hun 'naar'-afhankelijkheidstabellen aan de rechterkant. Elk entiteitsvak bevat kolommen die deelnemen aan de 'van' of 'naar'-kant van een relatie.
Standaard worden relaties gegenereerd als 'm:1' (niet als '1:m') of '1:1'. De relaties 1:1 kunnen op een of beide manieren worden gegenereerd, afhankelijk van of de verhouding tussen toegewezen waarden en alle waarden in slechts één of beide richtingen groter is dan
coverage_threshold
. Verderop in deze zelfstudie behandelt u het minder frequente geval van 'm:m'-relaties.
Problemen met relatiedetectie oplossen
In het basislijnvoorbeeld ziet u een geslaagde relatiedetectie voor schone Synthea gegevens. In de praktijk worden de gegevens zelden opgeschoond, waardoor succesvolle detectie wordt voorkomen. Er zijn verschillende technieken die nuttig kunnen zijn wanneer de gegevens niet worden opgeschoond.
In deze sectie van deze zelfstudie wordt de detectie van relaties opgelost wanneer het semantische model vuile gegevens bevat.
Begin met het bewerken van de oorspronkelijke DataFrames om 'vuile' gegevens te verkrijgen en de grootte van de vuile gegevens af te drukken.
# 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))
Ter vergelijking: afdrukgrootten van de oorspronkelijke tabellen:
print(len(patients)) print(len(providers))
Relaties tussen de tabellen zoeken met behulp van de
find_relationships
functie van SemPy:find_relationships([patients_dirty, providers_dirty, encounters])
In de uitvoer van de code ziet u dat er geen relaties zijn gedetecteerd vanwege de fouten die u eerder hebt geïntroduceerd om het semantische model 'vuil' te maken.
Validatie gebruiken
Validatie is het beste hulpprogramma voor het oplossen van fouten in relatiedetectie, omdat:
- Het rapporteert duidelijk waarom een bepaalde relatie niet aan de regels voor Foreign Keys voldoet en om deze reden niet kan worden gedetecteerd.
- Het wordt snel uitgevoerd met grote semantische modellen, omdat deze zich alleen richt op de gedeclareerde relaties en geen zoekopdracht uitvoert.
Validatie kan elk DataFrame gebruiken met kolommen die vergelijkbaar zijn met de kolommen die zijn gegenereerd door find_relationships
. In de volgende code verwijst het suggested_relationships
DataFrame naar patients
in plaats van patients_dirty
, maar u kunt de DataFrames wel aliasen met een woordenlijst:
dirty_tables = {
"patients": patients_dirty,
"providers" : providers_dirty,
"encounters": encounters
}
errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors
Zoekcriteria versoepelen
In meer duistere scenario's kunt u proberen uw zoekcriteria los te maken. Deze methode vergroot de kans op vals-positieven.
Stel
include_many_to_many=True
in en evalueer of dit helpt:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=1)
De resultaten tonen aan dat de relatie tussen
encounters
enpatients
is gedetecteerd, maar er zijn twee problemen:- De relatie geeft een richting aan van
patients
totencounters
, wat een inverse van de verwachte relatie is. Dit komt doordat allepatients
worden gedekt doorencounters
(Coverage From
is 1,0) terwijlencounters
slechts gedeeltelijk worden gedekt doorpatients
(Coverage To
= 0,85), omdat patiëntenrijen ontbreken. - Er is een onbedoelde overeenkomst op een lage cardinaliteit
GENDER
kolom, die overeenkomt qua naam en waarde in beide tabellen, maar het is geen 'm:1'-relatie van interesse. De lage kardinaliteit wordt aangegeven doorUnique Count From
enUnique Count To
kolommen.
- De relatie geeft een richting aan van
Voer
find_relationships
opnieuw uit om alleen te zoeken naar 'm:1'-relaties, maar met een lagerecoverage_threshold=0.5
:find_relationships(dirty_tables, include_many_to_many=False, coverage_threshold=0.5)
Het resultaat toont de juiste richting van de relaties van
encounters
totproviders
. De relatie tussenencounters
enpatients
wordt echter niet gedetecteerd, omdatpatients
niet uniek is, zodat deze niet aan de 'een'-kant van 'm:1'-relatie kan staan.Maak zowel
include_many_to_many=True
alscoverage_threshold=0.5
los:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)
Nu zijn beide relaties van belang zichtbaar, maar er is veel meer ruis:
- De lage kardinaliteitsmatch op
GENDER
is aanwezig. - Er verscheen een 'm:m'-overeenkomst met een hogere kardinaliteit op
ORGANIZATION
, waaruit blijkt datORGANIZATION
waarschijnlijk een kolom is die naar beide tabellen is gedenormaliseerd.
- De lage kardinaliteitsmatch op
Kolomnamen vergelijken
SemPy beschouwt standaard alleen die kenmerken als overeenkomsten die naamgelijkenis vertonen, waarbij het gebruikmaakt van het feit dat databaseontwerpers gerelateerde kolommen meestal op dezelfde manier benoemen. Dit gedrag helpt bij het voorkomen van valse relaties, die het vaakst voorkomen met gehele getallen met een lage kardinaliteit. Als er bijvoorbeeld 1,2,3,...,10
productcategorieën en 1,2,3,...,10
orderstatuscode zijn, worden ze met elkaar verward wanneer alleen waardetoewijzingen worden bekeken zonder rekening te houden met kolomnamen. Ongewenste relaties zouden geen probleem moeten zijn met GUID-achtige sleutels.
SemPy kijkt naar een overeenkomst tussen kolomnamen en tabelnamen. De overeenstemming is bij benadering en niet hoofdlettergevoelig. De meest voorkomende subtekenreeksen van "decorator", zoals 'id', 'code', 'name', 'key', 'pk', 'fk', worden genegeerd. De meest voorkomende matchgevallen zijn als gevolg hiervan:
- een kenmerk met de naam 'kolom' in entiteit 'foo' komt overeen met een kenmerk met de naam 'column' (ook 'COLUMN' of 'Column') in de entiteit 'bar'.
- een kenmerk met de naam 'kolom' in entiteit 'foo' komt overeen met een kenmerk met de naam 'column_id' in 'bar'.
- een kenmerk met de naam 'bar' in entiteit 'foo' komt overeen met een kenmerk met de naam 'code' in 'bar'.
Door eerst de kolomnamen te vergelijken, wordt de detectie sneller uitgevoerd.
Overeenkomen met de kolomnamen:
- Als u wilt weten welke kolommen zijn geselecteerd voor verdere evaluatie, gebruikt u de optie
verbose=2
(verbose=1
alleen de entiteiten weergeeft die worden verwerkt). - De parameter
name_similarity_threshold
bepaalt hoe kolommen worden vergeleken. De drempelwaarde van 1 geeft aan dat u alleen geïnteresseerd bent in 100% wedstrijd.
find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
Bij een gelijkenis van 100% houdt men geen rekening met kleine verschillen tussen namen. In uw voorbeeld hebben de tabellen een meervoudsvorm met achtervoegsel 's', wat resulteert in geen exacte overeenkomst. Dit wordt goed afgehandeld met de standaard
name_similarity_threshold=0.8
.- Als u wilt weten welke kolommen zijn geselecteerd voor verdere evaluatie, gebruikt u de optie
Opnieuw uitvoeren met de standaard
name_similarity_threshold=0.8
:find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0.8);
U ziet dat de id voor meervoudsvorm
patients
nu wordt vergeleken met enkelvoudpatient
zonder dat er te veel andere overbodige vergelijkingen aan de uitvoeringstijd worden toegevoegd.Opnieuw uitvoeren met de standaard
name_similarity_threshold=0
:find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0);
Het wijzigen van
name_similarity_threshold
in 0 is het andere uiterst en geeft aan dat u alle kolommen wilt vergelijken. Dit is zelden nodig en resulteert in een verhoogde uitvoeringstijd en valse overeenkomsten die moeten worden gecontroleerd. Controleer het aantal vergelijkingen in de uitgebreide uitvoer.
Overzicht van tips voor probleemoplossing
- Begin met exacte overeenkomst voor 'm:1'-relaties (dat wil zeggen de standaard-
include_many_to_many=False
encoverage_threshold=1.0
). Dit is meestal wat u wilt. - Gebruik een beperkte focus op kleinere subsets van tabellen.
- Gebruik validatie om problemen met gegevenskwaliteit te detecteren.
- Gebruik
verbose=2
als u wilt weten welke kolommen in aanmerking komen voor relatie. Dit kan leiden tot een grote hoeveelheid output. - Let op de afwegingen van zoekargumenten.
include_many_to_many=True
encoverage_threshold<1.0
kunnen valse relaties produceren die moeilijker te analyseren zijn en moeten worden gefilterd.
Relaties detecteren op de volledige Synthea gegevensset
Het eenvoudige basislijnvoorbeeld was een handig leer- en probleemoplossingsprogramma. In de praktijk kunt u beginnen met een semantisch model, zoals de volledige Synthea gegevensset, die veel meer tabellen bevat. Verken als volgt de volledige synthea gegevensset.
Alle bestanden uit de map synthea/csv- lezen:
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'), }
Zoek relaties tussen de tabellen met behulp van de
find_relationships
functie van SemPy:suggested_relationships = find_relationships(all_tables) suggested_relationships
Relaties visualiseren:
plot_relationship_metadata(suggested_relationships)
Tel hoeveel nieuwe 'm:m'-relaties worden gedetecteerd met
include_many_to_many=True
. Deze relaties zijn naast de eerder getoonde 'm:1'-relaties; Daarom moet u filteren opmultiplicity
:suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
U kunt de relatiegegevens sorteren op verschillende kolommen om meer inzicht te krijgen in hun aard. U kunt er bijvoorbeeld voor kiezen om de uitvoer te orden op
Row Count From
enRow Count To
, waarmee u de grootste tabellen kunt identificeren.suggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)
In een ander semantisch model is het misschien belangrijk om te focussen op het aantal null-waarden
Null Count From
ofCoverage To
.Deze analyse kan u helpen te begrijpen of een van de relaties ongeldig kan zijn en of u ze uit de lijst met kandidaten moet verwijderen.
Verwante inhoud
Bekijk andere tutorials voor semantische koppeling / SemPy:
- Zelfstudie: Gegevens opschonen met functionele afhankelijkheden
- Zelfstudie: Functionele afhankelijkheden analyseren in een semantisch voorbeeldmodel
- Zelfstudie: Relaties ontdekken in een semantisch model met behulp van semantische koppeling
- Zelfstudie: Power BI-metingen extraheren en berekenen uit een Jupyter-notebook