Bagikan melalui


Tutorial: Menemukan hubungan dalam himpunan data Synthea, menggunakan tautan semantik

Tutorial ini menggambarkan cara mendeteksi hubungan di publik Synthea himpunan data, menggunakan tautan semantik.

Saat Anda bekerja dengan data baru atau bekerja tanpa model data yang ada, akan sangat membantu untuk menemukan hubungan secara otomatis. Deteksi hubungan ini dapat membantu Anda untuk:

  • memahami model pada tingkat tinggi,
  • mendapatkan lebih banyak wawasan selama analisis data eksploratif,
  • memvalidasi data yang diperbarui atau data baru yang masuk, dan
  • bersihkan data.

Bahkan jika hubungan diketahui sebelumnya, pencarian hubungan dapat membantu pemahaman yang lebih baik tentang model data atau identifikasi masalah kualitas data.

Dalam tutorial ini, Anda memulai dengan contoh garis besar sederhana di mana Anda hanya bereksperimen dengan tiga tabel sehingga koneksi di antara mereka mudah diikuti. Kemudian, Anda menampilkan contoh yang lebih kompleks dengan kumpulan tabel yang lebih besar.

Dalam tutorial ini, Anda mempelajari cara:

  • Gunakan komponen pustaka Python tautan semantik (SemPy) yang mendukung integrasi dengan Power BI dan membantu mengotomatiskan analisis data. Komponen-komponen ini meliputi:
    • FabricDataFrame - struktur seperti panda yang ditingkatkan dengan informasi semantik tambahan.
    • Fungsi untuk menarik model semantik dari ruang kerja Fabric ke notebook Anda.
    • Fungsi yang mengotomatiskan penemuan dan visualisasi hubungan dalam model semantik Anda.
  • Mengatasi masalah dalam proses penemuan hubungan untuk model semantik yang melibatkan banyak tabel dan interdependensi.

Prasyarat

  • Dapatkan langganan Microsoft Fabric . Atau, daftar untuk uji coba Microsoft Fabric gratis.

  • Masuk ke Microsoft Fabric.

  • Gunakan pengalih pengalaman di sisi kiri bawah halaman beranda Anda untuk beralih ke Fabric.

    Cuplikan layar menu pengalih pengalaman, memperlihatkan tempat untuk memilih Ilmu Data.

  • Pilih Ruang Kerja dari panel navigasi kiri untuk menemukan dan memilih ruang kerja Anda. Ruang kerja ini menjadi ruang kerja Anda saat ini.

Ikuti langkah-langkah dalam buku catatan

Notebook relationships_detection_tutorial.ipynb menyertai tutorial ini.

Menyiapkan buku catatan

Di bagian ini, Anda menyiapkan lingkungan notebook dengan modul dan data yang diperlukan.

  1. Instal SemPy dari PyPI menggunakan fitur penginstalan sebaris %pip dalam notebook.

    %pip install semantic-link
    
  2. Lakukan impor modul SemPy yang diperlukan nanti:

    import pandas as pd
    
    from sempy.samples import download_synthea
    from sempy.relationships import (
        find_relationships,
        list_relationship_violations,
        plot_relationship_metadata
    )
    
  3. Impor pandas untuk menetapkan opsi konfigurasi yang membantu memformat keluaran:

    import pandas as pd
    pd.set_option('display.max_colwidth', None)
    
  4. Ambillah data sampel. Untuk tutorial ini, Anda menggunakan Synthea himpunan data catatan medis sintetis (versi kecil untuk kesederhanaan):

    download_synthea(which='small')
    

Mendeteksi hubungan pada subset kecil tabel Synthea

  1. Pilih tiga tabel dari set yang lebih besar:

    • patients menentukan informasi pasien
    • encounters menentukan pasien yang mengalami pertemuan medis (misalnya, janji temu medis, prosedur)
    • providers menentukan penyedia medis mana yang merawat pasien

    Tabel encounters menyelesaikan hubungan banyak ke banyak antara patients dan providers dan dapat dijelaskan sebagai entitas asosiatif :

    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. Temukan hubungan antara tabel menggunakan fungsi find_relationships SemPy:

    suggested_relationships = find_relationships([patients, providers, encounters])
    suggested_relationships
    
  3. Visualisasikan hubungan DataFrame sebagai grafik, menggunakan fungsi plot_relationship_metadata SemPy.

    plot_relationship_metadata(suggested_relationships)
    

    Cuplikan layar memperlihatkan hubungan antar tabel dalam himpunan data.

    Fungsi ini menjabarkan hierarki hubungan dari sisi kiri ke sisi kanan, yang sesuai dengan tabel "dari" dan "ke" dalam output. Dengan kata lain, tabel "dari" independen di sisi kiri menggunakan kunci asing mereka untuk menunjuk ke tabel dependensi "ke" mereka di sisi kanan. Setiap kotak entitas menampilkan kolom-kolom yang berpartisipasi dalam sisi "dari" atau "ke" dalam suatu relasi.

    Secara default, hubungan dihasilkan sebagai "m:1" (bukan sebagai "1:m") atau "1:1". Hubungan "1:1" dapat dihasilkan dalam satu arah atau kedua arah, tergantung pada apakah rasio nilai yang dipetakan dari semua nilai melebihi coverage_threshold hanya dalam satu atau kedua arah. Kemudian dalam tutorial ini, Anda akan membahas kasus hubungan "m:m" yang jarang terjadi.

Memecahkan masalah deteksi hubungan

Contoh garis besar menunjukkan deteksi hubungan yang berhasil pada data Synthea yang bersih. Dalam praktiknya, data jarang bersih, yang mencegah keberhasilan deteksi. Ada beberapa teknik yang dapat berguna ketika data tidak bersih.

Bagian tutorial ini membahas deteksi hubungan ketika model semantik berisi data kotor.

  1. Mulailah dengan memanipulasi DataFrames asli untuk mendapatkan data "kotor", dan cetak ukuran data kotor.

    # 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. Sebagai perbandingan, ukuran cetak tabel asli:

    print(len(patients))
    print(len(providers))
    
  3. Temukan hubungan antara tabel menggunakan fungsi find_relationships SemPy:

    find_relationships([patients_dirty, providers_dirty, encounters])
    

    Output kode menunjukkan bahwa tidak ada hubungan terdeteksi karena kesalahan yang Anda tambahkan sebelumnya untuk membuat model semantik yang kacau.

Gunakan validasi

Validasi adalah alat terbaik untuk memecahkan masalah kegagalan deteksi hubungan karena:

  • Ini melaporkan dengan jelas mengapa hubungan tertentu tidak mengikuti aturan Kunci Asing sehingga tidak dapat dideteksi.
  • Ini berjalan cepat dengan model semantik besar karena hanya berfokus pada hubungan yang dideklarasikan dan tidak melakukan pencarian.

Validasi dapat menggunakan DataFrame apa pun dengan kolom yang mirip dengan yang dihasilkan oleh find_relationships. Dalam kode berikut, suggested_relationships DataFrame mengacu pada patients daripada patients_dirty, tetapi Anda dapat alias DataFrame dengan kamus:

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

errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors

Melonggarkan kriteria pencarian

Dalam situasi yang lebih tidak jelas, Anda dapat mencoba melonggarkan kriteria pencarian Anda. Metode ini meningkatkan kemungkinan positif palsu.

  1. Atur include_many_to_many=True dan evaluasi jika membantu:

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

    Hasilnya menunjukkan bahwa hubungan dari encounters ke patients terdeteksi, tetapi ada dua masalah:

    • Hubungan menunjukkan arah dari patients ke encounters, yang merupakan inversi dari hubungan yang diharapkan. Ini karena semua patients ternyata dicakup oleh encounters (Coverage From adalah 1.0) sementara encounters hanya dicakup sebagian oleh patients (Coverage To = 0.85), karena terdapat baris pasien yang hilang.
    • Ada kecocokan yang tidak disengaja pada kolom GENDER kardinalitas rendah, yang kebetulan cocok dengan nama dan nilai di kedua tabel, tetapi itu bukan hubungan minat "m:1". Kardinalitas rendah ditunjukkan oleh kolom Unique Count From dan Unique Count To.
  2. Jalankan ulang find_relationships untuk mencari hubungan "m:1", tetapi dengan coverage_threshold=0.5yang lebih rendah :

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

    Hasilnya menunjukkan arah hubungan yang benar dari encounters ke providers. Namun, hubungan dari encounters ke patients tidak terdeteksi, karena patients tidak unik, sehingga tidak dapat berada di sisi "Satu" dari hubungan "m:1".

  3. Longgarkan include_many_to_many=True dan coverage_threshold=0.5:

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

    Sekarang kedua hubungan minat terlihat, tetapi ada lebih banyak kebisingan:

    • Ada kecocokan dengan kardinalitas rendah pada GENDER.
    • Kecocokan kardinalitas "m:m" yang lebih tinggi pada ORGANIZATION muncul, sehingga terlihat bahwa ORGANIZATION kemungkinan kolom didenormalisasi ke dalam kedua tabel.

Mencocokkan nama kolom

Secara default, SemPy menganggap sebagai kecocokan hanya atribut yang menunjukkan kesamaan nama, memanfaatkan fakta bahwa perancang database biasanya memberi nama kolom terkait dengan cara yang sama. Perilaku ini membantu menghindari hubungan yang salah, yang paling sering terjadi dengan kunci integer kardinalitas rendah. Misalnya, jika ada 1,2,3,...,10 kategori produk dan kode status pesanan 1,2,3,...,10, mereka akan bingung satu sama lain ketika hanya melihat pemetaan nilai tanpa memperhitungkan nama kolom. Hubungan semu seharusnya tidak menjadi masalah dengan kunci mirip GUID.

SemPy melihat kesamaan antara nama kolom dan nama tabel. Pencocokan adalah perkiraan dan tidak sensitif terhadap huruf besar/kecil. Ini mengabaikan substring "dekorator" yang paling sering ditemui seperti "id", "code", "name", "key", "pk", "fk". Akibatnya, kasus kecocokan yang paling umum adalah:

  • atribut yang disebut 'kolom' dalam entitas 'foo' cocok dengan atribut yang disebut 'kolom' (juga 'KOLOM' atau 'Kolom') di entitas 'bar'.
  • atribut yang disebut 'kolom' dalam entitas 'foo' cocok dengan atribut yang disebut 'column_id' di 'bar'.
  • atribut yang disebut 'bar' dalam entitas 'foo' cocok dengan atribut yang disebut 'code' di 'bar'.

Dengan mencocokkan nama kolom terlebih dahulu, deteksi berjalan lebih cepat.

  1. Sesuaikan nama kolom:

    • Untuk memahami kolom mana yang dipilih untuk evaluasi lebih lanjut, gunakan opsi verbose=2 (verbose=1 hanya mencantumkan entitas yang sedang diproses).
    • Parameter name_similarity_threshold menentukan bagaimana kolom dibandingkan. Ambang batas nilai 1 menunjukkan bahwa Anda hanya tertarik pada pencocokan 100% saja.
    find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
    

    Beroperasi pada 100% kesamaan gagal memperhitungkan perbedaan kecil antar nama. Dalam contoh Anda, tabel memiliki bentuk jamak dengan akhiran "s", yang tidak menghasilkan kecocokan yang tepat. Ini ditangani dengan baik dengan name_similarity_threshold=0.8default .

  2. Jalankan ulang dengan pengaturan default name_similarity_threshold=0.8

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

    Perhatikan bahwa ID untuk bentuk jamak patients sekarang dibandingkan dengan bentuk tunggal patient tanpa menambahkan terlalu banyak perbandingan yang tidak perlu terhadap waktu eksekusi.

  3. Jalankan ulang dengan default name_similarity_threshold=0.

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

    Mengubah name_similarity_threshold ke 0 adalah yang ekstrem lainnya, dan menunjukkan bahwa Anda ingin membandingkan semua kolom. Ini jarang diperlukan dan menghasilkan peningkatan waktu eksekusi dan kecocokan palsu yang perlu ditinjau. Amati jumlah perbandingan dalam output verbose.

Ringkasan tips pemecahan masalah

  1. Mulai dari kecocokan yang tepat untuk relasi "m:1" (yaitu, default include_many_to_many=False dan coverage_threshold=1.0). Ini biasanya yang Anda inginkan.
  2. Gunakan fokus sempit pada subset tabel yang lebih kecil.
  3. Gunakan validasi untuk mendeteksi masalah kualitas data.
  4. Gunakan verbose=2 jika Anda ingin memahami kolom mana yang dipertimbangkan untuk hubungan. Ini dapat menghasilkan sejumlah besar output.
  5. Waspadai kompromi dalam argumentasi pencarian. include_many_to_many=True dan coverage_threshold<1.0 dapat menghasilkan hubungan semu yang mungkin lebih sulit untuk dianalisis dan perlu disaring.

Mendeteksi hubungan pada himpunan data Synthea lengkap

Contoh garis besar sederhana adalah alat pembelajaran dan pemecahan masalah yang nyaman. Dalam praktiknya, Anda dapat memulai dari model semantik seperti himpunan data Synthea lengkap, yang memiliki lebih banyak tabel. Jelajahi himpunan data synthea lengkap.

  1. Baca semua file dari direktori 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. Temukan hubungan antara tabel, menggunakan fungsi find_relationships SemPy:

    suggested_relationships = find_relationships(all_tables)
    suggested_relationships
    
  3. Memvisualisasikan hubungan:

    plot_relationship_metadata(suggested_relationships)
    

    Cuplikan layar hubungan antar tabel.

  4. Hitung berapa banyak hubungan "m:m" baru yang akan ditemukan dengan include_many_to_many=True. Hubungan ini di samping hubungan "m:1" yang ditunjukkan sebelumnya; oleh karena itu, Anda perlu menyaring dengan multiplicity:

    suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) 
    suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
    
  5. Anda dapat mengurutkan data hubungan menurut berbagai kolom untuk mendapatkan pemahaman yang lebih mendalam tentang sifatnya. Misalnya, Anda dapat memilih untuk mengurutkan output berdasarkan Row Count From dan Row Count To, yang membantu mengidentifikasi tabel terbesar.

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

    Dalam model semantik yang berbeda, mungkin penting untuk fokus pada jumlah null Null Count From atau Coverage To.

    Analisis ini dapat membantu Anda memahami apakah salah satu hubungan bisa tidak valid, dan jika Anda perlu menghapusnya dari daftar kandidat.

Lihat tutorial lain untuk tautan semantik / SemPy: