教學課程:使用語意連結探索 Synthea 數據集中的關聯性
本教學課程說明如何使用語意連結來偵測公用 Synthea 數據集中的關聯性。
當您使用新數據或在沒有現有數據模型的情況下運作時,自動探索關聯性會很有説明。 此關聯性偵測可協助您:
- 瞭解高階的模型
- 在探勘數據分析期間取得更多深入解析,
- 驗證更新的數據或新的、傳入的數據,以及
- 清除數據。
即使事先知道關聯性,搜尋關聯性也有助於進一步了解數據模型或識別數據質量問題。
在本教學課程中,您會從簡單的基準範例開始,其中您只實驗三個數據表,讓兩者之間的連線很容易遵循。 然後,您會以較大的數據表集顯示更複雜的範例。
在本教學課程中,您會了解如何:
- 使用語意連結的 Python 連結庫 (SemPy) 元件,支援與 Power BI 整合,並協助自動化數據分析。 這些元件包括:
- FabricDataFrame - 使用其他語意信息增強的 pandas 類似結構。
- 將語意模型從 Fabric 工作區提取至筆記本的函式。
- 自動化語意模型中關聯性探索和視覺效果的函式。
- 針對具有多個數據表和相互相關性的語意模型關聯性探索程序進行疑難解答。
必要條件
取得 Microsoft Fabric 訂用帳戶。 或者,註冊免費的 Microsoft Fabric 試用版。
登入 Microsoft Fabric。
使用首頁左側的體驗切換器,切換至 Synapse 資料科學 體驗。
- 從左側瀏覽窗格中選取 [工作區 ],以尋找並選取您的工作區。 此工作區會變成您目前的工作區。
在筆記本中跟著
relationships_detection_tutorial.ipynb 筆記本會伴隨本教學課程。
若要開啟本教學課程隨附的筆記本,請遵循準備系統以進行數據科學教學課程中的指示,將筆記本匯入您的工作區。
如果您想要複製並貼上此頁面中的程式碼,您可以 建立新的筆記本。
開始執行程序代碼之前,請務必將 Lakehouse 附加至筆記本 。
設定筆記本
在本節中,您會使用必要的模組和數據來設定筆記本環境。
使用
%pip
筆記本內的內嵌安裝功能從 PyPI 安裝SemPy
:%pip install semantic-link
執行稍後需要的必要 SemPy 模組匯入:
import pandas as pd from sempy.samples import download_synthea from sempy.relationships import ( find_relationships, list_relationship_violations, plot_relationship_metadata )
匯入 pandas 以強制執行可協助輸出格式設定的組態選項:
import pandas as pd pd.set_option('display.max_colwidth', None)
提取範例數據。 在本教學課程中,您會使用 綜合醫療記錄的 Synthea 數據集(為了簡單起見,小版):
download_synthea(which='small')
偵測 Synthea 數據表子集的關聯性
從較大的集合中選取三個數據表:
patients
指定病患資訊encounters
指定有醫療接觸的患者(例如醫療預約、程式)providers
指定哪些醫療提供者參加了病人
數據表
encounters
會解析 和providers
之間的patients
多對多關聯性,可描述為關聯實體:patients = pd.read_csv('synthea/csv/patients.csv') providers = pd.read_csv('synthea/csv/providers.csv') encounters = pd.read_csv('synthea/csv/encounters.csv')
使用 SemPy 函
find_relationships
式尋找資料表之間的關聯性:suggested_relationships = find_relationships([patients, providers, encounters]) suggested_relationships
使用 SemPy 的
plot_relationship_metadata
函式,將 DataFrame 關聯性可視化為圖形。plot_relationship_metadata(suggested_relationships)
函式會配置從左側到右側的關聯性階層,其對應至輸出中的 “from” 和 “to” 數據表。 換句話說,左側的獨立「from」數據表會使用其外鍵指向右側的「對」相依性數據表。 每個實體方塊都會顯示參與關聯性之「從」或「到」端的數據行。
根據預設,關聯性會產生為 「m:1」 (而不是 “1:m”) 或 “1:1”。 「1:1」關聯性可以產生一或兩種方式,取決於對應值與所有值的比例是否只超過
coverage_threshold
一或兩個方向。 稍後在本教學課程中,您會討論 「m:m」關聯性較不頻繁的情況。
針對關聯性偵測問題進行疑難解答
基準範例會顯示全新 Synthea 數據上成功的關聯性偵測。 在實務上,數據很少清除,因此無法成功偵測。 當數據未清除時,有數種技術很有用。
本教學課程的本節說明語意模型包含臟數據時的關聯性偵測。
首先,操作原始 DataFrame 以取得「骯髒」的數據,並列印臟數據的大小。
# 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))
為了進行比較,原始數據表的列印大小:
print(len(patients)) print(len(providers))
使用 SemPy 函
find_relationships
式尋找資料表之間的關聯性:find_relationships([patients_dirty, providers_dirty, encounters])
程式代碼的輸出顯示,由於您稍早引進來建立「骯髒」語意模型的錯誤,因此沒有偵測到關聯性。
使用驗證
驗證是針對關聯性偵測失敗進行疑難解答的最佳工具,因為:
- 它清楚地報告為什麼特定關聯性未遵循外鍵規則,因此無法偵測到。
- 它會使用大型語意模型快速執行,因為它只著重於宣告的關聯性,而且不會執行搜尋。
驗證可以使用任何 DataFrame 與 所 find_relationships
產生數據行類似的數據行。 在下列程式代碼中 suggested_relationships
,DataFrame 會參考 patients
而不是 patients_dirty
,但您可以使用字典將 DataFrame 別名:
dirty_tables = {
"patients": patients_dirty,
"providers" : providers_dirty,
"encounters": encounters
}
errors = list_relationship_violations(dirty_tables, suggested_relationships)
errors
鬆散搜尋準則
在更模糊的案例中,您可以嘗試放寬搜尋準則。 這個方法會增加誤判的可能性。
設定
include_many_to_many=True
並評估它是否有説明:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=1)
結果顯示偵測到 的
patients
關聯性encounters
,但有兩個問題:- 關聯性表示從
patients
到encounters
的方向,這是預期關聯性的反函數。 這是因為所有patients
碰巧都由 (Coverage From
是 1.0) 覆蓋encounters
,而encounters
只是部分覆蓋patients
(Coverage To
= 0.85),因為患者數據列遺失。 - 低基數
GENDER
數據行發生意外比對,這兩個數據表中的名稱和值都會比對,但這不是感興趣的 「m:1」 關聯性。 低基數是由Unique Count From
和Unique Count To
數據行表示。
- 關聯性表示從
請重新執行
find_relationships
以只尋找 「m:1」 關聯性,但具有較低的coverage_threshold=0.5
:find_relationships(dirty_tables, include_many_to_many=False, coverage_threshold=0.5)
結果會顯示從
encounters
到providers
的正確關聯性方向。 不過,不會偵測到從encounters
到patients
的關聯性,因為 不是因為patients
不唯一的,因此不能位於 「m:1」 關聯性的 「One」 端。include_many_to_many=True
鬆散和coverage_threshold=0.5
:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)
現在兩個感興趣的關聯性都可見,但有更多的噪音:
- 上的
GENDER
低基數比對存在。 - 出現
ORGANIZATION
較高的基數 「m:m」 比對,因此很明顯ORGANIZATION
,這很可能是兩個數據表的數據行反正規化。
- 上的
比對數據行名稱
根據預設,SemPy 會視為只比對顯示名稱相似度的屬性,並利用資料庫設計工具通常以相同方式命名相關數據行的事實。 此行為有助於避免經常發生低基數整數索引鍵的假交關聯性。 例如,如果有 1,2,3,...,10
產品類別和 1,2,3,...,10
訂單狀態代碼,當只查看值對應而不考慮數據行名稱時,它們會彼此混淆。 假象關聯性不應該是類似 GUID 的索引鍵的問題。
SemPy 會查看資料行名稱和數據表名稱之間的相似度。 比對是近似且不區分大小寫。 它會忽略最常遇到的 「decorator」 子字串,例如 「id」、“code”、“name”、“key”、“pk”、“fk”。 因此,最常見的比對案例如下:
- 實體 'foo' 中稱為 'column' 的屬性會比對實體 'bar' 中稱為 'column' 的屬性(也稱為 'COLUMN' 或 'Column')。
- 實體 'foo' 中名為 'column' 的屬性與 'bar' 中稱為 'column_id' 的屬性相符。
- 實體 'foo' 中名為 'bar' 的屬性與 'bar' 中稱為 'code' 的屬性相符。
藉由先比對數據行名稱,偵測會更快執行。
符合資料列名稱:
- 若要瞭解要進一步評估哪些數據行,請使用
verbose=2
選項 (verbose=1
僅列出正在處理的實體)。 - 參數
name_similarity_threshold
會決定數據行的比較方式。 閾值 1 表示您只對 100% 相符感興趣。
find_relationships(dirty_tables, verbose=2, name_similarity_threshold=1.0);
以 100% 相似度執行無法解釋名稱之間的小差異。 在您的範例中,數據表具有具有 “s” 後綴的複數形式,這不會完全相符。 這是使用預設
name_similarity_threshold=0.8
的妥善處理。- 若要瞭解要進一步評估哪些數據行,請使用
使用預設值
name_similarity_threshold=0.8
重新執行 :find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0.8);
請注意,複數格式
patients
的標識符現在會與單數patient
比較,而不會將太多其他假想比較新增至運行時間。使用預設值
name_similarity_threshold=0
重新執行 :find_relationships(dirty_tables, verbose=2, name_similarity_threshold=0);
變更
name_similarity_threshold
為 0 是另一個極端值,表示您想要比較所有數據行。 這很少必要,而且會導致運行時間增加,以及需要檢閱的虛假相符專案。 觀察詳細信息輸出中的比較數目。
疑難解答秘訣摘要
- 從 「m:1」 關聯性完全相符開始 (也就是預設值
include_many_to_many=False
和coverage_threshold=1.0
)。 這通常是您想要的。 - 對較小的數據表子集使用窄焦點。
- 使用驗證來偵測數據質量問題。
- 如果您要瞭解哪些資料列被視爲關聯性, 請使用
verbose=2
。 這可能會導致大量的輸出。 - 請注意搜尋自變數的取捨。
include_many_to_many=True
和coverage_threshold<1.0
可能會產生可能更難分析且需要篩選的假關係。
偵測完整 Synthea 數據集上的關聯性
簡單的基準範例是一個方便的學習和疑難解答工具。 實際上,您可以從語意模型開始,例如完整的 Synthea 數據集,其中包含更多數據表。 探索完整的 合成器 數據集,如下所示。
從 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'), }
使用 SemPy 函
find_relationships
式尋找資料表之間的關聯性:suggested_relationships = find_relationships(all_tables) suggested_relationships
可視化關聯性:
plot_relationship_metadata(suggested_relationships)
計算使用 探索
include_many_to_many=True
到多少新的 「m:m」 關聯性。 這些關聯性除了先前顯示的 「m:1」 關聯性之外;因此,您必須篩選multiplicity
:suggested_relationships = find_relationships(all_tables, coverage_threshold=1.0, include_many_to_many=True) suggested_relationships[suggested_relationships['Multiplicity']=='m:m']
您可以依各種數據行排序關聯性數據,以深入瞭解其本質。 例如,您可以選擇依和
Row Count To
排序輸出Row Count From
,以協助識別最大的數據表。suggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)
在不同的語意模型中,也許請務必將焦點放在 Null
Null Count From
數目或Coverage To
。此分析可協助您瞭解是否有任何關聯性可能無效,而且如果您需要從候選專案清單中移除關聯性。
相關內容
查看語意連結 /SemPy 的其他教學課程:
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應