Sdílet prostřednictvím


Kurz: Zjišťování relací v datové sadě Synthea pomocí sémantického odkazu

Tento kurz ukazuje, jak pomocí sémantického odkazu rozpoznat relace ve veřejné datové sadě Synthea.

Když pracujete s novými daty nebo pracujete bez existujícího datového modelu, může být užitečné automaticky zjišťovat relace. Toto zjišťování relací vám může pomoct:

  • porozumět modelu na vysoké úrovni,
  • získání dalších přehledů při průzkumné analýze dat,
  • ověření aktualizovaných dat nebo nových, příchozích dat a
  • čištění dat

I když jsou relace známé předem, může vyhledávání relací pomoct lépe porozumět datovému modelu nebo identifikaci problémů s kvalitou dat.

V tomto kurzu začnete jednoduchým příkladem směrného plánu, ve kterém experimentujete pouze se třemi tabulkami, aby bylo snadné sledovat propojení mezi nimi. Pak zobrazíte složitější příklad s větší sadou tabulek.

V tomto kurzu se naučíte:

  • Používejte komponenty sémantické knihovny Pythonu (SemPy), které podporují integraci s Power BI a pomáhají automatizovat analýzu dat. Mezi tyto komponenty patří:
    • FabricDataFrame – struktura podobná knihovně pandas vylepšená o dodatečné sémantické informace.
    • Funkce pro načítání sémantických modelů z pracovního prostoru Fabric do poznámkového bloku
    • Funkce, které automatizují zjišťování a vizualizaci relací v sémantických modelech
  • Řešení potíží s procesem zjišťování relací pro sémantické modely s více tabulkami a vzájemnými závislostmi

Požadavky

  • V levém navigačním podokně vyberte Pracovní prostory a vyhledejte a vyberte pracovní prostor. Tento pracovní prostor se stane vaším aktuálním pracovním prostorem.

Sledujte v poznámkovém bloku

Tento kurz doprovází poznámkový blok relationships_detection_tutorial.ipynb.

Nastavení poznámkového bloku

V této části nastavíte prostředí poznámkového bloku s potřebnými moduly a daty.

  1. Nainstalujte SemPy z PyPI pomocí funkce in-line instalace %pip v notebooku:

    %pip install semantic-link
    
  2. Proveďte nezbytné importy modulů SemPy, které budete potřebovat později:

    import pandas as pd
    
    from sempy.samples import download_synthea
    from sempy.relationships import (
        find_relationships,
        list_relationship_violations,
        plot_relationship_metadata
    )
    
  3. Import knihovny pandas pro vynucování možnosti konfigurace, která pomáhá s formátováním výstupu:

    import pandas as pd
    pd.set_option('display.max_colwidth', None)
    
  4. Stáhněte si ukázková data. Pro účely tohoto kurzu použijete datovou sadu Synthea syntetických lékařských záznamů (pro jednoduchost malá verze):

    download_synthea(which='small')
    

Detekovat relace v malé podmnožině tabulek Synthea

  1. Vyberte tři tabulky z větší sady:

    • patients určuje informace o pacientech.
    • encounters určuje pacienty, kteří měli zdravotní setkání (například lékařské vyšetření, postup).
    • providers určuje, kteří poskytovatelé zdravotní péče věnovali pacientům péči

    Tabulka encounters řeší relaci M:N mezi patients a providers a lze ji popsat jako asociativní entitu:

    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. Pomocí find_relationships funkce SemPy můžete najít relace mezi tabulkami:

    suggested_relationships = find_relationships([patients, providers, encounters])
    suggested_relationships
    
  3. Vizualizujte datový rámec relací jako graf pomocí plot_relationship_metadata funkce SemPy.

    plot_relationship_metadata(suggested_relationships)
    

    Snímek obrazovky znázorňující relace mezi tabulkami v datové sadě

    Funkce stanoví hierarchii relací z levé strany na pravou stranu, která odpovídá tabulkám "from" a "to" ve výstupu. Jinými slovy, tabulky "od", které jsou nezávislé a umístěné na levé straně, používají své cizí klíče k nasměrování na jejich závislé tabulky "na" nacházející se na pravé straně. Každý rámeček entity zobrazuje sloupce, které se podílí na straně "from" nebo "to" vztahu.

    Ve výchozím nastavení se relace generují jako "m:1" (ne jako "1:m") nebo "1:1". Relace 1:1 lze vygenerovat jedním nebo oběma způsoby v závislosti na tom, jestli poměr mapovaných hodnot ke všem hodnotám překračuje coverage_threshold pouze jedním nebo oběma směry. Později v tomto kurzu se budeme zabývat méně častými případy relací m:m.

Řešení potíží s detekcí relací

Příklad směrného plánu ukazuje úspěšnou detekci relací při čistém Synthea dat. V praxi jsou data zřídka čistá, což brání úspěšné detekci. Existuje několik technik, které můžou být užitečné, když data nejsou čistá.

Tato část tohoto kurzu se zabývá detekcí vztahů, když sémantický model obsahuje špinavá data.

  1. Začněte tím, že manipulací s původními datovými rámci získáte "špinavá" data a vytisknete velikost zašpiněných dat.

    # 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. Pro porovnání tisk velikostí původních tabulek:

    print(len(patients))
    print(len(providers))
    
  3. Pomocí find_relationships funkce SemPy můžete najít relace mezi tabulkami:

    find_relationships([patients_dirty, providers_dirty, encounters])
    

    Výstup kódu ukazuje, že se nezjistily žádné relace kvůli chybám, které jste zavedli dříve, abyste vytvořili sémantický model "dirty".

Použijte ověřování

Ověření je nejlepší nástroj pro řešení potíží se selháními detekce vztahů, protože:

  • Hlásí jasně, proč konkrétní vztah nedodržuje pravidla cizího klíče, a proto nemůže být zjištěn.
  • Běží rychle u velkých sémantických modelů, protože se zaměřuje pouze na deklarované relace a neprovádí vyhledávání.

Ověření může použít libovolný datový rámec se sloupci podobnými datovému rámci vygenerovanému find_relationships. V následujícím kódu datový rámec suggested_relationships odkazuje na patients místo patients_dirty, ale datové rámce můžete aliasovat pomocí slovníku:

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

errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors

Zmírnit kritéria hledání

Ve složitějších scénářích můžete zkusit uvolnit kritéria hledání. Tato metoda zvyšuje možnost falešně pozitivních výsledků.

  1. Nastavte include_many_to_many=True a vyhodnoťte, jestli vám to pomůže:

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

    Výsledky ukazují, že byla zjištěna relace z encounters do patients, ale existují dva problémy:

    • Relace označuje směr od patients k encounters, což je inverzní k očekávané relaci. Důvodem je to, že všechny patients byly pokryty encounters (Coverage From je 1,0), zatímco encounters jsou pouze částečně pokryty patients (Coverage To = 0,85), protože v řádcích pacientů chybí údaje.
    • U sloupce s nízkou kardinalitou GENDER existuje náhodná shoda, která odpovídá názvu a hodnotě v obou tabulkách, ale nejedná se o relaci "m:1" zájmu. Nízká kardinalita je označena sloupci Unique Count From a Unique Count To.
  2. Spusťte znovu find_relationships a hledejte pouze relace m:1, ale s nižší hodnotou coverage_threshold=0.5:

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

    Výsledek ukazuje správný směr relací z encounters na providers. Relace z encounters na patients se ale nezjistí, protože patients není jedinečná, takže nemůže být na straně 1 relace m:1.

  3. Uvolněte include_many_to_many=True i coverage_threshold=0.5:

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

    Teď jsou obě relace zájmu viditelné, ale existuje mnohem více šumu:

    • Na GENDER existuje shoda s nízkou kardinalitou.
    • Objevila se vyšší kardinalita "m:m" na ORGANIZATION, což jasně naznačuje, že ORGANIZATION je pravděpodobně sloupec denormalizovaný do obou tabulek.

Odpovídat názvům sloupců

SemPy ve výchozím nastavení považuje za odpovídající pouze atributy, které zobrazují podobnost s názvem, a využívá tak skutečnost, že návrháři databáze obvykle označují související sloupce stejným způsobem. Toto chování pomáhá vyhnout se nechutným relacím, ke kterým dochází nejčastěji u celočíselného klíče s nízkou kardinalitou. Pokud jsou například 1,2,3,...,10 kategorie produktů a stavový kód objednávky 1,2,3,...,10, budou se vzájemně zaměňovat, když se podíváte pouze na mapování hodnot bez zohlednění názvů sloupců. Falešné relace by neměly představovat problém s klíči podobnými GUID.

SemPy se podívá na podobnost mezi názvy sloupců a názvy tabulek. Porovnávání je přibližné a nerozlišuje malá a velká písmena. Ignoruje nejčastěji zjištěných podřetězi "dekorátor", jako je "id", "code", "name", "key", "pk", "fk". V důsledku toho jsou nejběžnější případy shody:

  • atribut s názvem 'column' v entitě 'foo' odpovídá atributu s názvem 'column' (také 'COLUMN' nebo 'Column') v entitě 'bar'.
  • atribut s názvem 'column' v entitě 'foo' odpovídá atributu s názvem 'column_id' v entitě 'bar'.
  • atribut nazvaný "bar" v entitě "foo" odpovídá atributu nazvanému "code" v "bar".

Při párování názvů sloupců se detekce spustí rychleji.

  1. Porovná názvy sloupců:

    • Pokud chcete zjistit, které sloupce jsou vybrány k dalšímu vyhodnocení, použijte možnost verbose=2 (verbose=1 uvádí pouze zpracovávané entity).
    • Parametr name_similarity_threshold určuje, jak se sloupce porovnávají. Prahová hodnota 1 značí, že se zajímáte pouze o 100% shody.
    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
    

    Při použití hodnoty 100% podobnosti nezohledňuje malé rozdíly mezi názvy. V příkladu mají tabulky tvar množného čísla s příponou "s", což vede k žádné přesné shodě. To je zpracováno dobře s výchozími name_similarity_threshold=0.8.

  2. Spusťte znovu s výchozím nastavením name_similarity_threshold=0.8:

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

    Všimněte si, že ID pro množný tvar patients je nyní porovnána s jednotným tvarem patient, aniž by se přidalo příliš mnoho dalších zbytečných porovnání k době provádění.

  3. Spusťte znovu výchozí name_similarity_threshold=0:

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

    Změna name_similarity_threshold na 0 je druhá extrémní hodnota a znamená to, že chcete porovnat všechny sloupce. To je zřídka nutné a vede ke zvýšení doby provádění a nechtěných shod, které je potřeba zkontrolovat. Podívejte se na počet porovnání v podrobném výstupu.

Shrnutí tipů pro řešení potíží

  1. Začněte od přesné shody pro relace "m:1" (to znamená výchozí include_many_to_many=False a coverage_threshold=1.0). To je obvykle to, co chcete.
  2. Použijte úzký fokus na menší podmnožinu tabulek.
  3. K detekci problémů s kvalitou dat použijte ověřování.
  4. Pokud chcete pochopit, které sloupce jsou zvažovány pro vztah, použijte verbose=2. Výsledkem může být velký objem výstupu.
  5. Mějte na paměti kompromisy u parametrů vyhledávání. include_many_to_many=True a coverage_threshold<1.0 můžou vést k nechutným relacím, které mohou být obtížně analyzovat a budou muset být filtrované.

Zjištění vztahů na úplné datové sadě Synthea

Jednoduchý základní příklad sloužil jako užitečný nástroj pro výuku a řešení potíží. V praxi můžete začít od sémantického modelu, jako je úplná datová sada Synthea, která obsahuje mnohem více tabulek. Prozkoumejte úplnou datovou sadu synthea následujícím způsobem.

  1. Přečtěte všechny soubory z adresáře 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'),
    }
    
  2. Pomocí find_relationships funkce SemPy najděte relace mezi tabulkami:

    suggested_relationships = find_relationships(all_tables)
    suggested_relationships
    
  3. Vizualizace relací:

    plot_relationship_metadata(suggested_relationships)
    

    Snímek obrazovky s relacemi mezi tabulkami

  4. Spočítejte, kolik nových relací m:m se zjistí pomocí include_many_to_many=True. Tyto relace jsou navíc k dříve zobrazeným relacím m:1; proto musíte filtrovat podle multiplicity:

    suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) 
    suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
    
  5. Data relací můžete řadit podle různých sloupců, abyste získali hlubší přehled o jejich povaze. Můžete se například rozhodnout uspořádat výstup podle Row Count From a Row Count To, které pomáhají identifikovat největší tabulky.

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

    V jiném sémantickém modelu by možná bylo důležité zaměřit se na počet hodnot null Null Count From nebo Coverage To.

    Tato analýza vám pomůže pochopit, jestli některá z relací není platná, a pokud je potřebujete odebrat ze seznamu kandidátů.

Podívejte se na další kurzy pro sémantický odkaz / SemPy: