หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
บทช่วยสอนนี้แสดงวิธีการตรวจหาความสัมพันธ์ใน สาธารณะชุดข้อมูล Synthea โดยใช้ลิงก์ความหมาย
เมื่อคุณกําลังทํางานกับข้อมูลใหม่หรือทํางานโดยไม่มีแบบจําลองข้อมูลที่มีอยู่ จะเป็นประโยชน์ในการค้นหาความสัมพันธ์โดยอัตโนมัติ การตรวจหาความสัมพันธ์นี้สามารถช่วยให้คุณ:
- ทําความเข้าใจกับแบบจําลองในระดับสูง
- รับข้อมูลเชิงลึกเพิ่มเติมในระหว่างการวิเคราะห์ข้อมูลการสํารวจ
- ตรวจสอบข้อมูลที่อัปเดตแล้วหรือข้อมูลใหม่ ข้อมูลขาเข้า และ
- ทําความสะอาดข้อมูล
แม้ว่าความสัมพันธ์เป็นที่รู้จักล่วงหน้า การค้นหาความสัมพันธ์สามารถช่วยในการทําความเข้าใจเกี่ยวกับแบบจําลองข้อมูลหรือการระบุปัญหาคุณภาพของข้อมูลได้ดียิ่งขึ้น
ในบทช่วยสอนนี้ คุณเริ่มต้นด้วยตัวอย่างพื้นฐานอย่างง่ายที่คุณทดลองกับเพียงสามตารางเพื่อให้การเชื่อมต่อระหว่างตารางเป็นเรื่องง่าย จากนั้นคุณแสดงตัวอย่างที่ซับซ้อนมากขึ้นด้วยชุดตารางที่ใหญ่กว่า
ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธีการ:
- ใช้คอมโพเนนต์ของไลบรารี Python ของลิงก์ความหมาย (SemPy) ที่สนับสนุนการผสานรวมกับ Power BI และช่วยในการวิเคราะห์ข้อมูลโดยอัตโนมัติ คอมโพเนนต์เหล่านี้ประกอบด้วย:
- FabricDataFrame - โครงสร้างที่คล้ายกับ pandas เพิ่มขึ้นด้วยข้อมูลความหมายเพิ่มเติม
- ฟังก์ชันสําหรับการดึงแบบจําลองความหมายจากพื้นที่ทํางาน Fabric ลงในสมุดบันทึกของคุณ
- ฟังก์ชันที่ทําให้การค้นพบและการแสดงภาพของความสัมพันธ์ในแบบจําลองความหมายของคุณเป็นแบบอัตโนมัติ
- แก้ไขปัญหากระบวนการของการค้นพบความสัมพันธ์สําหรับแบบจําลองความหมายที่มีหลายตารางและการขึ้นต่อกัน
ข้อกําหนดเบื้องต้น
รับ การสมัครใช้งาน Microsoft Fabric หรือลงทะเบียนสําหรับ Microsoft Fabric รุ่นทดลองใช้ฟรี
ลงชื่อเข้าใช้ Microsoft Fabric
ใช้ตัวสลับประสบการณ์การใช้งานที่ด้านล่างซ้ายของหน้าหลักของคุณเพื่อเปลี่ยนเป็น Fabric
- เลือก พื้นที่ทํางาน จากบานหน้าต่างนําทางด้านซ้ายเพื่อค้นหาและเลือกพื้นที่ทํางานของคุณ พื้นที่ทํางานนี้จะกลายเป็นพื้นที่ทํางานปัจจุบันของคุณ
ติดตามในสมุดบันทึก
relationships_detection_tutorial.ipynb สมุดบันทึกมาพร้อมกับบทช่วยสอนนี้
เมื่อต้องการเปิดสมุดบันทึกที่มาพร้อมกับบทช่วยสอนนี้ ให้ทําตามคําแนะนําใน เตรียมระบบของคุณสําหรับบทช่วยสอนวิทยาศาสตร์ข้อมูล การนําเข้าสมุดบันทึกไปยังพื้นที่ทํางานของคุณ
ถ้าคุณต้องการคัดลอกและวางโค้ดจากหน้านี้ สร้างสมุดบันทึกใหม่
ตรวจสอบให้แน่ใจว่า แนบ lakehouse เข้ากับ สมุดบันทึกก่อนที่คุณจะเริ่มเรียกใช้โค้ด
ตั้งค่าสมุดบันทึก
ในส่วนนี้ คุณตั้งค่าสภาพแวดล้อมของสมุดบันทึกด้วยโมดูลและข้อมูลที่จําเป็น
ติดตั้ง
SemPyจาก PyPI โดยใช้ความสามารถในการติดตั้ง%pipในบรรทัดภายในสมุดบันทึก:%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แก้ไขความสัมพันธ์แบบกลุ่มต่อกลุ่มระหว่างpatientsกับprovidersและสามารถอธิบายได้ว่าเป็นเอนทิตี้ที่เกี่ยวข้อง :patients = pd.read_csv('synthea/csv/patients.csv') providers = pd.read_csv('synthea/csv/providers.csv') encounters = pd.read_csv('synthea/csv/encounters.csv')-
ค้นหาความสัมพันธ์ระหว่างตารางโดยใช้ฟังก์ชัน
find_relationshipsของ SemPy:suggested_relationships = find_relationships([patients, providers, encounters]) suggested_relationshipsแสดงภาพความสัมพันธ์ DataFrame เป็นกราฟ โดยใช้ฟังก์ชัน
plot_relationship_metadataของ SemPyplot_relationship_metadata(suggested_relationships)ฟังก์ชันจะวางลําดับชั้นความสัมพันธ์จากด้านซ้ายมือทางด้านขวาซึ่งสอดคล้องกับตาราง "จาก" และ "ไปยัง" ในผลลัพธ์ กล่าวอีกนัยหนึ่ง ตารางอิสระ "จาก" ทางด้านซ้ายมือใช้คีย์นอกของตารางเพื่อชี้ไปยังตารางที่ขึ้นต่อกัน "ไปยัง" ทางด้านขวา แต่ละกล่องเอนทิตีแสดงคอลัมน์ที่เข้าร่วมในด้าน "จาก" หรือ "ไปยัง" ของความสัมพันธ์
ตามค่าเริ่มต้น ความสัมพันธ์จะถูกสร้างขึ้นเป็น "m:1" (ไม่ใช่เป็น "1:m") หรือ "1:1" ความสัมพันธ์ "1:1" สามารถสร้างได้หนึ่งหรือทั้งสองวิธี ขึ้นอยู่กับว่าอัตราส่วนของค่าที่แมปกับค่าทั้งหมดเกิน
coverage_thresholdในทิศทางเดียวหรือทั้งสองทิศทาง ต่อมาในบทช่วยสอนนี้ คุณจะครอบคลุมกรณีที่พบได้บ่อยน้อยกว่าของความสัมพันธ์ "m:m"
แก้ไขปัญหาการตรวจหาความสัมพันธ์
ตัวอย่างพื้นฐานแสดงการตรวจจับความสัมพันธ์ที่ประสบความสําเร็จ ล้างข้อมูล Synthea ในทางปฏิบัติ ข้อมูลไม่สะอาดซึ่งป้องกันการตรวจหาที่สําเร็จ มีหลายเทคนิคที่จะเป็นประโยชน์เมื่อข้อมูลไม่สะอาด
ส่วนนี้ของบทช่วยสอนนี้จะกล่าวถึงการตรวจหาความสัมพันธ์เมื่อแบบจําลองความหมายประกอบด้วยข้อมูลสกปรก
เริ่มต้นโดยการจัดการ DataFrames ต้นฉบับเพื่อให้ได้ข้อมูล "สกปรก" และพิมพ์ขนาดของข้อมูลสกปรก
# 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))ค้นหาความสัมพันธ์ระหว่างตารางโดยใช้ฟังก์ชัน
find_relationshipsของ SemPy:find_relationships([patients_dirty, providers_dirty, encounters])ผลลัพธ์ของโค้ดแสดงว่าไม่มีการตรวจพบความสัมพันธ์เนื่องจากข้อผิดพลาดที่คุณแนะนําก่อนหน้านี้เพื่อสร้างแบบจําลองเชิงความหมาย "สกปรก"
ใช้การตรวจสอบความถูกต้อง
การตรวจสอบความถูกต้องเป็นเครื่องมือที่ดีที่สุดสําหรับการแก้ไขปัญหาความล้มเหลวในการตรวจหาความสัมพันธ์เนื่องจาก:
- ซึ่งจะรายงานอย่างชัดเจนว่าทําไมความสัมพันธ์เฉพาะไม่เป็นไปตามกฎของคีย์นอก ดังนั้นจึงไม่สามารถตรวจพบได้
- ซึ่งทํางานได้อย่างรวดเร็วด้วยแบบจําลองความหมายขนาดใหญ่เนื่องจากจะมุ่งเน้นเฉพาะความสัมพันธ์ที่ประกาศและไม่ทําการค้นหา
การตรวจสอบความถูกต้องสามารถใช้ DataFrame ใด ๆ กับคอลัมน์ที่คล้ายกับคอลัมน์ที่สร้างขึ้นโดย find_relationships ในโค้ดต่อไปนี้ suggested_relationships DataFrame อ้างอิงถึง patients แทนที่จะเป็น patients_dirtyแต่คุณสามารถนามแฝง DataFrames กับพจนานุกรม:
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)ผลลัพธ์แสดงให้เห็นว่าความสัมพันธ์จาก
encountersกับpatientsตรวจพบ แต่มีปัญหาสองประการ:- ความสัมพันธ์แสดงทิศทางจาก
patientsไปยังencountersซึ่งเป็นค่าผกผันของความสัมพันธ์ที่คาดไว้ ทั้งนี้เนื่องจากpatientsทั้งหมดเกิดขึ้นโดยencounters(Coverage Fromคือ 1.0) ในขณะที่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"คลายทั้ง
include_many_to_many=Trueและcoverage_threshold=0.5:find_relationships(dirty_tables, include_many_to_many=True, coverage_threshold=0.5)ในตอนนี้ ความสัมพันธ์ทั้งสองที่น่าสนใจจะมองเห็นได้ แต่มีเสียงรบกวนมากกว่า:
- การจับคู่คาร์ดินาลลิตี้ต่ําบน
GENDERปรากฏอยู่ - คาร์ดินาลลิตี้ที่สูงขึ้น "m:m" ตรงกับ
ORGANIZATIONปรากฏขึ้น ทําให้เห็นได้ชัดว่าORGANIZATIONน่าจะเป็นคอลัมน์ที่ลดความซ้ําซ้อนในทั้งสองตาราง
- การจับคู่คาร์ดินาลลิตี้ต่ําบน
จับคู่ชื่อคอลัมน์
ตามค่าเริ่มต้น SemPy จะพิจารณาว่าเป็นรายการที่ตรงกันเฉพาะแอตทริบิวต์ที่แสดงความคล้ายคลึงกันของชื่อ โดยการใช้ประโยชน์จากข้อเท็จจริงที่ผู้ออกแบบฐานข้อมูลมักจะตั้งชื่อคอลัมน์ที่เกี่ยวข้องด้วยวิธีเดียวกัน พฤติกรรมนี้จะช่วยหลีกเลี่ยงความสัมพันธ์ที่น่าสงสาร ซึ่งเกิดขึ้นบ่อยที่สุดกับคีย์จํานวนเต็มของคาร์ดินาลลิตี้ต่ํา ตัวอย่างเช่น หากมี 1,2,3,...,10 หมวดหมู่ผลิตภัณฑ์และ 1,2,3,...,10 รหัสสถานะคําสั่งซื้อ พวกเขาจะสับสนเมื่อดูเฉพาะการแมปค่าโดยไม่ต้องใช้ชื่อคอลัมน์ในการพิจารณา ความสัมพันธ์ที่น่าแปลกใจไม่ควรมีปัญหากับคีย์ที่คล้ายกับ GUID
SemPy ดูที่ความคล้ายคลึงกันระหว่างชื่อคอลัมน์และชื่อตาราง การจับคู่จะเป็นการประมาณและไม่ตรงตามตัวพิมพ์ใหญ่-เล็ก จะละเว้นสตริงย่อยที่พบบ่อยที่สุดที่พบบ่อยที่สุด เช่น "id", "code", "name", "key", "pk", "fk" ผลที่ได้คือ กรณีการจับคู่ที่ใช้กันทั่วไปมากที่สุดคือ:
- แอตทริบิวต์ที่เรียกว่า 'คอลัมน์' ในเอนทิตี 'foo' ตรงกับแอตทริบิวต์ที่เรียกว่า 'คอลัมน์' (และ 'COLUMN' หรือ 'Column') ในเอนทิตี 'bar'
- แอตทริบิวต์ที่เรียกว่า 'คอลัมน์' ในเอนทิตี 'foo' ตรงกับแอตทริบิวต์ที่เรียกว่า 'column_id' ใน 'bar'
- แอตทริบิวต์ที่เรียกว่า 'bar' ในเอนทิตี 'foo' ตรงกับแอตทริบิวต์ที่เรียกว่า 'โค้ด' ใน 'bar'
การตรวจหาจะทํางานได้เร็วขึ้นโดยการจับคู่ชื่อคอลัมน์ก่อน
ตรงกับชื่อคอลัมน์:
- เมื่อต้องการทําความเข้าใจว่าคอลัมน์ใดที่ถูกเลือกสําหรับการประเมินผลเพิ่มเติม ให้ใช้ตัวเลือก
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);โปรดสังเกตว่า Id สําหรับฟอร์มพหูพจน์
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 ชุดข้อมูลดังนี้
อ่านไฟล์ทั้งหมดจากไดเรกทอรี 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'), }ค้นหาความสัมพันธ์ระหว่างตาราง โดยใช้ฟังก์ชัน
find_relationshipsของ SemPy:suggested_relationships = find_relationships(all_tables) suggested_relationshipsแสดงภาพความสัมพันธ์:
plot_relationship_metadata(suggested_relationships)นับจํานวนความสัมพันธ์ใหม่ "m:m" ที่จะถูกค้นพบด้วย
include_many_to_many=Trueความสัมพันธ์เหล่านี้นอกเหนือจากความสัมพันธ์ที่แสดงไว้ก่อนหน้านี้ที่แสดงไว้ก่อนหน้านี้เป็น "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 FromและRow Count Toซึ่งช่วยระบุตารางที่ใหญ่ที่สุดsuggested_relationships.sort_values(['Row Count From', 'Row Count To'], ascending=False)ในแบบจําลองความหมายอื่น อาจเป็นสิ่งสําคัญที่ต้องเน้นไปที่จํานวน null
Null Count FromหรือCoverage Toการวิเคราะห์นี้สามารถช่วยให้คุณเข้าใจว่าความสัมพันธ์ใด ๆ อาจไม่ถูกต้องและหากคุณต้องการนําออกจากรายชื่อผู้สมัคร
เนื้อหาที่เกี่ยวข้อง
ดูบทช่วยสอนอื่น ๆ สําหรับลิงก์ความหมาย / SemPy: