Freigeben über


Tutorial: Entdecken von Beziehungen im Synthea-Dataset mithilfe von Semantic Link

In diesem Lernprogramm wird veranschaulicht, wie Beziehungen im öffentlichen Synthea-Dataset mithilfe von Semantic Link erkannt werden.

Wenn Sie mit neuen Daten oder ohne ein vorhandenes Datenmodell arbeiten, kann es hilfreich sein, Beziehungen automatisch zu ermitteln. Diese Beziehungserkennung kann Ihnen dabei helfen:

  • Das Modell auf hoher Ebene zu verstehen,
  • mehr Einblicke während der explorativen Datenanalyse zu gewinnen,
  • aktualisierte Daten oder neue, eingehende Daten zu überprüfen und
  • Daten zu bereinigen.

Auch wenn Beziehungen im Voraus bekannt sind, kann eine Suche nach Beziehungen helfen, das Datenmodell besser zu verstehen oder Probleme mit der Datenqualität zu identifizieren.

In diesem Tutorial beginnen Sie mit einem einfachen Basisplanbeispiel, in dem Sie mit nur drei Tabellen experimentieren, sodass Verbindungen zwischen ihnen leicht zu verfolgen sind. Anschließend sehen Sie ein komplexeres Beispiel mit einem größeren Tabellensatz an.

In diesem Tutorial lernen Sie Folgendes:

  • Verwenden Sie Komponenten der Python-Bibliothek von Semantic Link (SemPy), welche die Integration in Power BI unterstützen und bei der Automatisierung der Datenanalyse helfen. Zu diesen Komponenten gehören:
    • FabricDataFrame: eine Pandas-ähnliche Struktur, die um zusätzliche semantische Informationen erweitert wurde.
    • Funktionen zum Abrufen von semantischen Modellen aus einem Fabric-Arbeitsbereich in Ihr Notizbuch.
    • Funktionen, welche die Ermittlung und Visualisierung von Beziehungen in Ihren semantischen Modellen automatisieren.
  • Problembehandlung für den Prozess der Beziehungsermittlung für semantische Modelle mit mehreren Tabellen und Abhängigkeiten.

Voraussetzungen

  • Wählen Sie im linken Navigationsbereich Arbeitsbereiche aus, um Ihren Arbeitsbereich zu suchen und auszuwählen. Dieser Arbeitsbereich wird zu Ihrem aktuellen Arbeitsbereich.

Das Notebook für das Tutorial

Das relationships_detection_tutorial.ipynb-Notizbuch begleitet dieses Tutorial.

Um das zugehörige Notebook für dieses Tutorial zu öffnen, befolgen Sie die Anweisungen unter Vorbereiten Ihres Systems für Data-Science-Tutorials zum Importieren des Notebooks in Ihren Arbeitsbereich.

Wenn Sie den Code lieber von dieser Seite kopieren und einfügen möchten, können Sie auch ein neues Notebook erstellen.

Fügen Sie unbedingt ein Lakehouse an das Notebook an, bevor Sie mit der Ausführung von Code beginnen.

Einrichten des Notebooks

In diesem Abschnitt richten Sie eine Notizbuchumgebung mit den erforderlichen Modulen und Daten ein.

  1. Installieren Sie SemPy über PyPI mithilfe der %pip-Inlineinstallationsfunktion innerhalb des Notizbuchs:

    %pip install semantic-link
    
  2. Führen Sie die erforderlichen Importvorgänge von Modulen durch, die Sie später benötigen:

    import pandas as pd
    
    from sempy.samples import download_synthea
    from sempy.relationships import (
        find_relationships,
        list_relationship_violations,
        plot_relationship_metadata
    )
    
  3. Importieren Sie Pandas zum Erzwingen einer Konfigurationsoption, die bei der Ausgabeformatierung hilft:

    import pandas as pd
    pd.set_option('display.max_colwidth', None)
    
  4. Ziehen Sie die Beispieldaten. In diesem Tutorial verwenden Sie das Synthea-Dataset synthetischer Medizinische Datensätze (kleine Version zur Einfachheit):

    download_synthea(which='small')
    

Erkennen von Beziehungen in einer kleinen Teilmenge von Synthea-Tabellen

  1. Wählen Sie drei Tabellen aus einem größeren Satz aus:

    • patients gibt Patienteninformationen an
    • encounters gibt die Patienten an, die medizinische Vorfälle hatten (z. B. ein medizinischer Termin, eine Behandlung)
    • providers gibt an, welche medizinischen Dienstleister die Patienten behandelt haben

    Die encounters Tabelle löst eine n:n-Beziehung zwischen patients und providers aus und kann als assoziative Entitätbeschrieben werden:

    patients = pd.read_csv('synthea/csv/patients.csv')
    providers = pd.read_csv('synthea/csv/providers.csv')
    encounters = pd.read_csv('synthea/csv/encounters.csv')
    
  2. Suchen von Beziehungen zwischen den Tabellen mithilfe der find_relationships-Funktion von SemPy:

    suggested_relationships = find_relationships([patients, providers, encounters])
    suggested_relationships
    
  3. Visualisieren Sie die Beziehungen von DataFrame als Diagramm mithilfe der plot_relationship_metadata-Funktion von SemPy.

    plot_relationship_metadata(suggested_relationships)
    

    Screenshot mit Beziehungen zwischen Tabellen im Dataset.

    Die Funktion legt die Beziehungshierarchie von der linken Seite zur rechten Seite dar, die den Tabellen "von" und "zu" in der Ausgabe entspricht. Mit anderen Worten: Die unabhängigen "von"-Tabellen auf der linken Seite verwenden ihre Fremdschlüssel, um auf ihre Abhängigkeitstabellen auf der rechten Seite zu verweisen. Jedes Entitätsfeld zeigt Spalten an, die entweder an der "von"- oder "an"-Seite an einer Beziehung teilhaben.

    Standardmäßig werden Beziehungen als "m:1" (nicht als "1:m") oder "1:1" generiert. Die Beziehungen "1:1" können auf eine oder beide Arten generiert werden, je nachdem, ob das Verhältnis der zugeordneten Werte zu allen Werten coverage_threshold in nur eine oder beide Richtungen überschreitet. Später in diesem Tutorial behandeln Sie den weniger häufigen Fall von "m:m"-Beziehungen.

Behandeln von Problemen bei der Beziehungserkennung

Das Basisplanbeispiel zeigt eine erfolgreiche Beziehungserkennung für saubere Synthea-Daten. In der Praxis sind die Daten selten sauber, was eine erfolgreiche Erkennung verhindert. Es gibt mehrere Techniken, die nützlich sein können, wenn die Daten nicht sauber sind.

In diesem Abschnitt des Tutorials wird die Beziehungserkennung behandelt, wenn das semantische Modell unsaubere Daten enthält.

  1. Bearbeiten Sie zunächst die ursprünglichen DataFrames, um „schmutzige“ Daten abzurufen, und zeigen Sie die Größe der geänderten Daten an.

    # 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))
    
    
  2. Zum Vergleich, Druckgrößen der ursprünglichen Tabellen:

    print(len(patients))
    print(len(providers))
    
  3. Suchen von Beziehungen zwischen den Tabellen mithilfe der find_relationships-Funktion von SemPy:

    find_relationships([patients_dirty, providers_dirty, encounters])
    

    Die Ausgabe des Codes zeigt, dass aufgrund der Fehler, die Sie zuvor beim Erstellen des „unsauberen“ semantischen Modells eingeführt haben, keine Beziehungen erkannt wurden.

Führen Sie eine Überprüfung aus

Die Überprüfung ist das beste Tool für die Problembehandlung von Fehlern bei der Beziehungserkennung, weil:

  • Sie eindeutig meldet, warum eine bestimmte Beziehung nicht den Regeln des Fremdschlüssels folgt und daher nicht erkannt werden kann.
  • Es wird schnell mit großen semantischen Modellen ausgeführt, da es sich nur auf die deklarierten Beziehungen konzentriert und keine Suche durchführt.

Die Überprüfung kann jeden DataFrame mit Spalten verwenden, die dem von find_relationships ähnelt. Im folgenden Code bezieht sich der suggested_relationships-DataFrame auf patients nicht auf patients_dirty, Sie können aber die DataFrames mit einem Wörterbuch aliasen:

dirty_tables = {
    "patients": patients_dirty,
    "providers" : providers_dirty,
    "encounters": encounters
}

errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors

Lockerung der Suchkriterien

In komplizierteren Szenarien können Sie versuchen, Ihre Suchkriterien zu lockern. Diese Methode erhöht die Möglichkeit falsch positiver Ergebnisse.

  1. Legen Sie include_many_to_many=True fest, und bewerten Sie, ob hilft:

    find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=1)
    

    Die Ergebnisse zeigen, dass die Beziehung von encounters zu patients erkannt wurde, aber es zwei Probleme gibt:

    • Die Beziehung gibt eine Richtung von patients zu encounters vor, die eine Umkehrung der erwarteten Beziehung ist. Dies liegt daran, dass zufällig alle patients von encounters abgedeckt werden (Coverage From ist 1,0), während encounters nur teilweise von patients abgedeckt sind (Coverage To = 0,85), da Patientenzeilen fehlen.
    • Es gibt eine versehentliche Übereinstimmung in einer Spalte mit niedriger Kardinalität GENDER, die nach Name und Wert in beiden Tabellen übereinstimmt, aber es sich nicht um eine "m:1"-Beziehung von Interesse handelt. Die niedrige Kardinalität wird durch Unique Count From- und Unique Count To-Spalten angegeben.
  2. Führen Sie den Vorgang find_relationships erneut aus, um nur nach "m:1"-Beziehungen zu suchen, aber mit einer niedrigeren coverage_threshold=0.5:

    find_relationships(dirty_tables, include_many_to_many=False, coverage_threshold=0.5)
    

    Das Ergebnis zeigt die richtige Richtung der Beziehungen von encounters zu providers. Die Beziehung von encounters zu patients wird jedoch nicht erkannt, da patients nicht eindeutig ist, sodass es sich nicht auf der "1"-Seite der "m:1"-Beziehung befinden kann.

  3. Lösen Sie sowohl include_many_to_many=True als auch coverage_threshold=0.5:

    find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)
    

    Jetzt sind beide gewünschte Beziehungen sichtbar, aber es gibt viel mehr Rauschen:

    • Die Übereinstimmung mit niedriger Kardinalität auf GENDER ist vorhanden.
    • Eine höhere Kardinalitäts-Übereinstimmung von "m:m" auf ORGANIZATION wurde angezeigt, wodurch deutlich wird, dass die ORGANIZATION-Spalte wahrscheinlich für beide Tabellen denormalisiert ist.

Spaltennamen abgleichen

SemPy betrachtet standardmäßig nur Attribute, die eine Namensähnlichkeit aufweisen, und nutzt dabei die Tatsache, dass Datenbankdesigner in der Regel verwandte Spalten auf die gleiche Weise benennen. Dieses Verhalten trägt dazu bei, unechte Beziehungen zu vermeiden, die am häufigsten mit ganzzahligen Schlüsseln mit niedriger Kardinalität auftreten. Wenn z. B. 1,2,3,...,10-Produktkategorien und 1,2,3,...,10-Bestellstatuscodes vorhanden sind, werden sie häufig miteinander verwechselt, wenn nur Wertezuordnungen betrachtet werden, ohne Spaltennamen zu berücksichtigen. Unechte Beziehungen sollten mit GUID-ähnlichen Schlüsseln kein Problem sein.

SemPy betrachtet eine Ähnlichkeit zwischen Spaltennamen und Tabellennamen. Der Abgleich ist ungefähr und die Groß-/Kleinschreibung wird nicht beachtet. Es ignoriert die am häufigsten gefundenen „Decorator“-Teilzeichenfolgen wie „id“, „code“ „name“, „key“, „pk“, „fk“. Daher sind die häufigsten Übereinstimmungsfälle:

  • Ein Attribut namens „column“ in der Entität „foo“ stimmt mit einem Attribut namens „column“ (auch „COLUMN“ oder „Column“) in der Entität „bar“ überein.
  • Ein Attribut namens „column“ in der Entität „foo“ stimmt mit einem Attribut namens „column_id“ in „bar“ überein.
  • Ein Attribut namens „bar“ in der Entität „foo“ stimmt mit einem Attribut namens „code“ in „bar“ überein.

Durch den ersten Abgleich von Spaltennamen wird die Erkennung schneller ausgeführt.

  1. Gleichen Sie mit die Spaltennamen an:

    • Um zu verstehen, welche Spalten zur weiteren Auswertung ausgewählt werden, verwenden Sie die verbose=2-Option (verbose=1 führt nur die Entitäten auf, die verarbeitet werden).
    • Der name_similarity_threshold-Parameter bestimmt, wie Spalten verglichen werden. Der Schwellenwert von 1 gibt an, dass Sie nur eine Übereinstimmung von 100 % haben wollen.
    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
    

    Die Ausführung bei 100 % Ähnlichkeit lässt keine geringen Unterschiede zwischen Namen zu. In Ihrem Beispiel weisen die Tabellen eine Pluralform mit dem Suffix „s“ auf, was zu keiner exakten Übereinstimmung führt. Diese Situationen werden gut mit der Standardeinstellung name_similarity_threshold=0.8 behandelt.

  2. Führen Sie mit der Standardeinstellung name_similarity_threshold=0.8 erneut aus:

    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0.8);
    

    Beachten Sie, dass die ID für Pluralformen patients jetzt mit der Singularform patient verglichen wird, ohne zu viele andere unechte Vergleiche zur Ausführungszeit hinzuzufügen.

  3. Führen Sie mit der Standardeinstellung name_similarity_threshold=0 erneut aus:

    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0);
    

    Der Wechsel von name_similarity_threshold zu 0 ist das andere Extrem, und es zeigt an, dass Sie alle Spalten vergleichen möchten. Dies ist selten notwendig und führt zu erhöhter Ausführungszeit und unechten Übereinstimmungen, die überprüft werden müssen. Beobachten Sie die Anzahl der Vergleiche in der ausführlichen Ausgabe.

Zusammenfassung der Tipps zur Problembehandlung

  1. Beginnen Sie mit der genauen Übereinstimmung für "m:1"-Beziehungen (d. h. den Standardwerten include_many_to_many=False und coverage_threshold=1.0). Das ist das zu empfehlende Vorgehen.
  2. Verwenden Sie einen schmalen Fokus auf kleineren Teilmengen von Tabellen.
  3. Verwenden Sie die Überprüfung, um Probleme mit der Datenqualität zu erkennen.
  4. Verwenden Sie verbose=2, wenn Sie verstehen möchten, welche Spalten für die Beziehung berücksichtigt werden. Dies kann zu einer großen Ausgabemenge führen.
  5. Beachten Sie Kompromisse und ihre Folgen bei Suchargumenten. include_many_to_many=True und coverage_threshold<1.0 können zu unechten Beziehungen führen, die schwieriger zu analysieren sind und gefiltert werden müssen.

Erkennen von Beziehungen in vollständigen Synthea-Datasets

Das einfache Basisplanbeispiel war ein praktisches Lern- und Problembehandlungstool. In der Praxis können Sie mit einem semantischen Modell wie dem vollständigen Synthea-Dataset beginnen, das viel mehr Tabellen enthält. Erkunden Sie das vollständige Synthea-Dataset wie folgt.

  1. Lesen aller Dateien aus dem synthea/csv-Verzeichnis:

    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'),
    }
    
  2. Suchen der Beziehungen zwischen den Tabellen mithilfe der find_relationships-Funktion von SemPy:

    suggested_relationships = find_relationships(all_tables)
    suggested_relationships
    
  3. Visualisieren der Beziehungen:

    plot_relationship_metadata(suggested_relationships)
    

    Screenshot der Beziehungen zwischen Tabellen.

  4. Zählen Sie, wie viele neue "m:m"-Beziehungen ermittelt include_many_to_many=True werden. Diese Beziehungen sind zusätzlich zu den zuvor gezeigten "m:1"-Beziehungen. Sie müssen daher nach multiplicity filtern:

    suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) 
    suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
    
  5. Sie können die Beziehungsdaten nach verschiedenen Spalten sortieren, um ein tieferes Verständnis ihrer Art zu erhalten. Sie können z. B. die Ausgabe nach Row Count From und Row Count To sortieren, um die größten Tabellen zu identifizieren.

    suggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)
    

    In einem anderen semantischen Modell wäre es vielleicht wichtig, sich auf die Anzahl von Nullen Null Count From oder Coverage To zu konzentrieren.

    Diese Analyse kann Ihnen helfen zu verstehen, ob eine der Beziehungen ungültig sein könnte, und ob Sie sie aus der Liste der Kandidaten entfernen müssen.

Sehen Sie sich weitere Tutorials zu Semantic Link und SemPy an: