สร้างกราฟความรู้ชีวการแพทย์ด้วย NLP

โหนดต้นทาง: 1401511

ฉันได้สาธิตวิธีการแล้ว สร้างกราฟความรู้จากหน้า Wikipedia. อย่างไรก็ตาม เนื่องจากโพสต์ได้รับความสนใจเป็นอย่างมาก ฉันจึงตัดสินใจสำรวจโดเมนอื่นๆ ที่ใช้เทคนิค NLP เพื่อสร้างกราฟความรู้ที่เหมาะสม ในความเห็นของฉัน สาขาวิชาชีวการแพทย์เป็นตัวอย่างสำคัญที่แสดงข้อมูลเป็นกราฟที่สมเหตุสมผล เนื่องจากคุณมักจะวิเคราะห์ปฏิสัมพันธ์และความสัมพันธ์ระหว่างยีน โรค ยา โปรตีน และอื่นๆ

กราฟย่อยตัวอย่างที่แสดงความสัมพันธ์ของกรดแอสคอร์บิกกับแนวคิดชีวการแพทย์อื่นๆ ภาพโดยผู้เขียน

ในการแสดงภาพด้านบนนี้ เรามีกรดแอสคอร์บิก หรือที่เรียกว่าวิตามินซี และมีความสัมพันธ์กับแนวคิดอื่นๆ ตัวอย่างเช่น แสดงให้เห็นว่าวิตามินซีสามารถใช้รักษาโรคกระเพาะเรื้อรังได้

ตอนนี้ คุณสามารถให้ทีมผู้เชี่ยวชาญด้านโดเมนทำแผนที่ความเชื่อมโยงระหว่างยา โรค และแนวคิดทางชีวการแพทย์อื่นๆ สำหรับคุณ แต่น่าเสียดายที่มีพวกเราไม่มากที่สามารถจ้างทีมแพทย์มาทำงานให้เราได้ ในกรณีนั้น เราสามารถใช้เทคนิค NLP เพื่อแยกความสัมพันธ์เหล่านั้นโดยอัตโนมัติ ส่วนที่ดีคือเราสามารถใช้ไปป์ไลน์ NLP เพื่ออ่านเอกสารการวิจัยทั้งหมดที่มีอยู่ และส่วนที่ไม่ดีก็คือผลลัพธ์ที่ได้จะไม่สมบูรณ์แบบทั้งหมด อย่างไรก็ตาม เนื่องจากฉันไม่มีทีมนักวิทยาศาสตร์พร้อมที่จะดึงความสัมพันธ์ด้วยตนเอง ฉันจะหันไปใช้เทคนิค NLP เพื่อสร้างกราฟความรู้ด้านชีวการแพทย์ของตัวฉันเอง

ฉันจะใช้บทความวิจัยฉบับเดียวในโพสต์บล็อกนี้เพื่ออธิบายขั้นตอนทั้งหมดที่จำเป็นในการสร้างกราฟความรู้ด้านชีวการแพทย์ – วิศวกรรมเนื้อเยื่อของการสร้างผิวหนังใหม่และการเจริญเติบโตของเส้นผม.

กระดาษเขียนโดย โมฮัมมาเดรซา อาห์มาดี. บทความในเวอร์ชัน PDF มีให้ใช้งานภายใต้ลิขสิทธิ์ CC0 1.0 เราจะทำตามขั้นตอนต่อไปนี้เพื่อสร้างกราฟความรู้:

  • การอ่านเอกสาร PDF ด้วย OCR
  • การประมวลผลข้อความล่วงหน้า
  • การรับรู้และเชื่อมโยงแนวคิดชีวการแพทย์
  • การแยกความสัมพันธ์
  • การเพิ่มประสิทธิภาพของฐานข้อมูลภายนอก

ในตอนท้ายของโพสต์นี้ คุณจะต้องสร้างกราฟด้วยสคีมาต่อไปนี้

สคีมากราฟชีวการแพทย์ ภาพโดยผู้เขียน

เราจะใช้ Neo4j ซึ่งเป็นฐานข้อมูลกราฟที่มีรูปแบบกราฟคุณสมบัติที่มีป้ายกำกับ เพื่อจัดเก็บกราฟของเรา แต่ละบทความสามารถมีผู้เขียนได้ตั้งแต่หนึ่งคนขึ้นไป เราจะแบ่งเนื้อหาบทความออกเป็นประโยคและใช้ NLP เพื่อแยกทั้งหน่วยงานทางการแพทย์และความสัมพันธ์ อาจเป็นการตอบโต้โดยสัญชาตญาณเล็กน้อยที่เราจะเก็บความสัมพันธ์ระหว่างเอนทิตีเป็นโหนดระดับกลางแทนที่จะเป็นความสัมพันธ์ ปัจจัยสำคัญที่อยู่เบื้องหลังการตัดสินใจนี้คือ เราต้องการมีหลักฐานการตรวจสอบของข้อความต้นฉบับที่ดึงความสัมพันธ์ออกมา ด้วยโมเดลกราฟคุณสมบัติที่มีป้ายกำกับ คุณไม่สามารถมีความสัมพันธ์ที่ชี้ไปยังความสัมพันธ์อื่นได้ ด้วยเหตุนี้ เราจึงปรับโครงสร้างการเชื่อมต่อระหว่างแนวคิดทางการแพทย์ให้เป็นโหนดระดับกลาง วิธีนี้จะช่วยให้ผู้เชี่ยวชาญด้านโดเมนประเมินว่าความสัมพันธ์ถูกดึงออกมาอย่างถูกต้องหรือไม่

ระหว่างทาง ฉันจะสาธิตการใช้งานการใช้กราฟที่สร้างขึ้นเพื่อค้นหาและวิเคราะห์ข้อมูลที่เก็บไว้

มาดำน้ำกันเลย!

หากเนื้อหาการศึกษาเชิงลึกนี้มีประโยชน์สำหรับคุณ สมัครรับจดหมายข่าวการวิจัย AI ของเรา เพื่อรับการแจ้งเตือนเมื่อเราเผยแพร่เนื้อหาใหม่

การอ่านเอกสาร PDF ด้วย OCR

ดังที่กล่าวไว้ เอกสารการวิจัยเวอร์ชัน PDF สามารถเข้าถึงได้โดยสาธารณะภายใต้ลิขสิทธิ์ CC0 1.0 ซึ่งหมายความว่าเราสามารถดาวน์โหลดเอกสารนี้ด้วย Python ได้อย่างง่ายดาย เราจะใช้ ไพเทสเซอแรค ห้องสมุดเพื่อดึงข้อความจาก PDF เท่าที่ฉันรู้ ไลบรารี pytesseract เป็นหนึ่งในไลบรารียอดนิยมสำหรับ OCR หากคุณต้องการทำตามตัวอย่างโค้ด ฉันได้เตรียม a สมุดบันทึก Google Colabดังนั้นคุณจึงไม่ต้องคัดลอกและวางโค้ดด้วยตนเอง

import requests
import pdf2image
import pytesseract pdf = requests.get('https://arxiv.org/pdf/2110.03526.pdf')
doc = pdf2image.convert_from_bytes(pdf.content) # Get the article text
article = []
for page_number, page_data in enumerate(doc): txt = pytesseract.image_to_string(page_data).encode("utf-8") # Sixth page are only references if page_number < 6: article.append(txt.decode("utf-8"))
article_txt = " ".join(article)

การประมวลผลข้อความล่วงหน้า

ตอนนี้เรามีเนื้อหาบทความแล้ว เราจะดำเนินการลบชื่อส่วนและคำอธิบายรูปภาพออกจากข้อความ ต่อไปเราจะแบ่งข้อความออกเป็นประโยค

import nltk
nltk.download('punkt') def clean_text(text): """Remove section titles and figure descriptions from text""" clean = "n".join([row for row in text.split("n") if (len(row.split(" "))) > 3 and not (row.startswith("(a)")) and not row.startswith("Figure")]) return clean text = article_txt.split("INTRODUCTION")[1]
ctext = clean_text(text)
sentences = nltk.tokenize.sent_tokenize(ctext)

การเชื่อมโยงเอนทิตีที่มีชื่อทางการแพทย์

ตอนนี้มาถึงส่วนที่น่าตื่นเต้น สำหรับผู้ที่เพิ่งเริ่มใช้ NLP และการรับรู้และการลิงก์เอนทิตีที่มีชื่อ เรามาเริ่มด้วยพื้นฐานกันก่อน เทคนิคการรู้จำเอนทิตีที่มีชื่อใช้เพื่อตรวจหาเอนทิตีหรือแนวคิดที่เกี่ยวข้องในข้อความ ตัวอย่างเช่น ในโดเมนชีวการแพทย์ เราต้องการระบุยีน ยา โรค และแนวคิดอื่นๆ ในเนื้อหา

การแยกแนวคิดทางชีวการแพทย์ ภาพโดยผู้เขียน

ในตัวอย่างนี้ แบบจำลอง NLP ระบุยีน โรค ยา สปีชีส์ การกลายพันธุ์ และวิถีทางในข้อความ ดังที่กล่าวไว้ กระบวนการนี้เรียกว่าการรับรู้เอนทิตีที่มีชื่อ การอัพเกรดเป็นการรับรู้เอนทิตีที่มีชื่อเป็นสิ่งที่เรียกว่าการเชื่อมโยงเอนทิตีที่มีชื่อ เทคนิคการเชื่อมโยงเอนทิตีที่มีชื่อจะตรวจจับแนวคิดที่เกี่ยวข้องในข้อความและพยายามจับคู่กับฐานความรู้เป้าหมาย ในโดเมนชีวการแพทย์ ฐานความรู้เป้าหมายบางส่วนคือ:

เหตุใดเราจึงต้องการเชื่อมโยงหน่วยงานทางการแพทย์กับฐานความรู้เป้าหมาย เหตุผลหลักคือช่วยให้เราจัดการกับความกำกวมเอนทิตี ตัวอย่างเช่น เราไม่ต้องการแยกเอนทิตีในกราฟที่แสดงกรดแอสคอร์บิกและวิตามินซี เนื่องจากผู้เชี่ยวชาญด้านโดเมนสามารถบอกคุณได้ว่าสิ่งเหล่านี้เป็นสิ่งเดียวกัน เหตุผลรองคือโดยการจับคู่แนวคิดกับฐานความรู้เป้าหมาย เราสามารถปรับปรุงโมเดลกราฟของเราได้โดยการดึงข้อมูลเกี่ยวกับแนวคิดที่แมปจากฐานความรู้เป้าหมาย หากเราใช้ตัวอย่างกรดแอสคอร์บิกอีกครั้ง เราสามารถดึงข้อมูลเพิ่มเติมจากฐานข้อมูล CHEBI ได้อย่างง่ายดายหากเราทราบอยู่แล้ว รหัสเชบี.

ข้อมูลการเพิ่มคุณค่าที่มีอยู่เกี่ยวกับกรดแอสคอร์บิกบนเว็บไซต์ของ CHEBI เนื้อหาทั้งหมดบนเว็บไซต์อยู่ภายใต้ ใบอนุญาต CC BY 4.0 ภาพโดยผู้เขียน

ฉันกำลังมองหาการเชื่อมโยงเอนทิตีชื่อโอเพนซอร์สที่ได้รับการฝึกฝนล่วงหน้าสำหรับชีวการแพทย์ที่ดีมาระยะหนึ่งแล้ว โมเดล NLP จำนวนมากมุ่งเน้นที่การแยกเฉพาะแนวคิดทางการแพทย์บางส่วน เช่น ยีนหรือโรค หาแบบจำลองที่ตรวจจับแนวคิดทางการแพทย์ส่วนใหญ่และเชื่อมโยงไปยังฐานความรู้เป้าหมายได้ยากกว่า โชคดีไปเจอมา เบิร์น[1] การรับรู้เอนทิตีชีวการแพทย์ทางประสาทและเครื่องมือการทำให้เป็นมาตรฐานหลายประเภท ถ้าฉันเข้าใจถูกต้อง มันคือโมเดล BioBert ที่ปรับแต่งอย่างละเอียดพร้อมโมเดลการเชื่อมโยงเอนทิตีที่มีชื่อต่างๆ ที่รวมไว้สำหรับแนวคิดการทำแผนที่กับฐานความรู้เป้าหมายด้านชีวการแพทย์ ไม่เพียงแค่นั้น แต่ยังให้จุดสิ้นสุด REST ฟรีด้วย ดังนั้นเราจึงไม่ต้องปวดหัวกับการต้องพึ่งพาและโมเดลในการทำงาน การแสดงภาพการรู้จำเอนทิตีทางชีวการแพทย์ที่ฉันได้ใช้ข้างต้น ถูกสร้างขึ้นโดยใช้แบบจำลอง BERN ดังนั้นเราจึงรู้ว่ามันตรวจจับยีน โรค ยา สายพันธุ์ การกลายพันธุ์ และวิถีทางในข้อความ

น่าเสียดายที่โมเดล BERN ไม่ได้กำหนดรหัสฐานความรู้เป้าหมายให้กับแนวคิดทั้งหมด ดังนั้นฉันจึงได้เตรียมสคริปต์ที่จะตรวจสอบว่ามีการระบุ id ที่แตกต่างกันสำหรับแนวคิดหรือไม่ และหากไม่ใช่ จะใช้ชื่อเอนทิตีเป็น id นอกจากนี้เรายังจะคำนวณ sha256 ของข้อความในประโยคเพื่อระบุประโยคที่เฉพาะเจาะจงได้ง่ายขึ้นในภายหลังเมื่อเราจะทำการแยกความสัมพันธ์

import hashlib def query_raw(text, url="https://bern.korea.ac.kr/plain"): """Biomedical entity linking API""" return requests.post(url, data={'sample_text': text}).json() entity_list = []
# The last sentence is invalid
for s in sentences[:-1]: entity_list.append(query_raw(s)) parsed_entities = []
for entities in entity_list: e = [] # If there are not entities in the text if not entities.get('denotations'): parsed_entities.append({'text':entities['text'], 'text_sha256': hashlib.sha256(entities['text'].encode('utf-8')).hexdigest()}) continue for entity in entities['denotations']: other_ids = [id for id in entity['id'] if not id.startswith("BERN")] entity_type = entity['obj'] entity_name = entities['text'][entity['span']['begin']:entity['span']['end']] try: entity_id = [id for id in entity['id'] if id.startswith("BERN")][0] except IndexError: entity_id = entity_name e.append({'entity_id': entity_id, 'other_ids': other_ids, 'entity_type': entity_type, 'entity': entity_name}) parsed_entities.append({'entities':e, 'text':entities['text'], 'text_sha256': hashlib.sha256(entities['text'].encode('utf-8')).hexdigest()})

ฉันได้ตรวจสอบผลลัพธ์ของการลิงก์เอนทิตีที่มีชื่อแล้ว และตามที่คาดไว้ มันไม่สมบูรณ์แบบ ตัวอย่างเช่น ไม่ได้ระบุเซลล์ต้นกำเนิดว่าเป็นแนวคิดทางการแพทย์ ในทางกลับกัน ตรวจพบเอนทิตีเดียวที่ชื่อว่า "หัวใจ สมอง เส้นประสาท และไต" อย่างไรก็ตาม เบิร์นยังคงเป็นโมเดลชีวการแพทย์โอเพนซอร์ซที่ดีที่สุดที่ฉันสามารถหาได้ในระหว่างการสืบสวน

สร้างกราฟความรู้

ก่อนที่จะดูเทคนิคการแยกความสัมพันธ์ เราจะสร้างกราฟความรู้ทางชีวการแพทย์โดยใช้เอนทิตีเท่านั้น และตรวจสอบการใช้งานที่เป็นไปได้ ดังที่ได้กล่าวมาแล้ว ข้าพเจ้าได้เตรียม สมุดบันทึก Google Colab ที่คุณสามารถใช้เพื่อติดตามตัวอย่างโค้ดในโพสต์นี้ ในการจัดเก็บกราฟ เราจะใช้ Neo4j คุณไม่จำเป็นต้องจัดการกับการเตรียมสภาพแวดล้อม Neo4j ในพื้นที่ คุณสามารถใช้อินสแตนซ์ Neo4j Sandbox ฟรีแทนได้

Neo4j แซนด์บ็อกซ์

เริ่มต้น โปรเจ็กต์เปล่าในกล่องทราย และคัดลอกรายละเอียดการเชื่อมต่อไปยังสมุดบันทึก Colab

รายละเอียดการเชื่อมต่อ Neo4j Sandbox ภาพโดยผู้เขียน

ตอนนี้คุณสามารถเตรียมการเชื่อมต่อ Neo4j ในโน้ตบุ๊กได้

from neo4j import GraphDatabase
import pandas as pd host = 'bolt://3.236.182.55:7687'
user = 'neo4j'
password = 'hydrometer-ditches-windings'
driver = GraphDatabase.driver(host,auth=(user, password)) def neo4j_query(query, params=None): with driver.session() as session: result = session.run(query, params) return pd.DataFrame([r.values() for r in result], columns=result.keys())

เราจะเริ่มต้นด้วยการนำเข้าผู้เขียนและบทความลงในกราฟ โหนดบทความจะมีเฉพาะชื่อเรื่องเท่านั้น

author = article_txt.split("n")[0]
title = " ".join(article_txt.split("n")[2:4]) neo4j_query("""
MERGE (a:Author{name:$author})
MERGE (b:Article{title:$title})
MERGE (a)-[:WROTE]->(b)
""", {'title':title, 'author':author})

หากคุณเปิด Neo4j Browser คุณจะเห็นกราฟต่อไปนี้

ภาพโดยผู้เขียน

คุณสามารถนำเข้าประโยคและเอนทิตีที่กล่าวถึงโดยดำเนินการแบบสอบถาม Cypher ต่อไปนี้:

neo4j_query("""
MATCH (a:Article)
UNWIND $data as row
MERGE (s:Sentence{id:row.text_sha256})
SET s.text = row.text
MERGE (a)-[:HAS_SENTENCE]->(s)
WITH s, row.entities as entities
UNWIND entities as entity
MERGE (e:Entity{id:entity.entity_id})
ON CREATE SET e.other_ids = entity.other_ids, e.name = entity.entity, e.type = entity.entity_type
MERGE (s)-[m:MENTIONS]->(e)
ON CREATE SET m.count = 1
ON MATCH SET m.count = m.count + 1
""", {'data': parsed_entities})

คุณสามารถดำเนินการแบบสอบถาม Cypher ต่อไปนี้เพื่อตรวจสอบกราฟที่สร้างขึ้น:

MATCH p=(a:Article)-[:HAS_SENTENCE]->()-[:MENTIONS]->(e:Entity)
RETURN p LIMIT 25

หากคุณนำเข้าข้อมูลอย่างถูกต้อง คุณควรเห็นการแสดงภาพที่คล้ายกัน

การแยกเอนทิตีที่เก็บไว้เป็นกราฟ ภาพโดยผู้เขียน

แอพพลิเคชั่นกราฟความรู้

แม้จะไม่มีโฟลว์การแยกความสัมพันธ์ แต่ก็มีบางกรณีการใช้งานสำหรับกราฟของเราอยู่แล้ว

เครื่องมือค้นหา

เราสามารถใช้กราฟของเราเป็นเครื่องมือค้นหา ตัวอย่างเช่น คุณสามารถใช้แบบสอบถาม Cypher ต่อไปนี้เพื่อค้นหาประโยคหรือบทความที่กล่าวถึงหน่วยงานทางการแพทย์ที่เฉพาะเจาะจง

MATCH (e:Entity)<-[:MENTIONS]-(s:Sentence)
WHERE e.name = "autoimmune diseases"
RETURN s.text as result

ผลสอบ

ภาพโดยผู้เขียน

การวิเคราะห์การเกิดร่วม

ตัวเลือกที่สองคือการวิเคราะห์การเกิดร่วม คุณสามารถกำหนดการเกิดร่วมกันระหว่างหน่วยงานทางการแพทย์ได้หากปรากฏในประโยคหรือบทความเดียวกัน ฉันพบบทความ[2]ที่ใช้เครือข่ายการเกิดขึ้นร่วมทางการแพทย์เพื่อทำนายความเชื่อมโยงที่เป็นไปได้ใหม่ระหว่างหน่วยงานทางการแพทย์

การเชื่อมโยงการคาดการณ์ในเครือข่าย MeSH co-occurrence: ผลเบื้องต้น – PubMed

คุณสามารถใช้แบบสอบถาม Cypher ต่อไปนี้เพื่อค้นหาเอนทิตีที่มักเกิดขึ้นในประโยคเดียวกัน

MATCH (e1:Entity)<-[:MENTIONS]-()-[:MENTIONS]->(e2:Entity)
MATCH (e1:Entity)<-[:MENTIONS]-()-[:MENTIONS]->(e2:Entity)
WHERE id(e1) < id(e2)
RETURN e1.name as entity1, e2.name as entity2, count(*) as cooccurrence
ORDER BY cooccurrence
DESC LIMIT 3

ผลสอบ

นิติบุคคล1 นิติบุคคล2 การเกิดร่วมกัน
โรคผิวหนัง แผลเบาหวาน 2
แผลเรื้อรัง แผลเบาหวาน 2
โรคผิวหนัง แผลเรื้อรัง 2

แน่นอน ผลลัพธ์จะดีกว่าถ้าเราวิเคราะห์บทความนับพันหรือมากกว่า

ตรวจสอบความเชี่ยวชาญของผู้เขียน

คุณยังสามารถใช้กราฟนี้เพื่อค้นหาความเชี่ยวชาญของผู้เขียนโดยตรวจสอบหน่วยงานทางการแพทย์ที่พวกเขาเขียนบ่อยที่สุด ด้วยข้อมูลนี้ คุณสามารถแนะนำการทำงานร่วมกันในอนาคตได้

ดำเนินการแบบสอบถาม Cypher ต่อไปนี้เพื่อตรวจสอบว่าหน่วยงานทางการแพทย์ใดที่ผู้เขียนคนเดียวของเรากล่าวถึงในรายงานการวิจัย

MATCH (a:Author)-[:WROTE]->()-[:HAS_SENTENCE]->()-[:MENTIONS]->(e:Entity)
RETURN a.name as author, e.name as entity,
MATCH (a:Author)-[:WROTE]->()-[:HAS_SENTENCE]->()-[:MENTIONS]->(e:Entity)
RETURN a.name as author, e.name as entity, count(*) as count
ORDER BY count DESC
LIMIT 5

ผลสอบ

ผู้เขียน เอกลักษณ์ นับ
โมฮัมมาเดรซา อาห์มาดี คอลลาเจน 9
โมฮัมมาเดรซา อาห์มาดี การเผาไหม้ 4
โมฮัมมาเดรซา อาห์มาดี โรคผิวหนัง 4
โมฮัมมาเดรซา อาห์มาดี เอนไซม์คอลลาเจนเนส 2
โมฮัมมาเดรซา อาห์มาดี เอพิเดอร์โมไลซิสบูลซา 2

การแยกความสัมพันธ์

ตอนนี้เราจะพยายามแยกความสัมพันธ์ระหว่างแนวคิดทางการแพทย์ จากประสบการณ์ของฉัน การดึงความสัมพันธ์อย่างน้อยก็มีลำดับความสำคัญยากกว่าการแยกเอนทิตีที่มีชื่อ หากคุณไม่ควรคาดหวังผลลัพธ์ที่สมบูรณ์แบบด้วยการเชื่อมโยงเอนทิตีที่มีชื่อ คุณสามารถคาดหวังข้อผิดพลาดบางอย่างได้ด้วยเทคนิคการแยกความสัมพันธ์

ฉันได้มองหาแบบจำลองการแยกความสัมพันธ์ทางชีวการแพทย์ที่มีอยู่แล้ว แต่ไม่พบสิ่งใดที่ได้ผลทันทีหรือไม่ต้องการการปรับแต่งแบบละเอียด ดูเหมือนว่าสาขาของการแยกความสัมพันธ์จะอยู่ในระดับที่ทันสมัย ​​และหวังว่าเราจะได้รับความสนใจมากขึ้นในอนาคต ขออภัย ฉันไม่ใช่ผู้เชี่ยวชาญ NLP ดังนั้นฉันจึงหลีกเลี่ยงการปรับแต่งโมเดลของตัวเองอย่างละเอียด เราจะใช้ตัวแยกความสัมพันธ์แบบ zero-shot ตามเอกสารแทน สำรวจขีด จำกัด ของศูนย์ช็อตของ FewRel[3]. แม้ว่าฉันจะไม่แนะนำให้นำโมเดลนี้ไปใช้จริง แต่ก็ดีเพียงพอสำหรับการสาธิตง่ายๆ รุ่นมีจำหน่ายบน กอดใบหน้าดังนั้นเราจึงไม่ต้องจัดการกับการฝึกอบรมหรือการตั้งค่าโมเดล

from transformers import AutoTokenizer
from zero_shot_re import RelTaggerModel, RelationExtractor model = RelTaggerModel.from_pretrained("fractalego/fewrel-zero-shot")
tokenizer = AutoTokenizer.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
relations = ['associated', 'interacts']
extractor = RelationExtractor(model, tokenizer, relations)

ด้วยตัวแยกความสัมพันธ์แบบ zero-shot คุณสามารถกำหนดความสัมพันธ์ที่คุณต้องการตรวจจับได้ ในตัวอย่างนี้ ฉันได้ใช้ ที่เกี่ยวข้อง และ  เชิงโต้ตอบ ความสัมพันธ์ ฉันได้ลองใช้ความสัมพันธ์แบบเฉพาะเจาะจงมากขึ้นด้วย เช่น การปฏิบัติ สาเหตุ และอื่นๆ แต่ผลลัพธ์ก็ไม่ค่อยดีนัก

ด้วยโมเดลนี้ คุณต้องกำหนดระหว่างคู่ของเอนทิตีที่คุณต้องการตรวจจับความสัมพันธ์ เราจะใช้ผลลัพธ์ของการเชื่อมโยงเอนทิตีที่มีชื่อเป็นข้อมูลป้อนเข้าสู่กระบวนการแยกความสัมพันธ์ อันดับแรก เราพบประโยคทั้งหมดที่มีการกล่าวถึงเอนทิตีตั้งแต่สองรายการขึ้นไป จากนั้นเรียกใช้ผ่านแบบจำลองการแยกความสัมพันธ์เพื่อแยกการเชื่อมต่อใดๆ ฉันได้กำหนดค่าขีดจำกัดไว้ที่ 0.85 ซึ่งหมายความว่าหากตัวแบบคาดการณ์การเชื่อมโยงระหว่างเอนทิตีที่มีความน่าจะเป็นต่ำกว่า 0.85 เราจะเพิกเฉยต่อการคาดคะเน

import itertools
# Candidate sentence where there is more than a single entity present
candidates = [s for s in parsed_entities if (s.get('entities')) and (len(s['entities']) &gt; 1)]
predicted_rels = []
for c in candidates: combinations = itertools.combinations([{'name':x['entity'], 'id':x['entity_id']} for x in c['entities']], 2) for combination in list(combinations): try: ranked_rels = extractor.rank(text=c['text'].replace(",", " "), head=combination[0]['name'], tail=combination[1]['name']) # Define threshold for the most probable relation if ranked_rels[0][1] &gt; 0.85: predicted_rels.append({'head': combination[0]['id'], 'tail': combination[1]['id'], 'type':ranked_rels[0][0], 'source': c['text_sha256']}) except: pass # Store relations to Neo4j
neo4j_query("""
UNWIND $data as row
MATCH (source:Entity {id: row.head})
MATCH (target:Entity {id: row.tail})
MATCH (text:Sentence {id: row.source})
MERGE (source)-[:REL]-&gt;(r:Relation {type: row.type})-[:REL]-&gt;(target)
MERGE (text)-[:MENTIONS]-&gt;(r)
""", {'data': predicted_rels})

เราจัดเก็บความสัมพันธ์ตลอดจนข้อความต้นฉบับที่ใช้ในการแยกความสัมพันธ์นั้นในกราฟ

ดึงความสัมพันธ์ที่เก็บไว้ในกราฟ ภาพโดยผู้เขียน

คุณสามารถตรวจสอบความสัมพันธ์ที่แยกออกมาระหว่างเอนทิตีและข้อความต้นฉบับด้วยคิวรี Cypher ต่อไปนี้:

MATCH (s:Entity)-[:REL]->(r:Relation)-[:REL]->(t:Entity), (r)<-[:MENTIONS]-(st:Sentence)
RETURN s.name as source_entity, t.name as target_entity, r.type as type, st.text as source_text

ผลสอบ

ภาพโดยผู้เขียน

ดังที่กล่าวไว้ แบบจำลอง NLP ที่ฉันเคยใช้ดึงความสัมพันธ์นั้นไม่สมบูรณ์แบบ และเนื่องจากฉันไม่ใช่แพทย์ ฉันจึงไม่รู้ว่าขาดการเชื่อมต่อไปมากเพียงใด อย่างไรก็ตาม สิ่งที่ตรวจพบนั้นดูสมเหตุสมผล

การเพิ่มประสิทธิภาพของฐานข้อมูลภายนอก

ดังที่ได้กล่าวไว้ก่อนหน้านี้ เรายังคงสามารถใช้ฐานข้อมูลภายนอก เช่น CHEBI หรือ MESH เพื่อทำให้กราฟของเราสมบูรณ์ ตัวอย่างเช่น กราฟของเรามีหน่วยงานทางการแพทย์ เอพิเดอร์โมไลซิสบูลซา และเราก็รู้จัก MeSH id ของมันด้วย

คุณสามารถดึงข้อมูล MeSH id ของ Epidermolysis bullosa ด้วยข้อความค้นหาต่อไปนี้:

MATCH (e:Entity)
WHERE e.name = "Epidermolysis bullosa"
RETURN e.name as entity, e.other_ids as other_ids

คุณสามารถดำเนินการต่อและตรวจสอบ MeSH เพื่อค้นหาข้อมูลที่มี:

ข้อมูลเชื่อมโยงตาข่าย

ภาพหน้าจอโดยผู้เขียน ข้อมูลได้รับความอนุเคราะห์จากหอสมุดแพทยศาสตร์แห่งชาติของสหรัฐอเมริกา

นี่คือภาพหน้าจอของข้อมูลที่มีอยู่บนเว็บไซต์ MeSH สำหรับ Epidermolysis bullosa ดังที่ได้กล่าวมาแล้ว ฉันไม่ใช่แพทย์ ดังนั้นฉันจึงไม่รู้ว่าวิธีที่ดีที่สุดในการสร้างแบบจำลองข้อมูลนี้ในกราฟจะเป็นอย่างไร อย่างไรก็ตาม ฉันจะแสดงวิธีดึงข้อมูลนี้ใน Neo4j โดยใช้ขั้นตอน apoc.load.json เพื่อดึงข้อมูลจากปลายทาง MeSH REST จากนั้น คุณสามารถขอให้ผู้เชี่ยวชาญโดเมนช่วยคุณสร้างแบบจำลองข้อมูลนี้

แบบสอบถาม Cypher เพื่อดึงข้อมูลจากปลายทาง MeSH REST คือ:

MATCH (e:Entity)
WHERE e.name = "Epidermolysis bullosa"
WITH e, [id in e.other_ids WHERE id contains "MESH" | split(id,":")[1]][0] as meshId
CALL apoc.load.json("https://id.nlm.nih.gov/mesh/lookup/details?descriptor=" + meshId) YIELD value
RETURN value

กราฟความรู้เป็นอินพุตข้อมูลการเรียนรู้ของเครื่อง

ในความคิดสุดท้าย ฉันจะแนะนำคุณอย่างรวดเร็วเกี่ยวกับวิธีที่คุณสามารถใช้กราฟความรู้ด้านชีวการแพทย์เป็นอินพุตสำหรับเวิร์กโฟลว์แมชชีนเลิร์นนิง ในช่วงไม่กี่ปีที่ผ่านมา มีการวิจัยและความก้าวหน้าอย่างมากในสาขาการฝังโหนด โมเดลการฝังโหนดแปลโทโพโลยีเครือข่ายเป็นพื้นที่ฝัง

ลิขสิทธิ์ © 2017 Manan Shah, SNAP Group. รูปภาพพร้อมใช้งานภายใต้ใบอนุญาต MIT ใน https://github.com/snap-stanford/cs224w-notes.

สมมติว่าคุณสร้างกราฟความรู้ด้านชีวการแพทย์ที่มีหน่วยงานและแนวคิดทางการแพทย์ ความสัมพันธ์ และการเพิ่มคุณค่าจากฐานข้อมูลทางการแพทย์ต่างๆ คุณสามารถใช้เทคนิคการฝังโหนดเพื่อเรียนรู้การแสดงแทนโหนด ซึ่งเป็นเวกเตอร์ที่มีความยาวคงที่ และป้อนข้อมูลเหล่านี้ลงในเวิร์กโฟลว์การเรียนรู้ของเครื่อง แอปพลิเคชันต่างๆ กำลังใช้แนวทางนี้ ตั้งแต่การนำยากลับมาใช้ใหม่ ไปจนถึงการคาดคะเนผลข้างเคียงหรือผลข้างเคียงของยา ฉันพบรายงานการวิจัยที่ใช้ ลิงค์ทำนายสำหรับการรักษาที่เป็นไปได้ของโรคใหม่[4]

สรุป

โดเมนชีวการแพทย์เป็นตัวอย่างสำคัญที่ใช้กราฟความรู้ มีแอพพลิเคชั่นมากมายตั้งแต่เสิร์ชเอ็นจิ้นทั่วไปไปจนถึงเวิร์กโฟลว์แมชชีนเลิร์นนิงที่ซับซ้อนยิ่งขึ้น หวังว่าเมื่ออ่านโพสต์ในบล็อกนี้ คุณจะมีแนวคิดบางประการเกี่ยวกับวิธีใช้กราฟความรู้ด้านชีวการแพทย์เพื่อสนับสนุนแอปพลิเคชันของคุณ คุณสามารถเริ่ม ฟรี Neo4j Sandbox และเริ่มสำรวจวันนี้

เช่นเคย รหัสสามารถใช้ได้บน GitHub.

อ้างอิง

[1] ด. คิม อัล et., “A Neural Named Entity Recognition และ Multi-Type Normalization Tool for Biomedical Text Mining” ใน การเข้าถึง IEEEฉบับที่ 7, pp. 73729–73740, 2019, ดอย: 10.1109/ACCESS.2019.2920708.

[2] Kastrin A, Rindflesch TC, Hristovski D. การทำนายลิงก์ในเครือข่าย MeSH co-occurrence: ผลเบื้องต้น สตั๊ดเฮลธ์เทคโนโลยแจ้ง. 2014;205:579–83. PMID: 25160252.

[3] Cetoli, A. (2020). สำรวจขีด จำกัด Zero-shot ของ FewRel ใน การประชุมวิชาการนานาชาติด้านภาษาศาสตร์คอมพิวเตอร์ ครั้งที่ 28 (หน้า 1447–1451). คณะกรรมการระหว่างประเทศว่าด้วยภาษาศาสตร์คอมพิวเตอร์

[4] Zhang, R. , Hristovski, D. , Schutte, D. , Kastrin, A., Fiszman, M. , & Kilicoglu, H. (2021) การนำยามาใช้ใหม่สำหรับ COVID-19 ผ่านการเติมกราฟความรู้. วารสารชีวการแพทย์, 115, 103696.

บทความนี้ถูกเผยแพร่เมื่อวันที่ ต่อวิทยาศาสตร์ข้อมูล และเผยแพร่ซ้ำไปยัง TOPBOTS โดยได้รับอนุญาตจากผู้เขียน

สนุกกับบทความนี้? ลงทะเบียนเพื่อรับการอัปเดต AI เพิ่มเติม

เราจะแจ้งให้คุณทราบเมื่อเราเผยแพร่การศึกษาด้านเทคนิคเพิ่มเติม

โพสต์ สร้างกราฟความรู้ชีวการแพทย์ด้วย NLP ปรากฏตัวครั้งแรกเมื่อ ท็อปบอท.

ประทับเวลา:

เพิ่มเติมจาก ท็อปบอท